2016-03-21 44 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

没问题。让我知道事情的后续! –