如何有效地添加JS侦听器

时间:2018-02-24 21:32:33

标签: javascript listener

我正在进行课程作业以创建待办事项列表。在我的CustomPrompt()函数中,我创建了一个捕获器来捕获回车键。所以似乎每次我添加一个todo我都会创建一个新的监听器。这是正确的,有没有办法只用一个听众来做到这一点?



function CustomPrompt(){
	this.render = function(dialog,func){
		var winW = window.innerWidth;
	  var winH = window.innerHeight;
		var dialogoverlay = document.getElementById('dialogoverlay');
	  var dialogbox = document.getElementById('dialogbox');

		dialogoverlay.style.display = "block";
	  dialogoverlay.style.height = winH+"px";
		dialogbox.style.left = (winW/2) - (550 * .5)+"px";
	  dialogbox.style.top = "100px";
	  dialogbox.style.display = "block";

		document.getElementById('dialogboxhead').innerHTML = '&nbsp';
	  document.getElementById('dialogboxbody').innerHTML = dialog;
		document.getElementById('dialogboxbody').innerHTML += '<br><input id="prompt_value1"  >';
		document.getElementById('dialogboxfoot').innerHTML = '&nbsp';
		document.getElementById('prompt_value1').focus();
		//document.getElementById('dialogboxfoot').innerHTML = '<button onclick="Prompt.ok(\''+func+'\')">OK</button> <button onclick="Prompt.cancel()">Cancel</button>';
		const node = document.getElementById("prompt_value1");
		node.addEventListener("keyup", function(event) {
		    if (event.key === "Enter") {

					Prompt.ok('newToDo');

		        
		    }
	   });
	}
	this.cancel = function(){
		document.getElementById('dialogbox').style.display = "none";
		document.getElementById('dialogoverlay').style.display = "none";
	}
	this.ok = function(func){
		var prompt_value1 = document.getElementById('prompt_value1').value;
		window[func](prompt_value1);
		document.getElementById('dialogbox').style.display = "none";
		document.getElementById('dialogoverlay').style.display = "none";
	}
}
var Prompt = new CustomPrompt();

function newToDo(val){
   
   var ul = document.getElementById('todo-list'); //ul
   var li = document.createElement('li');//li

   var checkbox = document.createElement('input');
      checkbox.type = "checkbox";
      checkbox.value = 1;
      checkbox.name = "todo[]";

    li.appendChild(checkbox);

    var span = document.createElement("SPAN");
        var att = document.createAttribute("class");
        att.value = 'centerSpan';
        span.setAttributeNode(att);

    var text = document.createTextNode(val);
    span.appendChild(text);
    li.appendChild(span);

    var but = document.createElement("BUTTON");
        but.classList.add("rightButton");
        text = document.createTextNode('X');
        but.append(text);



    li.appendChild(but);
    console.log(li);
    ul.appendChild(li);
}



window.onload= function(){

const classNames = {
  TODO_ITEM: 'todo-container',
  TODO_CHECKBOX: 'todo-checkbox',
  TODO_TEXT: 'todo-text',
  TODO_DELETE: 'todo-delete',
}

const list = document.getElementById('todo-list')
const itemCountSpan = document.getElementById('item-count')
const uncheckedCountSpan = document.getElementById('unchecked-count')





var ulist = document.getElementById('todo-list');

ulist.addEventListener('click', function(e){
  if( e.target.nodeName == "BUTTON") {
		// List item found!  Output the ID!
    e.target.parentNode.remove();
	}
});

}
&#13;
#dialogoverlay{
	display: none;
	opacity: .8;
	position: fixed;
	top: 0px;
	left: 0px;
	background: #FFF;
	width: 100%;
	z-index: 10;
}
#dialogbox{
	display: none;
	position: fixed;
	background: #0388c6;
	border-radius:15px;
	width:550px;
	z-index: 10;
}
#dialogbox > div{ background:#0388c6; margin:8px; }
#dialogbox > div > #dialogboxhead{ background: #0388c6; font-size:19px; padding:10px; color:#ccc; }
#dialogbox > div > #dialogboxbody{ background: #00547d; padding:20px; color:#FFF;border-radius: 30px;}
#dialogbox > div > #dialogboxfoot{ background: #0388c6; padding:10px; text-align:right; }







html, body {
  background-color: #eee;
  margin: 0;
  padding: 0;
}

ul {
  margin: 0;
  padding: 0;
  list-style-type: none;
}

.center {
  align-self: center;
}

.flow-right {
  display: flex;
  justify-content: space-around;
}

.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
  background-color: white;
  height: 100vh;
}

.title, .controls, .button {
  flex: none;
}

.button {
  padding: 10px 20px;
}

.todo-list {
  flex: 1 1 0;
  margin-top: 20px;
  padding: 20px;
  overflow-y: auto;
}

.todo-delete {
  margin: 10px;
}

.todo-checkbox {
  margin: 10px;
}

.todo-container {
  padding: 20px;
  border-bottom: 1px solid #333;
}

.todo-container:first-of-type {
  border-top: 1px solid #333;
}

input[type=checkbox]{
  display:inline-block;
  width:5%;
  margin:0;
  margin-left:20%;
}

.centerSpan{
  text-align:center;
  display:inline-block;
  width:50%;
}
&#13;
<head>
     <meta charset="UTF-8">
     
     <title>TODO App</title>
  </head>

  <body>
     <div id="dialogoverlay"></div>

     <div id="dialogbox">
       <div>
          <div id="dialogboxhead"></div>
          <div id="dialogboxbody"></div>
          <div id="dialogboxfoot"></div>
       </div>
     </div>

     <div class="container center">
       <h1 class="center title">My TODO App</h1>
       <div class="flow-right controls">
         <span>Item count: <span id="item-count">0</span></span>
         <span>Unchecked count: <span id="unchecked-count">0</span></span>
       </div>

       <button class="button center"  onclick="Prompt.render('Input a new ToDo:','newToDo')">New ToDo</button>

       <ul id="todo-list" class="todo-list"></ul>
     </div>

  </body>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

是的,它被称为事件委派。您在所有ToDos的父元素上设置单个侦听器。然后使用事件对象来确定目标元素。我确定您已经看过这样的代码:

element.addEventListener('click', newTodo);

然后,在newTodo(e)中,您将以相同的方式获得值:

var prompt_value1 = document.getElementById('prompt_value1').value;

这个想法充分利用了该语言最重要的功能之一。事件系统允许事件冒泡直到父母。调查JS的事件阶段。