Domanda

I'm trying to write a simple CMS where user can add new paragraphs in contenteditable DIV. Also all paragraph's id's must be re-numbered. I was able to do that with jquery finishing up with this code:

<div class="wrap" contenteditable="true">
    <p class="paragraph" id="parg1" onclick="createNewP('parg1');">  
    Press ENTER at the end of text - works!</p>
    <p class="paragraph" id="parg2" onclick="createNewP('parg2');">  
    Press ENTER in the middle of text - pargId is undefined!</p>
</div>
<div class="showPargId">
    newpargId:<br />
</div>

js:

function createNewP(pargId){ 
    $('.paragraph').removeClass('active');
    $('#' + pargId).addClass('active');
}
$(function(){
    $('.wrap').keyup(function(event) {
        var keycode = (event.keyCode ? event.keyCode : event.which);
        if (keycode == '13') { //create new <p> by pressing ENTER and renumber all <p> id's
            $('.paragraph').removeClass('active');
            var pSum = $('.paragraph').length;
            var i = 1;
            if ( i < pSum ) {
                $('.paragraph').each(function(){
                    $(this).attr('id' , 'parg' + i).attr("onclick" , "createNewP('parg" + i + "');");
                    i++;                    
                });
            }
            var newpargId = window.getSelection().getRangeAt(0).endContainer.id; // id of a new paragraph where the cursor is placed
            $('#' + newpargId).addClass('active');
            $(function(){
                $('.showPargId').append(newpargId + '<br />');                
            });
        } else { //do nothing
        }
    });
});

Everything works great except window.getSelection().getRangeAt(0).endContainer.id; It gives me id of a parent .paragraph only if the text cursor was placed at the end of the text in paragraph when ENTER was pressed. But if cursor is placed in the middle of the text then "newpargId" id undefined.

You can check it on jsFiddle

Is there any method to get textNode parent ID? like:

window.getSelection().getRangeAt(0).parent().attr('id');

I was trying:

$((newpargId).parentNode.id);

But it doesn't work :(

È stato utile?

Soluzione

You can use closest for that:

$(window.getSelection().getRangeAt(0).endContainer).closest("[id]").attr("id");

Updated Fiddle

closest finds the first element matching the given selector, starting with the current element and then looking at ancestors. The selector [id] matches an element that has an id attribute.

Or if for some reason you want to do it without jQuery:

var parent = window.getSelection().getRangeAt(0).endContainer;
var newpargId = parent.id;
while (!newpargId && parent && parent.nodeName.toUpperCase() !== "BODY") {
    parent = parent.parentNode;
    newpargId = parent.id;
}

Updated Fiddle

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top