Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect when a child-element of a contenteditable DIV is edited via keyboard?

Given this HTML code:

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

When the user clicks on the SPAN element (in order to place the caret inside it), and then presses a character key on the keyboard (in order to edit the text-content of the SPAN element), a keydown, keypress, and keyup event will be fired.

However, the target property of those corresponding event objects is not the SPAN element, but the DIV element itself.

Live demo: (Also on 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>

How can I determine whether or not the key-event occurred inside a SPAN element?

like image 794
Šime Vidas Avatar asked Jul 19 '11 19:07

Šime Vidas


1 Answers

This can be done using the selection APIs:

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

Note: The above example is simplistic. See the SO post linked below for a complete solution to the selection problem.

Demo (also on 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>

References:

  • https://developer.mozilla.org/en/DOM/Selection/anchorNode
  • How can I get the DOM element which contains the current selection?
like image 143
Wayne Avatar answered Oct 16 '22 07:10

Wayne