2016-01-11 7 views
6

Ich habe zwei Event-Handler für das Click-Ereignis eingestellt. Eine auf allen <th> s in einer Tabelle und eine andere generische auf dem Dokument.Ändern von innerHTML bricht parentNode, wenn das Anchor-Tag überschrieben wird? Wie repariert man?

Teil des Codes in den <th> Handler ändert die innerHTML- des angeklickten Elements. Entscheidend ist, denke ich, dass es innerhalb des Tags th ein Anker-Tag gibt.

Teil des Codes in dem Dokument-Handler prüft die parentNode des angeklickten Elements.

Es erscheint, dass diese beiden Tatsachen ein Problem verursachen. Wenn ich die innerHTML-Modifikationszeile auskommentiere, funktioniert alles gut. Wenn ich es aber lasse, bekomme ich "null" für das Element parentNode.

Ist das ein bekanntes Problem, und wenn ja, was ist die Lösung? Ist es ein Bug in Chrome, oder verhält sich JavaScript/DOM aus irgendeinem Grund?

function isInside(eChild, eParent) { 
 
    alert('element is ' + eChild); 
 
    if (eChild === eParent) { 
 
    return true; 
 
    } 
 

 
    if (eChild === document) { 
 
    return false; 
 
    } 
 

 
    return isInside(eChild.parentNode, eParent); 
 
} 
 

 
function init1() { 
 
    document.getElementById('th').addEventListener('click', function(e) { 
 
    document.getElementById('th').innerHTML = '<a href="#">Changed</a>'; 
 
    }); 
 
} 
 

 
function init2() { 
 
    document.addEventListener('click', function(e) { 
 
    if (isInside(e.target, document.getElementById('table'))) { 
 
     alert('found in table'); 
 
    } else { 
 
     alert('not found in table'); 
 
    } 
 
    }); 
 
} 
 

 
init1(); 
 
init2();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 

 
<table id="table"> 
 
    <thead> 
 
    <tr> 
 
     <th id="th"><a href="#">Click me</a> 
 
     </th> 
 
    </tr> 
 
    </thead> 
 
</table>

Wenn Sie die

document.getElementById('th').innerHTML = '<a href="#">Changed</a>'; 

Linie in der JavaScript-Kommentar aus werden Sie das gewünschte Verhalten erleben.

Ich nehme an, es ist, weil das Ereignis auf dem <a> statt auf dem <th> feuern wird, und ich dann diesen Anker durch einen neuen im innerHTML Anruf ersetze. Wie würde ich das reparieren?

+4

können Sie das entsprechende Code-Snippet teilen? – gurvinder372

+1

Ohne Schnipsel, seine unklar, welche Teile des DOM wird –

+0

es ist kein Problem, und ist sonst in Ihrem Code wahrscheinlich etwas, das kein betroffen. Bitte geben Sie den entsprechenden Code an, der dieses Problem anzeigt, andernfalls ist diese Frage nicht Thema. –

Antwort

3

Dies geschieht, weil das Element, das nicht mehr in dem Dokument existiert an dem Punkt, dass seine parentNode angefordert wird geklickt wurde. Sie haben es durch ein völlig anderes Element ersetzt.

Statt die innerHTML- des Mutter ändern, damit das Element ersetzt, das mit einem neuen Elemente geklickt wurde, ändern Sie einfach das vorhandene Element.

ich die volle Demo kondensiert haben unten Platz zu sparen, aber das Fleisch der Lösung ist hier:

var th = document.getElementById('th'); 
var link = th.querySelector('a'); 

th.addEventListener('click', function(e) { 
    link.textContent = 'Changed'; 
}); 

Hier ist die Demo:

function isInside(eChild, eParent) { 
 
    alert('element is ' + eChild); 
 
    if (eChild === eParent) return true; 
 
    if (eChild === document) return false; 
 
    return isInside(eChild.parentNode, eParent); 
 
} 
 

 
var th = document.getElementById('th'); 
 
var link = th.querySelector('a'); 
 

 
th.addEventListener('click', function(e) { 
 
    link.textContent = 'Changed'; 
 
}); 
 

 
document.addEventListener('click', function(e) { 
 
    if (isInside(e.target, document.getElementById('table'))) alert('found in table'); 
 
    else alert('not found in table'); 
 
});
<table id="table"><thead><tr><th id="th"><a href="#">Click me</a></th></tr></thead></table>

Verwandte Themen