关于JavaScript中的事件代理
今天面试某家公司Web前端开发岗位,前面的问题回答的都还算凑活,并且又问了一下昨天面试时做的一道数组去重问题的解题思路(关于数组去重问题,可以观赏我前几天写的:http://www.cnblogs.com/craftsman-gao/p/4766223.html。幸好前几天专门看过这个问题,答题时才能轻松应对啊),因为这些以前都有过研究,所以回答起来并没有太大困难。然而,最后面试官又出了一道代码题让我涨姿势了。题目本身很简单:一个ul中有一千个li,如何给这一千个li绑定一个鼠标点击事件,当鼠标点击时alert出这个li的内容和li的位置坐标xy,
<ul id="ulItem">
<li id="li1">1</li>
<li id="li2">2</li>
<li id="li3">3</li>
...
<li id="li1000">1000</li>
</ul>
需要考虑到浏览器兼容性、事件冒泡、效率等问题。看到问题后我就直接在纸上写下了如下答案:
var ulItem = document.getElementById("ulItem");
var lis = document.getElementsByTagName("li");
for(var i=0; i<lis.length; i++){
lis[i].onclick = function(){
alert("内容:"+this.innerHTML);
alert("位置:"+getElementPosition(this).x+","+getElementPosition(this).y;
}
}
function getElementPosition(e){
var x=0,y=0;
while(e != null){
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
}
return {x:x, y:y};
}
写完了又看了一遍感觉没必要考虑兼容性、事件冒泡啊。效率的话,想了想,也想不出怎么提升了,就这样给面试官看了。面试官人也挺好的,他看了之后说:你并没有考虑到我说的重点啊,你这样1000次循环添加点击事件效率是很低的。然后就跟我讲了利用事件冒泡的特性,来提高效率,即事件代理(ps:以前做项目有遇到过要阻止事件冒泡的时候,但利用事件冒泡特性提高效率却还完全不知道)。听了面试官讲的涨了姿势,回来后自己也上网查了一下,现在自己再总结下当做记录自己学习的过程吧:
事件代理(Event Delegation),又称之为事件委托。是 JavaScript 中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。
为什么要这么做?众所周知,DOM操作是十分消耗性能的,所以重复的事件绑定简直是性能杀手。而事件代理的核心思想,就是通过尽量少的绑定,去监听尽量多的事件。程序猿的事,没代码说个J8,下面贴出代码:
var ulItem = document.getElementById("ulItem");
ulItem.onclick = function(e){
e = e || window.event;//这一行和下一行是为了兼容IE8以及之前版本
var target = e.target || e.srcElement;
if(target.tagName.toLowerCase() === "li"){
alert(target.innerHTML);
alert("位置为:"+getElementPosition(target).x+","+getElementPosition(target).y);
}
}
function getElementPosition(e){
var x=0,y=0;
while(e != null){
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
}
return {x:x, y:y};
}
嗯,现在代码去掉了for循环,提高了效率,也有了兼容性方面的处理,感觉这个答案应该可以了吧。上面说的也就是为了一道笔试题,下面就再本着学术研究的思想说说事件代理:
在传统的事件处理中,你按照需要为每一个元素添加或者是删除事件处理器。然而,事件处理器将有可能导致内存泄露或者是性能下降——你用得越多这种风险就越大。JavaScript事件代理则是一种简单的技巧,通过它你可以把事件处理器添加到一个父级元素上,这样就避免了把事件处理器添加到多个子级元素上。事件代理用到了两个在JavaSciprt事件中常被忽略的特性:事件冒泡以及目标元素。当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。任何一个事件的目标元素都是最开始的那个元素,在我们的这个例子中也就是按钮,并且它在我们的事件对象中以属性的形式出现。使用事件代理,我们可以把事件处理器添加到一个元素上,等待一个事件从它的子级元素里冒泡上来,并且可以得知这个事件是从哪个元素开始的。
关于事件代理,今天也是初次接触,就先写到这吧。
关于JavaScript中的事件代理的更多相关文章
- 关于JavaScript中的事件代理(例子:ul中无数的li上添加点击事件)
面试题:一个ul中有一千个li,如何给这一千个li绑定一个鼠标点击事件,当鼠标点击时alert出这个li的内容和li的位置坐标xy. 看到这个题目,我们一般首先想到的思路是,for循环,遍历1000次 ...
- JavaScript中的事件代理/委托
事件委托在JS高级程序设计中的定义为"利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件" 如何理解上面的这句话呢,在网上,大牛们一般都使用收快递这个例子来解释的, ...
- 了解javascript中的事件(二)
本文目录如下: 零.寒暄 一.事件的分类 二.事件代理 2.1 问题引出 2.2 什么是事件代理 2.3 完整示例 二.事件代理 三.事件代理思想的用处 四.总结 零.寒暄 这篇博客本该出现在两个月以 ...
- js实例分析JavaScript中的事件委托和事件绑定
我们在学习JavaScript中,难免都会去网上查一些资料.也许偶尔就会遇到“事件委托”(也有的称我“事件代理”,这里不评论谁是谁非.以下全部称为“事件委托”),尤其是在查JavaScript的事件处 ...
- javascript 中的事件机制
1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...
- JavaScript中的事件对象
JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...
- JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获
先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...
- javascript中onclick事件能调用多个方法吗
Q: javascript中onclick事件能调用多个方法吗? A: 可以的,方法如下onclick="aa();bb();cc();"每个方法用“;”分号隔开就行了
- 深入理解javascript中的事件循环event-loop
前面的话 本文将详细介绍javascript中的事件循环event-loop 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器 ...
随机推荐
- 很多Python新手教程
重要提示 这不是一个教程新手程序员准备,你担任很快编程,或者没有使用1至2程序设计语言,请移步!这是一些编程经验准备.它最出名Java或C,理解命令行,Shell等待.简而言之,面向老鸟的,让老鸟高速 ...
- win8/win10/win2012r2 存储池 冗余分析
StorageSpace:a. Simple,相当于RAID0,无冗余,不考虑b. Two-way Mirror,双重镜像,至少2块盘,性能单盘,可以坏一块盘c. Three-way Mirror,三 ...
- 【原创】leetCodeOj --- Largest Number 解题报告
原题地址: https://oj.leetcode.com/problems/largest-number/ 题目内容: Given a list of non negative integers, ...
- Eclipse正确导入第三方project
前言 昨晚,在不同的Android做出最终的在线测试时间,在其他平台上正常升级的提示突然报告出来"java.lang.NoClassDefFoundError"误.拉什adb lo ...
- 十一:Java之GUI图形Awt和Swing
一. AWT和 Swing AWT 和 Swing 是 Java 设计 GUI用户界面的基础.与 AWT 的重量级组件不同,Swing 中大部分是轻量级组件.正是这个原因,Swing 差点儿无所不能, ...
- isset,empty,is_null小知识
<?php /** 在这项研究开始时,有那么多的人不能很好的运用isset,empty,is_null正确null,false等待值回报值做出正确的推理,在这里,我自己总结通过学习小知识,随后的 ...
- js字的数目的计算方法(与word计算公式为)
[背景] 用户往往需要一定数量的单词填写必填字段限制,但js由value.length取出来的往往差异很大,与实际的话.通常真正的用户抱怨.很显然,我没有写那么多字,但系统提示超过字数限制.然后,我学 ...
- 如何区分MNO和MVNO
MVNO(Mobile Virtaul Network Operator)虚拟网络运营商,没有自己的物理网络,租用MNO(Mobile Network Operator)网络提供的网络服务. 我们知道 ...
- 笔试题&面试题:输入一个维度,逆时针打印出一个指定矩阵
称号:考虑到用户层面.打印出指定的矩阵,例如,一个给定的用户10,例如,下面的输出应被视为在图: 程序如下所示: #include <stdio.h> #include <mallo ...
- android:强大的图像下载和缓存库Picasso
1.Picasso一个简短的引论 Picasso它是Square该公司生产的一个强大的图像下载并缓存画廊.官方网站:http://square.github.io/picasso/ 仅仅须要一句代码就 ...