Capture keypress/down/up events on a descendant of contenteditable element

Viewed 275

I already read about similar issues like this topic Events on children of contenteditable element but I still can't find any solution.

https://jsfiddle.net/zbxg7jop/

HTML

<div id="main" contenteditable="true"> </div>
<button id="addLine">Add a line</button>

JS

var func_add_line = function() {

  var div = document.createElement("div"),
      texte = document.createTextNode("Click me now or use your keyboard on me");
  div.appendChild(texte); 
  div.addEventListener("click",function(){ alert("Click is working") }, false);
  div.addEventListener("keypress",function(){ alert() }, false);
  document.getElementById("main").appendChild(div)
}

document.getElementById("addLine").addEventListener("click", func_add_line, false)

I know it's because only the parent element with contenteditable attribute gets the key events, the event is bubbling. And it's the same if I use event.target.

So, is there a workaround solution for what I'm trying to do ?

Thanks !

EDIT: Well, it seems to work if at least, a intermediate container between parent and child is non-contenteditable.

<div id="main" contenteditable="true">
    <div id="intermediate" contenteditable="false">
        <div class="appended" contenteditable="true"></div>
    </div>
</div>

This way I can capture keyevents from the inner DIV. But there are other issues coming with this solution so still looking for a workaround :)

1 Answers

Well, I found a workaround which works for me but doesn't realy solves the capture of key events

I preferred to capture all the key events in the document, and check at any input the position of the caret, see :

var selectionRange;

var setSelection = function() {
  if (window.getSelection) {
    var sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
      selectionRange = sel.getRangeAt(0);
    }
  } 
}

var caretParent = function(){
    var par = selectionRange.commonAncestorContainer;
    return (par.nodeType == 3) ? par.parentNode : par;
}

document.addEventListener('click', setSelection, false);
document.addEventListener('keyup', function(e){
  setSelection();
  var currentElem = caretParent();
  if (13 == e.keyCode && currentElem .className == "innerElem") {
    console.log("Yes We Did It !")
  }

}, false);

HTML :

<div id="main" contenteditable="true">
    <div class="innerElem">I want to capture Key Events here !</div>
    <div class="innerElem">Me too !</div>
</div>

Still looking for a workaround with real event capture ^^

Related