5.3 DOM 相关

  1. document.getElementById('a') 通过 id 值为 a 获取页面中的一个元素

  2. document.getElementsByName('na') 通过 name 属性值为 na 获取页面中的一个元素

  3. document.getElementsByTagName('div') 通过标签名获取所有 div

  4. 以上说法都不对

关于获取页面元素,以上说法正确的是

答案:1 和 3

  1. document.getElementById()

  2. document.getElementsByClassName()

  3. document.getElementsByName() 给出的 attribute name

  4. document.getElementsByTagName()

  5. document.getElementsByTagNameNS()

事件流

HTML 与 JavaScript 交互是通过“事件驱动”来实现的,比如鼠标点击事件 onclick、页面的滚动事件 onscroll。我们可以向文档或文档中的元素,添加事件侦听器来监听特定的事件。

“事件流”描述的是,从页面中接收事件的顺序。DOM2 级事件流包括下面几个阶段:

  1. 事件捕获阶段

  2. 处于目标阶段

  3. 事件冒泡阶段

addEventListener 是 DOM2 级事件新增的指定事件处理程序的操作,该方法接收三个参数:

  1. 要处理的事件名

  2. 作为事件处理程序的函数

  3. 一个布尔值

    • true 表示是在捕获阶段调用事件处理程序

    • false 表示在冒泡阶段调用事件处理程序

IE 只支持事件冒泡。

事件代理在捕获阶段的实际应用:

  • 在父元素层面阻止事件向子元素传播

  • 代替子元素执行某些操作

如何让事件先冒泡后捕获?

在 DOM 标准事件模型中,是先捕获后冒泡。

但是如果要实现先冒泡后捕获的效果,对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后再执行捕获之间。

事件委托(事件代理)

事件委托本质上是利用了浏览器的事件冒泡的机制。

事件通过冒泡传到父节点,然后父节点通过事件对象来获取目标节点。这样就可以由父节点的监听函数统一处理多个子元素的事件,这种方式也叫事件代理。

好处:

  • 不需要给每一个元素都绑定一个监听事件,从而减少了内存上的消耗

  • 还可以实现事件的动态绑定,比如新增了子节点

事件冒泡,就是元素自身的事件被触发后,如果父元素有相同的事件,如 onclick 事件, 那么元素本身的触发状态就会传递——冒到父元素,父元素的相同事件也会一级一 级根据嵌套关系向外触发,直到 document/window,冒泡过程结束。

addEventListener 参数
addEventListener(type, listener)
addEventListener(type, listener, options)
addEventListener(type, listener, useCapture)
  1. event 事件名

  2. function 事件触发时执行的函数

  3. useCapture 布尔值,默认是 false,表示事件是捕获还是冒泡

    • 在冒泡中,内部元素先被触发,然后再触发外部元素

    • 捕获中,外部元素先被触发,在触发内部元素

节流和防抖
requestAnimationFrame
mouseover 和 mouseenter 的区别
  • mouseover:当鼠标移入元素或其子元素都会触发事件,所以有一个重复触发,冒泡的过程。对应的移除事件是 mouseout

  • mouseenter:当鼠标移出元素本身(不包含元素的子元素)会触发事件,也就是不会冒泡。对应的移除事件是 mouseleav

各种位置
  1. clientHeight:表示的是可视区域的高度,不包含 border 和滚动条

  2. offsetHeight:表示可视区域的高度,包含了 border 和滚动条

  3. scrollHeight:表示了所有区域的高度,包含了因为滚动被隐藏的部分

  4. clientTop:表示边框 border 的厚度,在未指定的情况下一般为 0

  5. scrollTop:滚动后被隐藏的高度,获取对象相对于由 offsetParent 属性指定的父坐标(css 定位的元素或 body 元素)距离顶端的高度

  6. offsetTop

移动端 click 的 300ms 延迟

click 在 ios 上有 300ms 延迟,原因及如何解决?

(1)粗暴型,禁用缩放

<meta name="viewport" content="width=device-width, user-scalable=no">

(2)利用 FastClick,原理是:检测到 touchend 事件后,立刻触发模拟 click 事件,并且把浏览器 300 毫秒之后真正触发的事件给阻断掉

加载图片
<div id="mypic">onloading......</div>
<script type="text/javascript">
    var obj=new Image();
    obj.src = "xxx.jpg";

    function show(){
        alert('图片的宽度为:'+obj.width+';图片的高度为:'+obj.height)
        document.getElementById("mypic").innnerHTML="<img src='"+this.src+"' />"
    }

    // 方法一
    obj.onload = function(){ 
        show()
    }
    // 方法二
    obj.onreadystatechange=function(){
        if(this.readyState=="complete"){
            show()
        }
    }
</script>
HTML5 drag API
  1. dragstart

  2. darg

  3. dragenter

  4. dragover

  5. dragleave

  6. drop

  7. dragend

实现拖拽

首先是三个事件,分别是 mousedown,mousemove,mouseup。

当点击鼠标时,需要一个 tag 标识此时已经按下,可以执行 mousemove 里面的具体方法。

clientX,clientY 标识的是鼠标的坐标,分别标识横坐标和纵坐标。用 offsetX 和 offsetY 来表示元素的初始坐标。

  • 移动的距离=鼠标移动时候的坐标-鼠标按下去时候的坐标

  • 定位信息 = 鼠标移动时候的坐标-鼠标按下去时候的坐标+元素初始情况下的 offetLeft

还有一点也是原理性的东西,也就是拖拽的同时是绝对定位,我们改变的是绝对定位条件下的 left 以及 top 等值。

补充:也可以通过 HTML5 的拖放(Drag 和 drop)来实现

virtual dom

详见 vue

Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。

Last updated