IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    DOM新特性之caretPositionFromPoint API

    张 鑫旭发表于 2025-04-14 14:07:41
    love 0

    by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11620
    本文可全文转载,独立域名个人网站无需授权,但需要保留原作者、出处以及文中链接,任何网站均可摘要聚合,商用请联系授权。

    封面图,小鹿看鸟

    一、caretPositionFromPoint特性的语法和作用

    caretPositionFromPoint是浏览器支持不久的一个新特性,可以基于当前的光标位置,返回光标所对应元素的位置信息,在之前,此特性使用的是非标准的document.caretRangeFromPoint()方法实现的。

    caretPositionFromPoint()方法和elementsFromPoint()方法的区别在于,前者返回节点及其偏移、尺寸等信息,而后者返回元素。

    比方说有一段<p>元素文字描述信息,点击这段描述的某个文字,caretPositionFromPoint()方法可以返回精确的文本节点以及点击位置的字符偏移值,而elementsFromPoint()方法只能返回当前<p>元素。

    作用

    caretPositionFromPoint()的作用场景比较小众,一般用在分词分句这种交互场景中。

    例如制作视频封面的时候,书封标题的文字需要中断,此时,就可以直接点击实现。

    语法

    语法如下所示:

    const range = document.caretPositionFromPoint(x, y, options);

    其中:

    • x, y就是相对于浏览器窗口左上角的坐标值。
    • options是一个可选参数,支持一个名为shadowRoots的属性,其值为一个ShadowRoot对象数组。该方法可以返回在shadow DOM中定义的节点的插入符号位置。如果不设置,返回的会是shadow DOM根元素。

    二、caretPositionFromPoint使用案例

    这里通过一个书封书名中断简单示意下caretPositionFromPoint()方法的使用。

    已知某书封HTML结构如下所示:

    <figure>
        <img src="https://image.zhangxinxu.com/image/blog/202308/nonce-popover-cover.png">
        <figcaption>我是书名点我断句</figcaption>
    </figure>

    然后figcaption设置允许换行符换行效果:

    figcaption {
        white-space: pre-wrap;
    }

    则下面的代码可以实现点击figcaption元素,自动中断:

    // 中断方法
    figcaption.addEventListener('click', function (event) {
        const { clientX, clientY } = event;
        let range;
        let textNode;
        let offset;
    
        if (document.caretPositionFromPoint) {
            range = document.caretPositionFromPoint(clientX, clientY);
            textNode = range.offsetNode;
            offset = range.offset;
        } else if (document.caretRangeFromPoint) {
            // 使用非标准的老的API代替
            range = document.caretRangeFromPoint(clientX, clientY);
            textNode = range.startContainer;
            offset = range.startOffset;
        } else {
            return;
        }
        
        // 文本节点在当前偏移位置分隔,返回的是后面的节点
        const replacement = textNode.splitText(offset);
        const brNode = document.createTextNode('\n');
        replacement.before(brNode);
    });

    眼见为实,您可以狠狠地点击这里:caretPositionFromPoint书名手动换行demo

    最终实现的效果如下GIF所示,点击哪里的文字,文字就在哪里换行了:

    点击文字断行GIF示意图

    三、兼容性、点评与结语

    caretPositionFromPoint的兼容性如下截图所示,Chrome 128版本开始支持的:

    caretPositionFromPoint兼容性

    Safari浏览器目前还不支持,我们可以使用caretRangeFromPoint代替,这个特性支持很久了:

    caretRangeFromPoint兼容性

    具体如何使用,可参见上面的演示页面源码。

    点评

    返回特定坐标的节点和选区偏移可以让我们精确知道当前坐标的文字内容是什么,又一定的实用价值。

    但我们日常开发很少遇到相关的需求,因此,我建议大家了解下这个属性即可,知道Web有这么一个能力,当我们遇到相关场景的时候,知道有这么个方法可以解决即可。

    OK,就说这么多。

    感谢大家的阅读,我们下一篇文章再见,还是介绍新特性的。

    👋🏻👋🏻👋🏻

    本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
    本文地址:https://www.zhangxinxu.com/wordpress/?p=11620

    (本篇完)



沪ICP备19023445号-2号
友情链接