DOM节点,事件高级

节点操作

获取元素有两种方式:

  1. 利用DOM提供的方法获取:逻辑性不强,繁琐
  2. 利用节点层级关系获取:逻辑性强但兼容性较差

节点概述

节点拥有:nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)三个基本属性。

  1. 元素节点,nodeType为1
  2. 属性节点,nodeType为2
  3. 文本节点,nodeType为3

节点层级

子节点
  1. parentNode.childNodes():返回指定节点的子节点的集合,包括元素节点,文本节点等;
  2. parentNode.children():是一个只读属性,返回所有的子元素节点;
  3. parentNode.firstChild():返回第一个子节点
  4. parentNode.lastChild():返回最后一个子节点
  5. parentNode.firstElementChild():返回第一个子元素节点
  6. parentNode.lastElementChild():返回最后一个子元素节点

(最后两个方法ie9以上才支持)因此在实际开发中为了获得第一个或最后一个子元素节点的写法是:

<ul>
        <li>li</li>
        <li>li</li>
        <li>li</li>
        <li>li</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        //获得第一个子元素节点
        console.log(ul.children[0]);
        //获得最后一个子元素节点
        console.log(ul.children[ul.children.length -1]);        
    </script>

兄弟节点
  1. nextSibling:下一个兄弟节点,包括元素节点文本节点等
  2. nextElementSibling:下一个兄弟元素节点
  3. previousSibling:上一个兄弟节点,包括元素节点文本节点等
  4. previousElementSibling:上一个兄弟元素节点

创建节点(元素)

  1. document.createElement(TagName)
  • 先创建节点,再将元素添加进去
  1. document.write()
  • 直接将内容写入页面的内容流,当文档流执行完毕,会导致页面全部重绘
  1. element.innerHTML
  • 将内容写入某个节点,不会导致页面重绘

innerHTML创建多个元素效率更高(不要凭借字符串,用字符串效率很低,采用数组形式拼接),结构比较复杂。

createElement()创建多个元素效率低于使用数组的innerHTML高于使用字符串的innerHTML,但结构更清晰。

//使用字符串的innerHTML
for (var i = 0; i <= 100; i++) {
    inner.innerHTML += '<a href="#">百度</a>'
 }
 
//使用数组的innerHTML
var arr = [];
for (var i = 0; i <= 100; i++) {
    arr.push('<a href="#">百度</a>');
}
    inner.innerHTML = arr.join('');
  
//使用createElement()
var create = document.querySelector('.create');
for (var i = 0; i <= 100; i++) {
     var a = document.createElement('a');
     create.appendChild(a);
}

添加节点

  • 在后面追加元素:document.appendChild(往里添加的节点)
  • 往前面添加:documnet.insertBefore(往里添加的节点,添加到哪个节点前)

删除节点

node.removeChild(child)

  1. node是要删除节点的父节点
  2. child是要删除的节点

克隆节点

node.cloneNode()括号里可选值true、flase或者空。

  1. 克隆节点跟添加节点一样,要先创建克隆节点再将节点插入
  2. 括号为空或者false为浅拷贝,只复制标签但不复制里面的内容
  3. 括号为true为深拷贝,赋值标签里的内容
<ul>
    <li>12</li>
    <li>123</li>
   </ul>
   <script>
    var ul = document.querySelector('ul');
    //首先克隆节点
    var cloneLi = ul.children[0].cloneNode(true);
    //再将克隆节点添加进去
    ul.appendChild(cloneLi);  
   </script>

事件

注册事件

  1. 传统注册事件方式
  • 以on开头的事件名,如onclick
  • 特点:注册事件的唯一性(同一个元素同一个事件只能设置一个处理函数,若设置多个后面的函数会覆盖前面的)
  1. 方法监听注册方式
  • 利用eventTarget.addEventListener(type,listener[,useCapture])
  • type:事件类型,如click、mouseover
  • listener:事件处理函数
  • useCapture:可选参数,boolean
  • 特点:同元素同事件可以注册多个监听器,按照注册的顺序依次执行
    attachEvent也是方法监听注册方式,用于较老的浏览器,不常用
<body>
    <button>传统方式注册事件</button>
    <button>方法监听注册事件</button>
    <script>
        var btns = document.querySelectorAll('button');
    //1.传统方式注册事件(结果:点击之后只能弹出‘点击了传统2’)
        btns[0].onclick = function(){
            alert('点击了传统哦1');
        }
        btns[0].onclick = function(){
            alert('点击了传统哦2');
        }
   //2.方法监听注册事件(结果:点击之后依次弹出两个alert)
        btns[1].addEventListener('click',function(){
            alert('点击了方法监听哦1');
        })
        btns[1].addEventListener('click',function(){
            alert('点击了方法监听哦2');
        })
    </script>
</body>

删除事件

  1. 传统注册方式
  • eventTarget.onclick = null
  1. 方法监听注册方式
  • eventTarget.removeEventListener = (type,listener[,useCapture]);
    eventTarget.detachEvent()也是删除方法监听注册方式,用于较老的浏览器,不常用
