2016-01-11 14 views
6

私は、クリックイベントに対して2つのイベントハンドラを設定しました。 1つは表の<th>であり、もう1つは文書上の一般的なものです。アンカータグが上書きされた場合、innerHTMLを変更するとparentNodeが破損しますか?直し方?

ハンドラ内のコードの一部が、クリックされた要素のinnerHTMLを変更します。重要なのは、thタグ内にアンカータグがあると思います。

ドキュメントハンドラ内のコードの一部が、クリックされた要素のparentNodeをチェックします。

が表示されます。これら2つの事実は問題を引き起こします。 innerHTMLの修正行をコメントアウトすると、すべて正常に動作します。私はそれを残す場合、私は要素のparentNodeの "null"を取得します。

これは既知の問題ですか?その場合、解決策はありますか? Chromeのバグですか?これがJavaScript/DOMが何らかの理由で動作する仕組みですか?

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>

あなたが希望の動作を体験しましょうJavaScriptで

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

行をコメントアウトした場合。

<th>ではなく、<a>でイベントが発生していると仮定して、そのアンカーをinnerHTML呼び出しで新しいものに置き換えています。どのように私はそれを修正するだろうか?

+4

ことができますが、関連するコードスニペットを共有しますか? – gurvinder372

+1

スニペットがないと、DOMのどの部分が影響を受けているのか不明確です –

+0

いいえ、問題はありません。この問題を示す関連コードを入力してください。そうでない場合は、この質問はトピック以外のものです。 –

答えて

3

これは、クリックされた要素が、parentNodeが要求された時点でドキュメント内に存在しなくなったために発生します。あなたは全く別の要素に置き換えました。

親のinnerHTMLを変更する代わりに、クリックされた要素を新しい要素に置き換えるのではなく、既存の要素を変更するだけです。

私はしかし、ソリューションの肉はここにある、スペースを節約するために、次の完全なデモを凝縮しました:

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

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

ここでデモです:

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>

関連する問題