Как определить, когда дочерний элемент contenteditable DIV редактируется с помощью клавиатуры?

Учитывая этот HTML-код:

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

Когда пользователь щелкает элемент SPAN (чтобы поместить внутри него курсор), а затем нажимает символьную клавишу на клавиатуре (чтобы редактировать текстовое содержимое элемента SPAN), keydown, keypress, а также 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>

Как я могу определить, произошло ли событие ключа внутри элемента SPAN?

2 ответа

Решение

Это можно сделать с помощью 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>

Рекомендации:

Делая целое div редактируемый означает, что <span> тег - это не что иное, как текстовое содержимое Если вы просто хотите span быть редактируемым contentEditable на самом пролете.

Другие вопросы по тегам