2013-06-18 46 views
0

我創建了多個div,其中class="extra"。然後我添加刪除按鈕到每個div爲了刪除每個div分別。所以我的代碼是:在遞歸中刪除當前父節點

var exr = document.getElementsByClassName("extra");   
    for(var i = 0 ;i<exr.length;i++){   
     var delbt = document.createElement("button"); 
     delbt.className="floatbutton_3 font_b" 
     delbt.innerHTML="delete"; 
     exr[i].appendChild(delbt); 
     delbt.onclick= function(i){ return function(){ exr[i].parentNode.removeChild(exr[i]) } }(i); 
    } 

問題是,按鈕無法刪除它應該刪除的按鈕。看來在最後刪除之後,索引被改變了。如何避免這種情況發生?

謝謝!

+0

爲什麼用jQuery標記,如果你不使用它?你打算使用jQuery嗎? –

+0

您正在遍歷'inserter',同時訪問'exr',並修改nodeList __does__更改索引。重複相反的方式。 – adeneo

+0

嘗試向下,例如'for(var i = exr.length; i> 0; i - ){' – davidkonrad

回答

0

使用thisonclick函數引用被點擊的按鈕內 - 所以用this.parentNode更換excr[i],如預期的代碼應該執行。

+1

*「問題在於,在函數內,'i'是引用click事件的參數。」*不,這是一個IIFE。再次查看代碼。 –

+0

奇怪...是一個編輯?無論如何,技術要點仍然是:「我」不是要尋找的東西(這很令人困惑,因爲這也是迭代器進一步擴大範圍的索引)。同時,'這個'將是可靠的。 – Barney

0

代碼看起來喜歡它應該工作,但只要你不添加或刪除元素。這就是你正在做的。

有一個更簡單和更可靠的解決方案:您可以在事件處理函數內使用this來引用當前元素。

delbt.onclick = function() { 
    var div = this.parentNode; // you want to remove the div, not the button 
    div.parentNode.removeChild(div); 
}; 

我建議閱讀quirksmode.org the excellent articles about event handling,特別是約traditional event handling(因爲這是你使用的是什麼)。

0

操作方法......

var exr = document.getElementsByClassName("extra");   
for(var i = 0 ;i<inserter.length;i++){   
    var delbt = document.createElement("button"); 
    delbt.className="floatbutton_3 font_b" 
    delbt.innerHTML="delete"; 
    exr[i].appendChild(delbt); 
    delbt.index = i; 
    delbt.onclick= function(i){ var me = this; return function(){ exr[me.index].parentNode.removeChild(exr[i]) } }(i); 
} 
+0

這是不正確的。在你的代碼中,'this'引用'window'而不是DOM元素。 –

+0

糟糕...抱歉...混合jQuery和常規JS在這裏。我的壞...所以你可以說'var me =(event || window.event).target;'而不是'var me = this;' – mohkhan

+0

這也行不通,與jQuery無關。這是一個IIFE,即該函數立即執行**。該函數返回的函數是事件處理程序,並且'this'指的是元素,'event'可用。 –

0

我將添加一個jQuery的解決方案:

$('.extra').append(function() { 
    return $('<button />', {'class':'floatbutton_3 font_b', html:'delete'}); 
}); 

$('.floatbutton_3').on('click', function() { 
    $(this).closest('div').remove(); 
}); 

FIDDLE

0

由於getElementsByClassName()返回現場設置,你可以做一個淺拷貝第一:

var exr = [].slice.call(document.getElementsByClassName("extra"), 0); 
0

getElementsByClassName()返回的HTMLCollection 。這是一個活動列表,當底層結構發生變化時會發生變化。因此,即使您沒有激活刪除列表中的元素,當您刪除相應的HTML元素時,它們仍會自動從其中刪除。

通過將i傳遞給匿名函數,您可以修正索引。因此,無論何時單擊第三個刪除按鈕,它都會嘗試刪除列表中的第三個元素。但是如果你已經刪除了第一個和第二個元素,那麼列表也會被修改。所以你的第三個按鈕將被列表中的第一個項目表示,但它會嘗試找到第三個按鈕。

爲了避免這個問題,你可以在完整的元素傳遞給匿名函數,而不僅僅是指數:

for(var i = 0 ;i<exr.length;i++){   
    var delbt = document.createElement("button"); 
    delbt.className="floatbutton_3 font_b" 
    delbt.innerHTML="delete"; 
    exr[i].appendChild(delbt); 
    delbt.onclick = function(el){ return function(){ el.parentNode.removeChild(el) } }(exr[i]); 
} 
0

你可以在點擊事件中使用currentTarget當前。

這隻會刪除被點擊的按鈕的父div。

var exr = document.getElementsByClassName("extra"); 
for(var i = 0 ;i<exr.length;i++){ 
    var delbt = document.createElement("button"); 
    delbt.className="floatbutton_3 font_b" 
    delbt.innerHTML="delete"; 
    exr[i].appendChild(delbt); 
    delbt.onclick= function(event){ 
     event.currentTarget.parentElement.remove(); 
    } 
}