问题 如何检测何时通过键盘编辑了一个可信的DIV的子元素?


鉴于此HTML代码:

<div contenteditable>
    ....
    <span> child-element </span>
    ....
</div>

当用户单击SPAN元素(为了将插入符号放在其中),然后按下键盘上的字符键(为了编辑SPAN元素的文本内容), keydownkeypress,和 keyup 事件将被解雇。

但是,那 target 那些相应事件对象的属性是  SPAN元素,但DIV元素本身。

现场演示: (也 在jsFiddle上

$('div').keydown(function(e) {
    alert( e.target.nodeName );
});
div { border:2px solid red; padding:10px; margin:10px; }
span { background-color:yellow; }
<div contenteditable>
    BEFORE
    <span>SPAN</span>
    AFTER
</div>

<p>
    Click on the yellow SPAN element (to place the caret inside it), and then press a character key (to change the text-content of the SPAN element). The alert-box shows that the event-target is the DIV element, not the SPAN element...
</p>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

10119
2017-07-19 19:08


起源



答案:


这可以使用选择API完成:

$('div').keydown(function(e) {
    if (document.selection) {
        alert(document.selection.createRange().parentElement().tagName); // IE
    } else {
        // everyone else
        alert(window.getSelection().anchorNode.parentNode.tagName); 
    }
});

注意: 上面的例子很简单。请参阅下面链接的SO帖子,以获得选择问题的完整解决方案。

演示(也是 在jsFiddle上):

$('div').keydown(function(e) {
    if (document.selection)
        alert(document.selection.createRange().parentElement().tagName); // IE
    else
        alert(window.getSelection().anchorNode.parentNode.tagName); // everyone else
});
div { border:2px solid red; padding:10px; margin:10px; }
span { background-color:yellow; }
<div contenteditable>
    BEFORE
    <span>SPAN</span>
    AFTER
</div>

<p>
    Click on the yellow SPAN element (to place the caret inside it), and then press a character key (to change the text-content of the SPAN element). The alert-box shows that the event-target is the DIV element, not the SPAN element...
</p>
<div id="stuff"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

参考文献:


12
2017-07-19 19:30



谢谢,我确信在IE中有类似的方法可以做到这一点...... - Šime Vidas
@Šime - 更新了IE解决方案。我在研究这篇文章时找到了这篇文章。那里有更完整的答案。 - Wayne Burkett
这解决了我的问题。非常感谢你 :) - Šime Vidas
一点: anchorNode 不保证在所有浏览器和所有情况下都是文本节点。最好检查它的节点类型,看看它是否是一个安全的元素。 - Tim Down
@Tim - 是的,当然。任何使用我的答案的人都需要阅读另一个链接的SO问题,该问题将进入具体细节。我说这不是骗局的唯一原因是因为它是在上下文中 contenteditable 特别。 - Wayne Burkett


答案:


这可以使用选择API完成:

$('div').keydown(function(e) {
    if (document.selection) {
        alert(document.selection.createRange().parentElement().tagName); // IE
    } else {
        // everyone else
        alert(window.getSelection().anchorNode.parentNode.tagName); 
    }
});

注意: 上面的例子很简单。请参阅下面链接的SO帖子,以获得选择问题的完整解决方案。

演示(也是 在jsFiddle上):

$('div').keydown(function(e) {
    if (document.selection)
        alert(document.selection.createRange().parentElement().tagName); // IE
    else
        alert(window.getSelection().anchorNode.parentNode.tagName); // everyone else
});
div { border:2px solid red; padding:10px; margin:10px; }
span { background-color:yellow; }
<div contenteditable>
    BEFORE
    <span>SPAN</span>
    AFTER
</div>

<p>
    Click on the yellow SPAN element (to place the caret inside it), and then press a character key (to change the text-content of the SPAN element). The alert-box shows that the event-target is the DIV element, not the SPAN element...
</p>
<div id="stuff"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

参考文献:


12
2017-07-19 19:30



谢谢,我确信在IE中有类似的方法可以做到这一点...... - Šime Vidas
@Šime - 更新了IE解决方案。我在研究这篇文章时找到了这篇文章。那里有更完整的答案。 - Wayne Burkett
这解决了我的问题。非常感谢你 :) - Šime Vidas
一点: anchorNode 不保证在所有浏览器和所有情况下都是文本节点。最好检查它的节点类型,看看它是否是一个安全的元素。 - Tim Down
@Tim - 是的,当然。任何使用我的答案的人都需要阅读另一个链接的SO问题,该问题将进入具体细节。我说这不是骗局的唯一原因是因为它是在上下文中 contenteditable 特别。 - Wayne Burkett


制作整体 div 可编辑意味着 <span> 标签只是文本内容。如果你只是想要的话 span 可编辑,设置 contentEditable 在跨度本身。


0
2017-07-19 19:34



我需要整个DIV可编辑。我使用SPAN元素给出某些特定样式和行为的单词...... - Šime Vidas
这是不正确的。子元素仍然存在,仍然可以访问和操作。例: jsfiddle.net/o90Lm8jr - T.J. Crowder