Selection API中getClientRects与getBoundingClientRect差异及可选文本边界框获取
获取元素可选文本的边界框(排除伪元素)
可以利用Selection API的特性来实现,伪元素不属于DOM节点,默认不会被选中,通过选中元素内所有可选中的内容,再获取对应Range的边界框,就能得到仅包含可选文本的区域,且无需处理伪元素样式:
实现代码
// 保存当前用户的选中状态,避免干扰操作 const originalSelection = window.getSelection(); let textBounds = null; try { // 创建新选择,选中目标元素内所有可选中内容 const selection = window.getSelection(); selection.removeAllRanges(); selection.selectAllChildren(e.target); // 获取选中范围的边界框 if (selection.rangeCount > 0) { const textRange = selection.getRangeAt(0); textBounds = textRange.getBoundingClientRect(); } } finally { // 恢复原选中状态 const selection = window.getSelection(); selection.removeAllRanges(); if (originalSelection.rangeCount > 0) { selection.addRange(originalSelection.getRangeAt(0)); } } // textBounds 就是可选文本的边界框 console.log(textBounds);
原理说明
selection.selectAllChildren()只会选中元素内的可选中DOM内容,伪元素不属于DOM子节点,默认不会被包含;同时会自动遵循user-select规则,排除不可选中的内容。- 相比直接用
range.selectNodeContents(),这种方法更贴合“可选文本”的定义——后者会选中元素内所有节点(包括不可选中的元素节点),而前者只保留用户实际能选中的内容。 - 最后恢复原选中状态,避免影响用户的正常操作。
内容的提问来源于stack exchange,提问作者undercover grill
相关产品推荐
相关产品推荐

