动态创建的Javascript表问题

时间:2016-03-21 20:22:45

标签: javascript html input html-table

我最近开始学习Javascript。我目前正在开展一些项目,但遇到了一个问题。我正在制作联系人管理员页面,其想法是用户输入姓名,电子邮件和电话号码,这些号码将显示在下面动态创建的HTML表格中。有三个按钮。第一个按钮保存信息,第二个按钮清除新用户的输入字段,第三个删除localStorage信息。单击表中的行时,该行的信息将显示在上面的输入字段中。当你点击HTML表格中的一行时,一切正常,但当我点击使用JavaScript创建的表格中的行时,它不起作用。两个表都具有相同的结构,id和#和class,但另一个表不起作用。 信息表单Javascript显示在dvcontainer div。

这是代码



(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);
}
&#13;
<!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>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分: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添加新元素并希望它们具有事件侦听器,则需要在添加后将元素添加到元素中。

看起来您正在将click事件侦听器添加到脚本加载时存在的元素,但不会向动态创建的元素添加任何元素。设置单击侦听器的代码在loaddata函数绑定到window.onload之前运行。

答案 2 :(得分:0)

您编写的用于添加侦听器的for循环在您首次加载JavaScript时执行,早在您创建任何新表格单元格之前。要在DOM元素上注册事件侦听器,该元素必须首先存在,对吧? :)

您需要做的是称为事件委派。基本上,在JavaScript运行之前,在网页上存在的DOM元素上连接一个事件侦听器。此DOM元素必须是目标元素的父元素。

在您的情况下,ID “dvcontainer”的div会很好,因为您在其中呈现表格。首先,我们将选择它:

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

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

如果我们向 myContainer 添加一个事件监听器,它将在任何点击时调用点击处理函数到整个div 。我们知道 e.target 选择了被点击的元素,但是对于名为匹配的元素有一个有用的方法,它会告诉我们所选元素是否与选择器字符串匹配(例如“#”容器“,”。username“,甚至”h2“)。

什么是你的桌子的好选择器?为了简单起见,让我们使用“td”处理任何表格单元&lt;获得点击的td&gt; 。这是解决问题的有效方法(用此替换你的for循环):

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元素,它们都将“继承”相同的侦听器和处理程序,而无需动态注册每个元素。

希望这对你有所帮助!

更多信息:

Vanilla JS事件代表团:https://davidwalsh.name/event-delegate

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