<body>
    <div>a</div>
    <div>b</div>
    <div>c</div>
    <script>
       var divs = document.querySelectorAll('div');
       //传统方式
       divs[0].onclick = function(){
        alert('点击了一次1');
        this.onclick = null;
       }
       //利用removeEventListener方法
       divs[1].addEventListener('click',fn);
       function fn(){
        alert('点击了一次2');
        divs[1].removeEventListener('click',fn);
       };
    </script>
</body>

事件流三个阶段

事件流描述的是从页面中接收事件的顺序。

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。

事件流分为三个阶段:

  1. 捕获阶段,事件捕获:由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接受的过程
  2. 当前目标阶段
  3. 冒泡阶段,事件冒泡:由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程

事件流的一些注意点:

  1. JS代码中只能执行捕获或者冒泡其中的一个阶段
  2. onclick和attachEvent只能得到冒泡阶段
  3. addEventListener(type,listener【,useCapture】)
  • 第三个参数如果为true,表示在事件捕获阶段调用事件处理程序
  • 若为空或false,表示在事件冒泡阶段调用事件处理程序

4.一些事件没有冒泡,如:onblur、onfocus、onmouseover、onmouseleave

<body>
   <div class="father">
    <div class="son"></div>
   </div>
   <script>
    var father = document.querySelector('.father');
    var son = document.querySelector('.son');
    //结果:点击son:先document、再son,最后father,因为document为捕获阶段,向下到father,发现father
    //是冒泡阶段则继续向下到最具体的son,son执行冒泡阶段,弹出son,再弹出father
    father.addEventListener('click',function(){
        alert('father');
    },);
    son.addEventListener('click',function(){
        alert('son');
    },);
    document.addEventListener('click',function(){
        alert('document');

    },true);
   </script>

</body>

事件对象

eventTarget.onclick = function(event){}
eventTarget.addEventListener('click',function(event){})

这里的event就是事件对象,事件发生后跟事件相关的一系列信息都存储在这个对象里。

  • event是个形参,系统会帮助设定为事件对象,并不需要传递实参
  • 当注册事件时,event对象会被系统自动创建,并以此传递给些事件监听器
常见事件对象的属性和方法
  1. e.target返回触发事件的元素
  • 注意:e.target是触发了哪个元素(点击等)就返回哪个元素,this返回的是绑定时间的元素
<body>
    <ul>
        <li>12</li>
        <li>123</li>
    </ul>
    <script>
       var ul = document.querySelector('ul');
       ul.addEventListener('click',function(e){
        //点击12(li)后返回li
        console.log(e.target);
        //返回ul
        console.log(this);
       })
    </script>
</body>
  1. e.type返回事件类型,返回mouseover、click等
  2. e.preventDefault()阻止默认行为:让链接不跳转或让提交按钮不提交
 <body>
    <a href="https://juejin.cn/">掘金</a>
    <script>
    //阻止之后页面无法跳转
        var a = document.querySelector('a');
        a.addEventListener('click',function(e){
            e.preventDefault();
        })
        
     //如果是传统的注册方式
          a.onclick = function(e) {
            // 可以用e.preventDefault()
            // 也可以用return false 阻止默认行为 没有兼容性问题 特点: return 后面的代码不执行了, 而且只限于传统的注册方式
            return false;
            alert(11);
        }
    </script>
  </body>
  1. 阻止事件冒泡
  • 标准写法:e.stopPropagation()
  • 非标准写法:ie6~8,利用事件对象昂的cancelBubble属性
  1. 常见鼠标事件
  • 禁止鼠标右键菜单
  • 禁止选中文字
<body>
    <div>1234</div>
    <script>
    //禁止鼠标右键
        document.addEventListener('contextmenu',function(e){
            e.preventDefault();
        })
     //禁止选中文字
        document.addEventListener('selectstart',function(e){
            e.preventDefault();
        })
 </script>
  </body>
  • 鼠标事件对象:client(鼠标在可视区的x,y坐标),page(鼠标在页面文档的x,y坐标),screen(鼠标在电脑屏幕的x,y坐标)
  1. 常见键盘事件
  • keyup(按键弹起时触发,不区分字母大小写,默认为大写)
  • keydown(按键按下时触发,可以识别功能键,不区分字母大小写,默认为大写)
  • keypress(按键按下时触发,不能识别功能键,区分字母大小写)

注意keyup是键盘操作完松开之后再执行事件,keydown相反

  • 三个事件的执行顺序:keydown-keypress-keyup
  • 键盘事件对象:keyCode可以得到相应键的ASCII码值

事件委托

事件委托的核心:给父节点添加监听器,利用冒泡影响每一个子节点。

<body>
    <ul>
        <li>你好我好大家好</li>
        <li>你好我好大家好</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        ul.addEventListener('click',function(e){
            //点击li后,利用冒泡使得绑定在父元素(ul)上的监听器响应
            //这样就不用每个li都注册
            e.target.style.color = 'red';
        })
    </script>
  </body>

练习

练习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值