最近在编写一个网页版Todo应用的过程中遇到一些jQuery的特性,不知道的话容易掉进坑里。
- 引用jQuery的script标签必须放在html文件的后部,让浏览器在将页面所有元素渲染完之后才运行jQuery脚本,否则选择器选不到写在html页面中的元素;
- 和上面一样的道理,用js新创建元素后,如果元素有事件绑定,不要忘记创建完再加一段绑定事件的代码;
- 一个元素可以绑定多个事件,即使是相同的事件。在on之前先off来避免多次绑定。
10-27更新:今天突然发现,上面第二种情况,正确的做法是“事件委托”:
on方法一般的用法是传递两个参数:一个事件类型,一个执行函数。其实完整用法是:
$(selector).on(event,childSelector,data,function)
事件委托的做法是,对要绑定事件的元素的父元素(或者祖先元素)使用on方法,而将要绑定事件的元素的选择器作为childSeletor传入。这样即使要绑定事件的元素还未创建,我们就相当于告诉其父元素或祖先元素,盯着点,你的这个孩子出生要给他绑个事件,我喝杯茶去。
拿我的Todo应用举个栗子,每个清单项里有一个详情按钮,一个删除按钮,之前的做法是,先定义好“监听点击详情/删除按钮”的函数:
function listenDelTask() { $('.delete').off('click').on('click', function() { //先off解绑 var index = $(this).parent().data('index'); if (confirm('Confirm deleting?')) { delTask(index); }; }); }
注意要先off掉,否则添加多个项之后,点一次删除会弹出相应多次确认弹框。因为元素可以多次绑定相同的事件。
然后在每次添加清单项后再调用一次相应的监听函数
function addTask(task) { taskList.push(task); /*其他相关操作*/ listenDelTask; //监听点击删除按钮事件 listenCheckDetail; //监听点击详情按钮事件 }
每次都会对当前页面上所有的相应元素进行事件绑定,而不只是新加的那个元素。
使用事件委托之后,只需调用父元素的on方法一次就可以:
$('.task-list').on('click', '.delete', function() { //选择父元素,参数中传入子选择器 var index = $(this).parent().data('index'); //注意this仍然指向子元素 if (confirm('Confirm deleting?')) { delTask(index); }; });
注意执行函数中的this仍然指向子元素,而不是父元素或祖先元素。
不管性能方面有没影响,代码少才显得优雅嘛。