JavaScript event handler to insert new pre tag

1k views Asked by At

I have a set of 3 pre tags that are editable. When someone is on one of the lines and hits 'enter', I want it to insert a new tag below (in the document tree) the one it is on. I have tried to put an event handler on the tags so that this occurs, but the 'onkeypress' doesn't seem to be firing.

<script>
    function handlers(){
        var pres = document.getElementsByTagName("pre");
        for(i=0; i<pres.length;i++){
            pres[i].addEventListener("onkeypress", function(e){
                if(e.which != 13) return;//the ENTER key
                var tag = e.srcElement;
                if(tag.nextSibling){
                    var next = tag.nextSibling;
                    var newPre = document.createElement('pre');
                    tag.nextSibling = newPre;
                    newPre.nextSibling = next;
                }
            var tree = document.getElementById("tree");
            tree.innerHTML = document.getElementByTagName().length;
            });
        }
    }
</script>
<body onload="handlers();">
    <div id="editor" contentEditable="true">
        <pre>1</pre>
        <pre>2</pre>
        <pre>3</pre>
    </div>

    <div>
    <p id="tree"></p>
    </div>
</body>
2

There are 2 answers

3
Shad On BEST ANSWER

You are iterating over the array of elements incorrectly, and you are not attaching event listeners correctly.

I recommend changing your for loop to:

for (var i=0, l=pres.length; i<l; i++) {
    pres[i];//This is where the Element is stored
}

You can read up on attaching event listeners here

Additionally, it would appear: http://jsfiddle.net/vZYpX that the source of the keypress event under "contentEditable" is the actual element that is "contentEditable". So you have to either make the <pre>s content editable (and not the div), or attach the listener to the parent div (that is currently contentEditable).

2
Omeriko On

I'm not sure the 'onkeypress' can be fired from 'pre' tag.

However I have a suggestion: 1. Register document.onmousemove to detect mouse position. 2. Register document.onkeypress event and when detecting the 'enter' key, check if the mouse is over a 'pre' tag. If so, run your code.

It should look like this:

function moveMoveHandler(e)
{
    var evt = window.event || e;
    window.lastMouseX = evt.clientX;
    window.lastMouseY = evt.clientY;
}


function keypressHandler(e)
{
    var evt = window.event || e;

    // handling only 'enter' key
    if (evt.keyCode !== 13) return;

    // getting the element the mouse is on
    var elem = document.elementFromPoint(window.lastMouseX,window.lastMouseY);
    var node = elem;
    // checking if the found node is a child of a 'pre' node
    while (node.nodeName !== "PRE" && node !== document.body)
          node = node.parentNode;        

    if (node.nodeName === "PRE")
    {
         ... INSERT YOUR CODE HERE ...
    }
}


// IE
if (window.attachEvent)
{
   document.attachEvent("onkeypress", keypressHandler);
   document.attachEvent("onmousemove", moveMoveHandler);
}
// other browsers
else 
{
   document.addEventListener("keypress", keypressHandler, false);
   document.addEventListener("mousemove", moveMoveHandler, false);
}