2016-03-21 43 views
2

我最近開始學習Javascript。我目前正在做一些項目,並遇到了一個問題。我正在創建聯繫人管理器頁面,其想法是用戶輸入名稱,電子郵件和電話號碼,這些名稱將顯示在下面動態創建的HTML表格中。有三個按鈕。第一個按鈕保存信息,第二個清除新用戶的輸入字段,第三個刪除localStorage信息。當您單擊表格中的一行時,該行中的信息將顯示在上面的輸入字段中。當你點擊HTML表格中的一行時,一切正常,但是當我點擊使用JavaScript創建的表格中的行時,它不起作用。兩個表具有相同的結構,ID和類,但另一個不起作用。 JavaScript的信息顯示在dvcontainer div中。動態創建Javascript表問題

下面的代碼

(function(){ 
 

 
var Person = { 
 
    Name: "", 
 
    Email: "", 
 
    MobileNo: "" 
 
}; 
 

 
var applogic = { 
 
    clearuielements: function() { 
 
     var inputs = document.getElementsByClassName("c1"); 
 
     for (i = 0; i < inputs.length; i++) { 
 
      inputs[i].value = ""; 
 
     } 
 
    }, 
 
    
 
    saveitem: function() { 
 
     var lscount = localStorage.length; 
 
     var inputs = document.getElementsByClassName("c1"); 
 
      Person.Name = inputs[0].value; 
 
      Person.Email = inputs[1].value; 
 
      Person.MobileNo = inputs[2].value; 
 
      localStorage.setItem("Person_" + lscount, JSON.stringify(Person)); 
 
      location.reload(); 
 
    }, 
 
    
 
    loaddata: function() { 
 
     var datacount = localStorage.length; 
 
     if (datacount > 0) { 
 
      var render = "<table id='t_id' border='1'>"; 
 
      render += "<tr><th>Name</th><th>Email</th><th>Phone</th></tr>"; 
 
      for (i = 0; i < datacount; i++) { 
 
       var key = localStorage.key(i); 
 
       var person = localStorage.getItem(key); 
 
       var data = JSON.parse(person); 
 

 
       render += "<tr><td class='row_s edit_row'>" + data.Name + "</td>"; 
 
       render += "<td class='row_t'>" + data.Email + "</td>"; 
 
       render += "<td class='row_d'>" + data.MobileNo + "</td></tr>"; 
 
      } 
 
      render+="</table>"; 
 
      dvcontainer.innerHTML = render; 
 
     } 
 
    }, 
 
    
 
    clearstorage: function() { 
 
     var storagecount = localStorage.length; 
 
     if (storagecount > 0) { 
 
      for (i = 0; i < storagecount; i++) { 
 
       localStorage.clear(); 
 
      } 
 
     } 
 
     window.location.reload(); 
 
    } 
 
}; 
 
    
 
    var btnsave = document.getElementById('btnsave'); 
 
    btnsave.addEventListener('click', applogic.saveitem, false); 
 

 
    var btnclear = document.getElementById('btnclear'); 
 
    btnclear.addEventListener('click', applogic.clearuielements, false); 
 

 
    var btnclearstorage = document.getElementById('btnclearstorage'); 
 
    btnclearstorage.addEventListener('click', applogic.clearstorage, false); 
 

 
    window.onload = function() { 
 
    applogic.loaddata(); 
 
    }; 
 
    
 
})(); 
 

 
var edit_row = document.querySelectorAll('#t_id .edit_row'); 
 
for(var i=0; i<edit_row.length; i++) { 
 
    edit_row[i].addEventListener('click', function(e){ 
 
     var tr_parent = this.parentNode; 
 
     document.getElementById('e_site').value = tr_parent.querySelector('.row_s').innerHTML; 
 
     document.getElementById('e_title').value = tr_parent.querySelector('.row_t').innerHTML; 
 
     document.getElementById('e_desc').value = tr_parent.querySelector('.row_d').innerHTML; 
 
    }, false); 
 
}
<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
     <title>nesto</title> 
 
    </head> 
 
    <body> 
 

 
    <form action="#" method="post" id="edit_form"> 
 
     Person Name:<input name="e_site" id="e_site" type="text" class="c1" /><br/> 
 
     Email:<input name="e_title" id="e_title" type="text" class="c1" /><br/> 
 
     Mobile No:<input name="e_desc" id="e_desc" type="text" class="c1"/><br/> 
 
    </form> 
 

 
    <td><input id="btnsave" type="button" value="Save" /></td> 
 
    <td><input id="btnclear" type="button" value="Clear" /></td> 
 
    <td><input id="btnclearstorage" type="button" value="Clear Storage" /></td> 
 

 
    <div id="dvcontainer"></div> 
 
     
 
    
 
     <!-- 
 
     <table id="t_id" border="1"> 
 
      <tr> 
 
       <td class="row_s edit_row">yyyy</td> 
 
       <td class="row_t">yyyy</td> 
 
       <td class="row_d">yyyyy</td> 
 
      </tr> 
 
     </table> 
 
     --> 
 
    
 
     
 
    <script type="text/javascript" src="funkcije.js"></script> 
 

 
    </body> 
 
