js总结(三)—DOM

277 阅读3分钟

事件绑定

  1. 利用on开头的时间 如onclick等

  2. addEventListener

  3. 两者区别:同一个元素同一个事件,设置多个函数,以on开头的后面的会把前面的覆盖掉,addEventListener不会

    
    html
    <button>传统注册事件</button>
     <button>方法监听注册事件</button>
        <script>
            var btns = document.querySelectorAll('button');
            btns[0].onclick = function () {
                alert('hh')
            }
            btns[0].onclick = function () {
                alert('enen')
            } //弹出 'enen'
            btns[1].addEventListener('click', function () {
                console.log(1);
            })
            btns[1].addEventListener('click', function () {
                console.log(2);
            })//分别弹出1 2
    

删除事件

  • 传统将事件赋值为null

  • removeEventListener ,这里的函数要是具名函数

     <div>1</div>
     <div>2</div>
     <div>3</div>
     //只打印一次
            var divs = document.querySelectorAll('div');
            divs[0].onclick = function () {
                console.log(1);
                divs[0].onclick = null;
            }
            divs[1].addEventListener('click', fn)
            function fn() {
                console.log(22);
                divs[1].removeEventListener('click', fn)
            }
    

DOM事件流

​ 事件的传播分为三个阶段

  • 捕获阶段
  • 当前目标阶段
  • 冒泡阶段

先来一张图 捕获阶段

 <div class="father">
        father
        <div class="son">son</div>
    </div>
    <script>
        var son = document.querySelector('.son');
        var father = document.querySelector('.father');
        son.addEventListener('click', function () {
            console.log(11)
        }, true)
        father.addEventListener('click', function () {
            console.log(22)
        }, true)
 // 先输出22 在输出11
 </script>

捕获阶段的原理:事件按照 document html body father son传播 ,当son点击时,从document开始捕获 ,father 有点击事件则触发 ,输出了22 ,然后son有点击事件输出了 11

  • js 中只能执行捕获或者冒泡其中的一个阶段

  • onclick 只到冒泡阶段

  • addEventListener的第三个参数为true表示在捕获阶段触发该程序,默认是false,

    表示只能在冒泡阶段调用该程序

  • 有些事件没有冒泡,如onblur , onfocus, onmouseenter, onmouseleave

事件对象 event

事件方法 说明
e.target 返回触发事件的对象
e.type 返回事件的类型,比如click mouseover
e.preventDefault( ) 阻止默认行为 ,比如不让链接跳转
e.stopPropagation 阻止冒泡

事件委托

假如有如下场景:

<ul>
	<li>改革春风吹满地</li>
	<li>改革春风吹满地</li>
	<li>改革春风吹满地</li>
	<li>改革春风吹满地</li>
	<li>改革春风吹满地</li>
</ul>

要求点击每个li都会弹出对话框,

 //传统做法是这样的
var lis = document.querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            lis[i].onclick = function () {
                alert('hhh')
            }
        }

事件委托的原理:不是每个子节点单独设置事件监听器, 将事件监听器设置在父节点上,利用冒泡的原理 ,每个子节点发生行为的时候,就会触发父节点相应行为

var ul = document.querySelector('ul');
        ul.addEventListener('click', function (e) {
            e.target.style.backgroundColor = 'pink'
        })

动画函数封装

原理 :通过定时器 setInterval 不断移动盒子位置

步骤:

  1. 获得盒子当前位置
  2. 让盒子在当前位置加上一个移动距离
  3. 使用定时器不断重复这个动作
  4. 加一个定时器结束的条件
  5. 注意此元素要添加定位,才能使用element.style.left

缓慢动画

让盒子每次移动的距离减小

思路:(目标值 - 现在的位置)/10

停止的条件是: 让当前盒子位置等于目标位置就停止定时器

加个回调函数 : 盒子停止运动的时候,执行回调函数

   function  animate(obj, target, callback) {
            clearInterval(obj.time)
            obj.time = setInterval(function () {
                if (obj.offsetLeft == target) {
                    clearInterval(obj.time)
                    // if (callback) {
                    //     callback()
                    // }
                    callback && callback();
                }
                var step = (target - obj.offsetLeft) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step)
                obj.style.left = obj.offsetLeft + step + 'px'
            }, 30)
        }