javascript cloneNode doesn't copy the event handlers

This article shows how to clone the javascript events along with node when we use the cloneNode method

javascript cloneNode do shallow copy, it doesn't copy the event handler attached to that node or it children. following method will help you to attach javascript events after cloning.



function cloneNodeWithEvents( orgNode ){

var orgNodeEvenets = orgNode.getElementsByTagName('*');
var cloneNode = orgNode.cloneNode( true );
var cloneNodeEvents = cloneNode.getElementsByTagName('*');

var allEvents = new Array('onabort','onbeforecopy','onbeforecut','onbeforepaste','onblur','onchange','onclick',
'oncontextmenu','oncopy','ondblclick','ondrag','ondragend','ondragenter', 'ondragleave' ,
'ondragover','ondragstart', 'ondrop','onerror','onfocus','oninput','oninvalid','onkeydown',
'onkeypress', 'onkeyup','onload','onmousedown','onmousemove','onmouseout',
'onmouseover','onmouseup', 'onmousewheel', 'onpaste','onreset', 'onresize','onscroll','onsearch', 'onselect','onselectstart','onsubmit','onunload');


// The node root
for( var j=0; j<allEvents.length ; j++ ){
eval('if( orgNode.'+allEvents[j]+' ) cloneNode.'+allEvents[j]+' = orgNode.'+allEvents[j]);
}

// Node descendants
for( var i=0 ; i<orgNodeEvenets.length ; i++ ){
for( var j=0; j<allEvents.length ; j++ ){
eval('if( orgNodeEvenets[i].'+allEvents[j]+' ) cloneNodeEvents[i].'+allEvents[j]+' = orgNodeEvenets[i].'+allEvents[j]);
}
}

return cloneNode;

}

2 comments:

  1. Really graceful!

    I have changed a little bit, to ensure the behaviour of the original cloneNode with "DEEP"-parameter. A third parameter ensures the choice to copy events or not. At least I replaced the performance-break "eval". Hope you like it.

    Call it like
    myCloneNode( OriginalNode , true, true );


    myCloneNode = function (oElm, bDeep, bEvents) {
    var
    aInputSubElements
    , eNodeCopy
    , aNodeCopySubElements
    , n1, n2

    ,allEvents = ['onabort','onbeforecopy','onbeforecut','onbeforepaste','onblur','onchange','onclick',
    'oncontextmenu','oncopy','ondblclick','ondrag','ondragend','ondragenter', 'ondragleave' ,
    'ondragover','ondragstart', 'ondrop','onerror','onfocus','oninput','oninvalid','onkeydown',
    'onkeypress', 'onkeyup','onload','onmousedown','onmousemove','onmouseout',
    'onmouseover','onmouseup', 'onmousewheel', 'onpaste','onreset', 'onresize','onscroll','onsearch', 'onselect','onselectstart','onsubmit','onunload']


    // defaults
    bDeep = bDeep||false;
    bEvents = bEvents||false;

    // clone
    eNodeCopy = oElm.cloneNode( bDeep );

    // events
    if (bEvents) {
    aInputSubElements = oElm.getElementsByTagName('*');
    aNodeCopySubElements = eNodeCopy.getElementsByTagName('*')

    // The node root
    for (n2 = 0; n2 < allEvents.length; n2++) {
    if (oElm[allEvents[n2]]) {
    eNodeCopy[allEvents[n2]] = oElm[allEvents[n2]];
    }
    }

    // Node descendants
    for (n1 = 0; n1 < aInputSubElements.length; n1++) {
    for (n2 = 0; n2 < allEvents.length; n2++) {
    if (aInputSubElements[n1][allEvents[n2]]) {
    aNodeCopySubElements[n1][allEvents[n2]] = aInputSubElements[n1][allEvents[n2]];
    }
    }
    }
    }

    return eNodeCopy;
    }

    ReplyDelete