</html>

+0

我沒有看到任何表,當我運行的代碼片段。 – John

+0

您必須在加載數據時動態添加綁定。 –

+0

最有可能發生的事情是在加載其他表之前將您的事件偵聽器添加到表中。因此,在創建動態表後,您需要添加事件偵聽器。 – Adjit

回答

0

你需要在渲染表中添加綁定。一種方法是將代碼末尾的綁定循環移動到loaddata函數中。

像這樣的工作:

loaddata: function() { 
     var datacount = localStorage.length; 
     if (datacount > 0) { 
      var render = "<table id='t_id' border='1'>"; 
      render += "<tr><th>Name</th><th>Email</th><th>Phone</th></tr>"; 
      for (i = 0; i < datacount; i++) { 
       var key = localStorage.key(i); 
       var person = localStorage.getItem(key); 
       var data = JSON.parse(person); 

       render += "<tr><td class='row_s edit_row'>" + data.Name + "</td>"; 
       render += "<td class='row_t'>" + data.Email + "</td>"; 
       render += "<td class='row_d'>" + data.MobileNo + "</td></tr>"; 
      } 
      render+="</table>"; 
      dvcontainer.innerHTML = render; 


      //add bindings 
      var edit_row = document.querySelectorAll('#t_id .edit_row'); 
      for(var i=0; i<edit_row.length; i++) { 
       edit_row[i].addEventListener('click', function(e){ 
        var tr_parent = this.parentNode; 
        document.getElementById('e_site').value = tr_parent.querySelector('.row_s').innerHTML; 
        document.getElementById('e_title').value = tr_parent.querySelector('.row_t').innerHTML; 
        document.getElementById('e_desc').value = tr_parent.querySelector('.row_d').innerHTML; 
       }, false); 
      } 

     } 

見一個完整的例子在這個JS小提琴:https://jsfiddle.net/9n8ecmj8/

希望幫助!

+1

感謝隊友,這有所幫助。現在它工作得很好。 –

0

如果向DOM添加新元素並希望它們具有事件偵聽器,則需要在添加元素後將偵聽器添加到元素。

看起來像將腳本事件監聽器添加到腳本加載時存在的元素,但不會將其添加到動態創建的元素中。設置點擊偵聽器的代碼在loaddata函數綁定到window.onload之前運行。

+0

我明白了,現在很高興知道這一點。謝謝! –

0

您創建任何新的表格單元格之前,您首次加載JavaScript時就會執行您爲添加監聽器而寫的for循環。要在DOM元素上註冊事件偵聽器,該元素必須首先存在,對嗎? :)

你需要做的是所謂的事件代表團。基本上,在JavaScript運行之前,您可以在網頁上存在的DOM元素上連接事件監聽器。此DOM元素必須是您的目標元素的父項。

就你的情況而言,ID爲「dvcontainer」的div會做得很好,因爲你在其中渲染表。首先,我們將選擇它:

var myContainer = document.querySelector('#dvcontainer'); 

myContainer.addEventListener('click', function(e) { 
    //... 
}; 

如果我們添加一個事件監聽器myContainer中,它會調用單擊處理功能的任何點擊到整個DIV。我們知道e.target選擇點擊的元素,但對元素的有效方法稱爲比賽會告訴我們,如果所選元素相匹配的選擇字符串(如「#container的」,「.username」,甚至「H2」)。

什麼是你的表的好選擇?爲了簡單起見,我們使用「td」來處理任何獲得點擊的表格單元格< td>。這裏有一個工作解決您的問題(更換你與這個循環):

var myContainer = document.querySelector('#dvcontainer'); 

// adds event listener on myContainer 
myContainer.addEventListener('click', function(e) { 

    // if the clicked element exists and is a TD element 
    if (e.target && e.target.matches('td')) { 

    // your code from your original for loop 
    var tr_parent = e.target.parentNode; 
    document.getElementById('e_site').value = tr_parent.querySelector('.row_s').innerHTML; 
    document.getElementById('e_title').value = tr_parent.querySelector('.row_t').innerHTML; 
    document.getElementById('e_desc').value = tr_parent.querySelector('.row_d').innerHTML; 
    } 
}, false); 

這種方法的最大好處是,你只需要設置事件監聽器一次。無論您使用JS動態創建一個,兩個還是一千個新的DOM元素,它們都將「繼承」相同的偵聽器和處理程序,而無需在運行中註冊每個元素。

希望這對你有幫助!

更多:

香草JS事件委派:https://davidwalsh.name/event-delegate

element.matches():https://developer.mozilla.org/en-US/docs/Web/API/Element/matches

+0

謝謝,我也會嘗試這種方法。 –

+0

沒問題。讓我知道事情的後續! –