2016-01-11 49 views
6

我有兩個事件處理程序設置爲單擊事件。一個在表中的所有<th>中,另一個在文檔上。當anchor標記被覆蓋時,更改innerHTML會中斷parentNode嗎?怎麼修?

<th>處理程序中部分代碼更改了單擊元素的innerHTML。最重要的是,我認爲,th標籤內有一個錨標籤。

文檔處理程序中部分代碼檢查單擊元素的父節點。

出現這兩個事實導致問題。如果我註釋掉innerHTML修改線,則一切正常。如果我把它放在裏面,我得到元素的「null」parentNode

這是一個已知的問題,如果是的話有什麼解決方案?它是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>'; 

線,你會體驗到所期望的行爲。

我認爲這是因爲事件發生在<a>而不是<th>上,然後我在innerHTML調用中用一個新錨替換了該錨。我將如何解決這個問題?

+4

可以嗎分享相關的代碼片段? – gurvinder372

+1

沒有片段,它不清楚DOM的哪些部分受到影響 –

+0

不,這不是問題,而且可能是代碼中的其他內容。請提供顯示此問題的相關代碼,否則此問題是無關緊要的。 –

回答

3

發生這種情況是因爲被請求的父節點被點擊的元素不再存在於文檔中。你用一個完全不同的元素取代了它。

而不是更改父項的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>