【问题标题】:Get ID of selected contenteditable element's child where cursor caret is located获取光标插入符号所在的选定 contenteditable 元素的子元素的 ID
【发布时间】:2017-09-26 22:54:24
【问题描述】:

我目前正在尝试使用 contenteditable div 制作编辑器,但我遇到了一个问题,即在开始时单击 child-2 中的退格键会导致合并 child- 1child-2 在一起,这违背了自己的目的。

我正在使用函数查找当前插入符号的位置:

caret: function() {
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt) return sel.getRangeAt(0).startOffset;
    }
    return null;
}

这一直运行良好,但要解决合并问题,我需要找出当前选择了哪个元素并将该数据与插入符号位置一起使用以使用 event.preventDefault() 并停止潜在的合并。

这是我正在使用和谈论的框架:

<div id="parent" contenteditable="true">
  <div id="child-1">
    One
  </div>
  <div id="child-2">
    Two
  </div>
  <div id="child-3">
    Three
  </div>
</div>

为了找到选定的元素,我试过这个:

console.log(document.activeElement);

查看这是否会打印出所选的子元素的 ID,尽管这会将整个父元素输出到控制台,而不仅仅是 ID。

【问题讨论】:

    标签: javascript jquery html css contenteditable


    【解决方案1】:

    使用Event Delegation 可以轻松找到被点击的节点。也可以添加其他事件,例如键和鼠标。

    详情在demo中注释

    演示

    // Refernce the parent of all of the target nodes
    var parent = document.getElementById('parent');
    // Register the click event to #parent
    parent.addEventListener('click', idNode);
    
    // This is the callback that is invoked on each click
    function idNode(e) {
      /* If the node clicked (e.target) is not the 
      || the registered event listener 
      || (e.currentTarget = #parent)
      */
      if (e.target !== e.currentTarget) {
        // Get the #id of clicked node
        var ID = e.target.id;
        // Reference e.target by its #id
        var child = document.getElementById(ID);
    
      }
      // Log the #id of each e.target at every click
      console.log('The caret is located at ' + ID);
      
      // Return the e.target as a DOM node when needed
      return child;
    
    }
    <div id="parent" contenteditable="true">
      <div id="child-1">
        One
      </div>
      <div id="child-2">
        Two
      </div>
      <div id="child-3">
        Three
      </div>
    </div>

    【讨论】:

    • 我的穿着闪亮盔甲的骑士。
    • 不客气。顺便说一句,您也可以添加键和鼠标事件。
    • @zer00ne 嘿,我尝试添加关键事件,但是当我应用“keydown”时,我得到了父 ID。
    【解决方案2】:

    您可以将tabindex="0" 应用于子元素,这使它们具有焦点,当使用document.activeElement 时将选择子元素(否则总是具有焦点的父元素):

    console.log(document.activeElement);
    <div id="parent" contenteditable="true">
      <div id="child-1" tabindex="0">
        One
      </div>
      <div id="child-2" tabindex="0">
        Two
      </div>
      <div id="child-3" tabindex="0">
        Three
      </div>
    </div>

    评论后:我正在添加这个非常sn-p的截图:我点击了“Two”这个词:你可以看到那条线周围的虚线边框表示焦点状态:

    【讨论】:

    • 为了关注元素,我不得不双击内容的末尾,这对用户来说有点麻烦。
    • 否 - 如果您只是单击它(即放置光标),则该元素被聚焦(通常由它周围的细虚线边框表示)
    • 当点击三个子div之一时,它只关注父? gyazo.com/3908eeadaad411036bb119c87114e4a8
    • 该链接在此处打开一个空白页面(灰色背景就是全部)
    • 请看看我在回答中添加了什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 2016-04-20
    • 1970-01-01
    相关资源
    最近更新 更多