资讯专栏INFORMATION COLUMN

DOM中的各种区别小节

Guakin_Huang / 936人阅读

摘要:欢迎光临小弟博客我的博客原文中的各种区别小节参考普通添加事件和事件绑定的事件监听与捕获和冒泡和的区别

相信大家在DOM的实际开发与学习过程中,肯定也遇到不少需要比较的东西,这里我主要列比较以下几点,更多的区别和总结,希望想到和遇到的朋友给我留言哦。

clientHeight/scrollHeight/offsetHeight

defer vs async

事件模型-捕获/目标/冒泡

普通事件 vs 事件绑定

stopPropagation/preventDefault/return false

target/currentTarget

文中示例显示不是很好,可以直接去小弟博客看原文:DOM中的各种区别小节

各种height/width

CSS盒模型是比较复杂的,尤其是当页面中有滚动条时,仅仅通过css来操作高度宽度是不够的,幸运的是Javascript提供了不少这样的接口。Javascript中clientHeight / cliengWidthscrollHeight / scrollWidthoffsetHeight / offsetWidthheight / width 都可以获取高度和宽度,但是他们有一些细微的差别:

See the Pen 各种height/width区别 by superlin (@superlin) on CodePen.

offsetHeight / offsetWidth:可见区域包含border,对于display:block的元素通过width/height + padding + border可以计算出来。

clientHeight / cliengWidth:可见区域包含padding,不包含border和滚动条,不能通过CSS样式计算出来,取决于滚动条的大小。

scrollHeight / scrollWidth:内容区域的大小,不包含border,包含不在可见区域内的隐藏部分,不能通过CSS样式计算出来。

height / width:不包含borderpadding

另外:滚动条的宽度可以通过如下方式计算:

javascriptscrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth
defer与async

一般情况下,能用async就用async,然后是defer,最后才是什么属性都不带,主要的规则如下:

如果当前脚本是模块化的,而且不依赖其他脚本,使用async

如果当前脚本依赖于其他脚本或被其他脚本所依赖,使用defer

如果脚本文件很小,而且被其他async脚本依赖,可以将当前脚本作为内联脚本放在那些async脚本的前面

事件捕获与冒泡

先来看一个简单的问题,假设有一个element1元素,里面还有一个element2元素。

-----------------------------------
| element1                        |
|   -------------------------     |
|   |element2               |     |
|   -------------------------     |
|                                 |
-----------------------------------

这两个元素都绑定了click事件,如果用户点击element2,那个先触发呢,换句话说事件触发的的顺序是怎样的呢?

  

网景公司说element1优先,这叫事件捕获(event capturing)

微软则坚持element2优先,这叫事件冒泡(event bubbling)

首先来看看事件捕获:

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2   /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

可以看出element1上的事件处理函数先触发,element2上的事件处理函数后触发。

那么事件冒泡又是怎样的呢:

                / 
 ---------------| |-----------------
 | element1     | |                |
 |   -----------| |-----------     |
 |   |element2  | |          |     |
 |   -------------------------     |
 |        Event BUBBLING           |
 -----------------------------------

这种情况下element2上面的事件处理函数先触发,element1上面的事件处理函数后触发。

对于这两种模型的截然不同,W3C很巧妙地在这场对抗中保持中立:任何W3C事件模型中发生的事件都是先捕获,直到它到达目标元素,然后再向外冒泡

                 | |  / 
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2     /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

基于事件模型可以有很多应用,最常见的就是事件代理和委托,感兴趣的可以深入研究,这里我不在具体描述。

普通事件与事件绑定

普通事件就是on+event绑定的事件,Javascript中有很多定义好的事件,例如 onclickonkeyuponmouseup 等,这种方式的使用示例如下:

javascriptobj1.onclick = function1;
obj1.onclick = function2;

以上的操作下,function1会被function2覆盖而只执行function2,解除事件只需:

javascriptobj1.onclick = null;

使用支持W3C标准的浏览器中绑定事件用的是addEventListener:

javascriptobj1.addEventListener("click",change1,false);
obj1.addEventListener("click",change2,false);

事件执行顺序跟绑定顺序一样,先执行change1,再执行change2,解除绑定:

javascriptobj1.removeEventListener("click",change1,false);

在IE里面,绑定事件要用attachEvent:

javascriptobj1.attachEvent("onclick",change1);
obj1.attachEvent("onclick",change2);

绑定时事件名称同样要以on为前缀,而且没有后面是否冒泡的boolean值,但是这种执行顺序变成了倒序,先执行change2,再执行change1。 事件取消绑定:

javascriptobj1.detachEvent("onclick",change1);
stopPropagation,preventDefault和return false

