如何判断元素上的点击位置是否落在其自身文本内容区域
实现方案
我们可以通过浏览器的Range API 获取元素自身文本节点的实际渲染边界,再和点击坐标做匹配,即可实现需求,具体实现如下:
document.addEventListener('click', (ev) => { const clickedElement = ev.target; const isClickOnText = checkClickOnElementText(ev, clickedElement); console.log(isClickOnText ? '有内容' : '无内容'); }); /** * 校验点击位置是否落在目标元素自身的渲染文本区域 * @param {MouseEvent} event 点击事件对象 * @param {HTMLElement} element 目标元素 * @returns {boolean} 点击是否在文本区域 */ function checkClickOnElementText(event, element) { const { clientX, clientY } = event; // 仅遍历元素的直接子节点,筛选非空的文本节点,排除子元素 for (const node of element.childNodes) { if (node.nodeType !== Node.TEXT_NODE || node.textContent.trim().length === 0) { continue; } // 创建Range选中当前文本节点,获取其实际渲染的矩形区域 const range = document.createRange(); range.selectNodeContents(node); const rects = range.getClientRects(); // 校验点击坐标是否落在任意一个文本矩形内(文本换行时会生成多个矩形) for (const rect of rects) { if ( clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom ) { return true; } } } return false; }
方案说明
- 我们只遍历目标元素的直接子节点,且仅筛选文本节点,完全排除子元素的内容影响,符合「仅判定当前元素自身文本」的要求
- 调用
getClientRects获取的是文本实际渲染的坐标范围,和元素本身的宽高、定位无关,针对你提到的全屏div场景,只有点击test文本本身时才会返回true,点击div其他空白区域都会返回false,完全匹配给定的判定规则 - 自动适配文本换行、多行长文本、不同字号行高等场景,兼容性覆盖所有主流现代浏览器
内容的提问来源于stack exchange,提问作者U. Bulle
相关产品推荐
相关产品推荐