因为有父, 子节点同在, 因为有监听事件和浏览器默认动作之分. 使用 JavaScript 时为了达到预期效果经常需要阻止事件和动作执行. 一般我们会用到三种方法, 分别是 stopPropagation(), preventDefault()return false。那么他们有什么区别呢?

See the Pen stopPropagation,preventDefault和return false对比 by superlin (@superlin) on CodePen.

stopPropagation:因为事件可以在各层级的节点中传递, 不管是冒泡还是捕获, 有时我们希望事件在特定节点执行完之后不再传递, 可以使用事件对象的 stopPropagation 方法。

preventDefault:元素上带有的功能. 如: 点击 a 链接节点的跳转动作, 点击submit按钮表单会提交等,如果监听这些元素的事件时不希望默认动作方式,就可以使用 preventDefault 方法。

return false:退出执行, return false 之后的所有触发事件和动作都不会被执行. 有时候 return false 可以用来替代 stopPropagationpreventDefault,除此之外,还可以返回对象, 跳出循环等。

可以去上面的例子试试哦。

target与currentTarget

target在事件流的目标阶段;currentTarget在事件流的捕获,目标及冒泡阶段。只有当事件流处在目标阶段的时候,两个的指向才是一样的, 而当处于捕获和冒泡阶段的时候,target指向被单击的对象而currentTarget指向当前事件活动的对象(一般为父级),具体示例如下。

See the Pen target与currentTarget区别 by superlin (@superlin) on CodePen.

更多的例子和意见请给我留言。

欢迎光临小弟博客:Superlin"s Blog
我的博客原文:DOM中的各种区别小节

参考

Understanding offsetWidth, clientWidth, scrollWidth and -Height

Get document height

async vs defer attributes

JS普通添加事件和事件绑定

Event order

javascript的事件监听与捕获和冒泡

Bubbling and capturing

stopPropagation, preventDefault 和 return false 的区别

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91492.html

相关文章

  • JavaScript书籍测评

    摘要:前言今天和大家一起聊聊的推荐书籍,每一本都是精选,做前端开发的朋友们如果没读过,可以尝试一下。如果怕麻烦,也可以关注晓舟报告,发送获取书籍,四个字,就可以得到电子书的提取码。 前言 今天和大家一起聊聊JavaScript的推荐书籍,每一本都是精选,做前端开发的朋友们如果没读过,可以尝试一下。下面给大家简单介绍了书的内容,还有读书的方法,希望可以帮大家提升读书效率。 一、《JavaScr...

    X1nFLY 评论0 收藏0
  • 实战Vue简易项目(4)定义视图

    摘要:是中的条件指令,根据返回的布尔值动态添加或移除元素。传值方式我是标题需要在中定义函数传的值为字符串,不需要前缀传的值为非字符串数字布尔值函数数组对象,为前缀,值为表达式计算结果在程序中,如引用的值。为该组件内,元素绑定的事件处理函数。 视图 包含内容#NavigationBar、#TabBar、#MainContext; 为什么#NavigationBar、#TabBar分在Layou...

    LeoHsiun 评论0 收藏0
  • 从 0 到 1 实现 React 系列 —— 生命周期和 diff 算法

    摘要:本系列文章在实现一个的同时理顺框架的主干内容虚拟组件生命周期算法从到实现系列和从到实现系列组件和生命周期先来回顾的生命周期,用流程图表示如下该流程图比较清晰地呈现了的生命周期。它们的目的都是降低空间复杂度。 showImg(https://segmentfault.com/img/remote/1460000015785464?w=640&h=280); 本系列文章在实现一个 (x)r...

    mist14 评论0 收藏0
  • Vue.js新手入门指南[转载]

    摘要:就是一个用于搭建类似于网页版知乎这种表单项繁多,且内容需要根据用户的操作进行修改的网页版应用。单页应用程序顾名思义,单页应用一般指的就是一个页面就是应用,当然也可以是一个子应用,比如说知乎的一个页面就可以视为一个子应用。 最近在逛各大网站,论坛,以及像SegmentFault等编程问答社区,发现Vue.js异常火爆,重复性的提问和内容也很多,楼主自己也趁着这个大前端的热潮,着手学习了一...

    MartinHan 评论0 收藏0
  • XSS分析及预防

    摘要:分析及预防,又称跨站脚本,的重点不在于跨站点,而是在于脚本的执行。在这里需要强调一点的是,默认会禁止代码块的执行禁止内联事件处理函数禁止内联样式禁止和。 XSS分析及预防 XSS(Cross Site Scripting),又称跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行。在WEB前端应用日益发展的今天,XSS漏洞尤其容易被开发人员忽视,最终可能造成对个人信息的泄漏。如今,...

    smartlion 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<