DOM学习笔记

目录

定义

一、获取元素

1、根据ID获取        

2、根据标签名获取       

3、H5新增方法获取——均是以伪数组的形式返回

(1)根据类名获取某些元素的集合       

(2)返回指定选择器的第一个元素对象       

(3)返回指定选择器的所有元素对象集合        

4、获取某些特殊元素(body、html)

二、事件

1、定义

2、事件三要素

三、操作元素

1、改变元素内容

2、改变元素属性

(1)获取属性值

(2)改变元素属性值

(3)移除元素属性值

3、改变表单元素

4、修改样式属性

5、排他思想:首先先排除其他人 然后再设置自己的样式

6、H5新增的自定义属性

(1)设置H5自定义属性

(2)获取H5自定义属性

四、节点操作

1、父级节点 

2、子节点

3、兄弟节点

4、创建节点

5、添加节点

6、删除节点

7、复制节点(克隆节点)

8、三种动态创建元素的区别

五、事件操作

1、注册事件(绑定事件):给元素添加事件

(1)传统注册方式

(2)方法监听注册方式

2.删除事件

(1)传统删除方式

(2)方法监听删除方式

六、DOM事件流

1、e.target 与 this 的区别

2、返回事件类型

3、阻止默认行为(事件) 让链接不跳转

4、阻止事件冒泡的两种方式

 5、事件委托(代理、委派)

6、常用鼠标事件

(1)禁止鼠标右键菜单 contextmenu

(2)禁止鼠标选中文字(selectstart 开始选中)

(3)鼠标事件MouseEvent

(4)键盘事件KeyboardEvent


定义

        DOM(文档对象模型):是W3C推荐的处理可拓展性标记语言(HTML/XML)的标准编程接口。

DOM树

文档(document):一个页面就是一个文档。

元素(element):页面中所有标签都是元素。

节点(node):网页中所有内容都是节点(标签、文本、属性、注释等)

一、获取元素

1、根据ID获取        

document.getElementById('参数')         

2、根据标签名获取       

document.getElementsByTagName()         

  • 返回的是获取过来的元素对象的集合 以伪数值的形式存储
  • 若页面中没有这个元素 返回一个空的伪数组

拓展:获取某个元素(父元素)内部指定标签名的子元素

element.getElementsByTagName('标签名')

  • 父元素必须是单个对象 不能是数组等 获取时不包括父元素自己

3、H5新增方法获取——均是以伪数组的形式返回

(1)根据类名获取某些元素的集合       

document.getElementsByClassName()

(2)返回指定选择器的第一个元素对象       

document.querySelector('选择器')   

         里面的选择器要加符号:eg标签名——'div',类名——'.box',ID名——'#nav'

(3)返回指定选择器的所有元素对象集合        

document.querySelectorAll()

4、获取某些特殊元素(body、html)

(1)document.body        返回body元素对象

(2)document.documentElement       返回html元素对象

二、事件

1、定义

        可以被JavaScript侦测到的行为        触发——响应机制

2、事件三要素

        事件源 事件类型 事件处理程序

<body>
    <!-- 获取事件源 -->
    <button id="btn">唐伯虎</button>
    <script>
        // 注册事件 事件类型 鼠标点击onclick 
        var btn = document.getElementById('btn');
        // 事件处理程序 通过一个函数赋值的方式
        btn.onclick = function(){
            alert('点秋香');
        }
    </script>
</body>

三、操作元素

1、改变元素内容

(1)element.innerText       

  • 不识别html标签 非标准       
  • 去除空格和换行

(2)element.innerHtml       

  • 识别html标签 W3C标准       
  • 保留空格和换行

2、改变元素属性

(1)获取属性值

element.属性 

element.getAttribute('属性');

区别:

  • element.属性 获取内置属性值(元素本身自带的属性)
  • element.getAttribute('属性'); 主要获得自定义的属性(标准)我们程序员自定义的属性

(2)改变元素属性值

element.属性='值'

element.setAttribute('属性','值'); 主要针对于自定义属性

(3)移除元素属性值

removeAttribute(属性)

<body>
    <div id="demo" index="1" class="nav"></div>
    <script>
    // 1.获取元素的属性值
    // (1)element.属性
    console.log(div.id);    //demo
    // (2)element.getAttribute('属性') get获取 attribute 属性 
    // 自定义属性:程序员自己添加的属性
    console.log(element.getAttribute('id'));    //demo
    console.log(element.getAttribute('index')); //1
    //2.设置元素属性值
    // (1)element.属性='值'
    div.id = 'test';
    div.className = 'nnnavs';
    // (2)element.setAttribute('属性','值'); 主要针对于自定义属性
    div.setAttribute('index',2);
    div.setAttribute('class','special');    //class比较特殊 这里就是使用class 而不是className
    // (3)移除属性 removeAttribute(属性)
    div.removeAttribute('index');
    </script>
</body>

案例:点击切换照片

    <script>
        //先获取元素
        var box = document.getElementById('box');
        var img = document.querySelector('img');
        //注册事件 处理程序
        box.onclick = function(){
            //点击的时候更换照片以及照片的title
            img.src='images/xxx.jpg';
            img.title='我是新的照片';
        }
    </script>

3、改变表单元素

利用DOM可以操作表单元素属性:type、value、checked、selected、disabled

注意:表单里面的值 文字内容是通过value来修改的

input.value = '我被修改了';
//如果想要某个表单被禁用 不用再被点击 disabled
input.disabled = true;

4、修改样式属性

(1)element.style       

  • 行内样式操作 产生的是行内样式 权重比css高       
  • 采用驼峰命名法
//将背景颜色改成紫色
属性名.style.backgroundColor = 'purple';

(2)element.className       

  • 类名样式操作 会覆盖原先的类名       
  • 适用于样式修改较多的情况
</head>
     <style>
    .change {
        color:rgb(161, 66, 66);
        font-size:25px;
    }
    </style>
</head>

<body>
    <div>文本</div>
    <!-- //多样式情况 -->
    <!-- <div class="first">文本</div> -->

    <script>    
        var text = document.querySelector('div');
        text.onclick = function(){
            text.className = 'change';
            // text.className = 'first change';
        }
    </script>
<body>

5、排他思想:首先先排除其他人 然后再设置自己的样式

        如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他思想

(1)所有元素全部清除样式(干掉其他人)

(2)给当前元素设置样式(留下我自己)

(3)注意顺序不能颠倒,首先干掉其他人,再设置自己

<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>
    
    <script>
    //1、获取所有按钮元素
    var btns = document.getElementsByTagName('button');
    //btns得到的是伪数组 里面的每一个元素 btns[i]
    for(var i=0; i<btns.length; i++){
        btns[i].onclick = function(){
        //将所有的按钮的背景颜色都去掉
        for(var i=0; i<btns.length; i++){
             btns[i].style.backgroundColor = '';
        }  
        //2.再让当前元素背景颜色为pink
        btn[i].style.backgroundColor = 'pink';
        }
    }

</script>
</body>

6、H5新增的自定义属性

自定义属性目的:是为了保存并使用数据,有些数据可以保存到页面中而不用保存在数据库中。

(1)设置H5自定义属性

        为了更容易判断元素的内置属性和自定义属性。H5规定自定义属性以 data- 开头作为属性名并且赋值。

        比如:<div data-index = '1></div> 或者使用JS设置 element.setAttribute('data-index',2);

(2)获取H5自定义属性

兼容性获取        

element.getAttribute('data-index');

H5新增        

element.dataset.index

element.dataset['index']       

  • ie 11 才支持
  • 如果自定义属性里面有多个-链接的单词 获取时采用驼峰命名法
  • dataset 是一个集合 里面存放了所有以data开头的自定义属性
<body>
    <div getTime="20" data-index="'2" data-list-name="andy"></div>
    <script>
        var div = document.querySelector('div');
        // 兼容性获取属性值的方法
        div.getAttribute('getTime');
        div.getAttribute('data-index');
        div.getAttribute('data-list-name');
        // H5新增的获取自定义属性值的方法  只能获取data-开头的自定义属性
        div.dataset.index;
        div.dataset['index'];
        // 如果自定义属性里面有多个-链接的单词 获取时采用驼峰命名法
        div.dataset.listName;
        div.dataset['listName'];
    </script>
</body>

四、节点操作

         一般的,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

  • 元素节点 nodeType 为 1 (主要操作)
  • 属性节点 nodeType 为 2
  • 文本节点 nodeType 为 3(文本节点包括文字、空行、换行等)

1、父级节点 

node.parentNode

  • parentNode 属性可返回某节点的父节点(最近的的一个父节点)
  • 如果指定的节点没有父节点则返回null
<body>
    <div class="demo">
        <div class="box">
            <span class="erweima">x</span>
        </div>
    </div>
    <script>
        // 1.父节点 parentNode
        var erweima = document.querySelector('.erweima');
        // 得到的是离元素最近的父级节点
        console.log(erweima.parentNode);//返回为box
    </script>
</body>

2、子节点

parentNode.childNodes(标准) 

  • 返回包含指定节点的子节点的集合(实时更新)
  • 注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等,如果只想要获得里面的元素节点,则需要专门处理。所以我们一般不提倡使用childNodes

parentNode.children(非标准)         重点掌握

  • 它是一个只读属性 只返回所有的元素节点 其余节点不返回 实际开发常用
<body>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');
        // 1.子节点 childNodes 所有的子节点 包含元素节点 文本节点等等
        console.log(ul.childNodes); // 集合有9个值
        console.log(ul.chileNodes[0].nodeType); //3
        console.log(ul.chileNodes[1].nodeType); //1
        // 获得里面的元素节点
        for(var i = 0; i<ul.childNodes.length; i++){
            if(ul.childNodes[i].nodeType == 1) {
                console.log(ul.childNodes[i]);
            }
        }

        // 2.children 获取所有的子元素节点 实际开发常用
        console.log(ul.children);
    </script>
</body>

parentNodes.firstChild

  • 返回第一个子元素节点 找不到返回null
  • 包含所有的节点

parentNodes.lastChild

  • 返回第一个子元素节点 找不到返回null
  • 包含所有的节点

parentNodes.firstElementChild

  • 返回第一个子元素节点 找不到返回null
  • 存在兼容性问题 IE9以上才支持

parentNodes.lastElementChild

  • 返回最后一个子元素节点 找不到返回null
  • 存在兼容性问题 IE9以上才支持

实际开发的写法 既没有兼容性问题又返回相应的指定的子元素

parent.children[parent.children.length - 1]

<body>
    <ol>
        <li>我是li1</li>
        <li>我是li2</li>
        <li>我是li3</li>
        <li>我是li4</li>
    </ol>
    <script>
        var ol = document.querySelector('ol');
        // 1.firstChild 第一个子节点 不管是文本节点还是元素节点
        console.log(ol.firstChild); //#text
        console.log(ol.lastChild);  //#text
        // 2.firstElementChild 返回第一个子元素节点
        console.log(ol.firstElementChild);  //<li>我是li1</li>
        console.log(ol.lastElementChild);  //<li>我是li4</li>
    </script>
</body>

案例:下拉菜单

案例分析:        

  • 导航栏里面的li都要有鼠标经过效果 所以需要循环注册鼠标事件
  • 核心原理:当鼠标经过li里面的第二个孩子ul显示 当鼠标离开 ul隐藏
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        li {
            list-style: none;
        }

        a {
            color: #333;
            text-decoration: none;
        }

        .nav {
            margin: 100px;
        }

        .nav>li{
            position: relative;
            float: left;
            width: 80px;
            height: 41px;
            text-align: center;
        }

        .nav li a {
            display: block;
            width: 100%;
            height: 100%;
            line-height: 41px;
        }

        .nav>li>a:hover {
            background-color: #eee;
        }

        .nav ul {
            display: none;
            position: absolute;
            top: 41px;
            left: 0;
            width: 100%;
            border-left: 1px solid #fecc5b;
            border-right: 1px solid #fecc5b;
        }

        .nav ul li {
            border-bottom: 1px solid #fecc5b;
        }

        .nav ul li a:hover {
            background-color: #fff5da;
        }
    </style>
</head>
<body>
    <ul class="nav">
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href="#">私信</a></li>
                <li><a href="#">评论</a></li>
                <li><a href="#">@我</a></li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href="#">私信</a></li>
                <li><a href="#">评论</a></li>
                <li><a href="#">@我</a></li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href="#">私信</a></li>
                <li><a href="#">评论</a></li>
                <li><a href="#">@我</a></li>
            </ul>
        </li>
    </ul>
    <script>
        //获取元素
        var nav = document.querySelector('.nav');
        var lis = nav.children;    //得到4个小li    
        //循环注册事件
        for(var i = 0; i<lis.length; i++){
            lis[i].onmouseover = function() {
                this.children[1].style.display = 'block';
            }
            lis[i].onmouseout = function() {
                this.children[1].style.display = 'none';
            }
        }
    </script>
</body>

3、兄弟节点

node.nextSibling

  • 返回当前元素的下一个兄弟节点 找不到返回null
  • 包含所有的元素节点(文本节点  元素节点等)

node.previousSibling

  • 返回当前元素的上一个兄弟节点 找不到返回null
  • 包含所有的元素节点(文本节点  元素节点等)

node.nextElementSibling

  • 返回当前元素的下一个兄弟元素节点 找不到返回null
  • 存在兼容性问题 IE9以上才支持

node.previousElementSibling

  • 返回当前元素的上一个兄弟元素节点 找不到返回null
  • 存在兼容性问题 IE9以上才支持
<body>
    <div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');
        // 1.nextSibling 得到下一个兄弟节点 包含元素节点 文本节点等
        console.log(div.nextSibling);   //#text
        // 2.previousSibling 得到上一个兄弟节点 包含元素节点 文本节点等
        console.log(div.previousSibling);   //#text
        // 3.nextElementSibling 得到下一个兄弟元素节点 
        console.log(div.nextElementSibling);    //<span>我是span</span>
        // 4.previousElementSibling 得到上一个兄弟元素节点
        console.log(div.previousElementSibling);    //null
    </script>
</body>

解决兼容性以及只获取元素节点的方法——封装一个兼容性函数

        function getNextElementSibling(element) {
            var el = element;
            while(el = el.nextSibling) {
                if(el.nodeType === 1) {
                    return el;
                }
            }
            return null;
        }

4、创建节点

document.createElement(‘tagName’);      

  • 动态创建元素节点

5、添加节点

node.appendChild(child);     

  • 将一个节点添加到指定父节点的子节点列表末尾  类似于css里面的after伪元素

node.insertBefore(child,指定元素)

  • 将一个节点添加到指定父节点的指定节点前面  类似于css里面的before伪元素
<body>
    <ul>
        <li>123</li>
    </ul>
    <script>
        // 1.创建节点元素节点
        var li = document.createElement('li');
        // 2.添加节点 node.appendChild(child) node 父级 child 子级 后面追加元素 类似于数组的push
        var ul = document.querySelector('ul');
        ul.appendChild(li);
        // 3.添加节点 node.insertBefore(child,指定元素);
        var lili = document.createElement('li');
        ul.insertBefore(lili,ul.children[0]);
        //4.我们想要添加一个新的元素:(1)创建元素 (2)添加元素
    </script>
</body>

6、删除节点

node.removeChild(child)

  • 从DOM中删除一个子节点 返回删除的节点
<body>
    <button>删除</button>
    <ul>
      <li>光头强</li>
      <li>熊大</li>
      <li>熊二</li>
    </ul>
    <script>
      // 1.获取元素
      var btn = document.querySelector("button");
      var ul = document.querySelector("ul");
      // 2.注册事件 点击按钮依次删除里面的孩子
      btn.onclick = function () {
        if (ul.children.length == 0) {
          this.disabled = true;
        } else {
          // 删除元素 node.children(child)
          ul.removeChild(ul.children[0]);
        }
      }
    </script>
  </body>

案例

简单版发布留言

  • 核心思路:点击按钮之后,就动态创建一个li, 添加到ul里面
  • 创建li的同时,把文本域里面的值通过li.innerHTML赋值给li
  • 如果想要新的留言后面显示就用appendChild
  • 如果想要新的留言前面显示就用insertBefore

删除留言

  • 当我们把文本域里面的值赋值给li的时候,多添加一个删除的链接
  • 需要把所有的链接获取过来,当我们点击当前的链接的时候,删除当前链接所在的li
  • 阻止链接跳转需要添加JavaScript:void(0);或者 javascript:;
 <head>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      body {
        padding: 100px;
      }

      textarea {
        width: 200px;
        height: 100px;
        border: 1px solid pink;
        outline: none;
        resize: none;
      }

      ul {
        margin-top: 50px;
      }

      li {
        width: 300px;
        padding: 5px;
        background-color: pink;
        color: red;
        font-size: 14px;
        margin: 15px 0;
      }

      li a {
        float: right;
      }
    </style>
  </head>
  <body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul></ul>
    <script>
      //1.获取元素
      var text = document.querySelector("textarea");
      var ul = document.querySelector("ul");
      var btn = document.querySelector("button");
      // 2.注册事件
      btn.onclick = function () {
        if (text.value == "") {
          alert("请输入内容");
          return false;
        } else {
          // (1)创建元素
          var li = document.createElement("li");
          li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
          // (2)添加元素
          // ul.appendChild(li); 在后面添加
          ul.insertBefore(li, ul.children[0]); //在前面添加
          // (3)删除元素 删除的是当前链接的li 它的父亲
          var as = document.querySelectorAll("a");
          for (var i = 0; i < as.length; i++) {
            as[i].onclick = function () {
              //node.removeChild(child); 删除的是 li 当前a所在的li  this.parentNode;
              ul.removeChild(this.parentNode);
            }
          }
        }
      }
    </script>
  </body>
</html>

7、复制节点(克隆节点)

node.cloneNode()

  • 返回调用该方法的节点的一个副本
  • 如果括号参数为空或者为false,则是浅拷贝 即只复制标签,不复制里面的内容
  • 如果括号参数为true,则是深拷贝 复制标签和里面的内容
<body>
    <ul>
        <li>111</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        // 复制节点 node.cloneNode()
        var lili = ul.children[0].cloneNode(true);
        ul.appendChild(lili);
    </script>
</body>

8、三种动态创建元素的区别

  • document.write()
  • element.innerHTML
  • document.createElement()

区别:

  • document.write 是直接将内容写到页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
  • innerHTML 是将内容写到某个DOM节点,不会导致页面全部重绘
  • innerHTML创建多个元素效率更高(采用数组形式拼接,不要采用字符串拼接),但是结构稍微复杂
  • createElement()创建多个元素效率稍低一点点,但是结构更清晰

总结:不同浏览器下,innerHTML采取数值形式拼接时,效率要比createElement高

五、事件操作

1、注册事件(绑定事件):给元素添加事件

(1)传统注册方式

  • 利用on开头的事件onclick
  • <button onclick = "alert(hi~)" ></button>
  • btn.onclick = function() {}

特点:

        注册事件的唯一性。同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。

(2)方法监听注册方式

  • w3c标准 推荐方式
  • addEventListener() 它是一个方法
  • IE9之前的IE 不支持此方法 可使用 attachEvent()代替

特点:

        同一个元素同一个事件可以注册多个监听器,会按照注册顺序依次执行

eventTarget.addEventListener(type,listener[, useCapture])

eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。

该方法接收三个参数:

  • type:事件类型字符串,比如click、mouseover,注意这里不要带on
  • listener:事件处理函数,事件发生时,会调用该监听函数
  • useCapture:可选参数,是一个布尔值,默认是false
  <body>
    <button>传统方式注册事件</button>
    <button>事件侦听注册事件</button>
    <script>
      var btns = document.querySelectorAll("button");
      // 1.传统方式注册事件
      btns[0].onclick = function () {
        alert("hi~");
      };
      // 2.事件侦听注册事件 addEventListener
      // (1)里面的时间类型是字符串 必定加引号 而且不带on
      // (2)同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
      btns[1].addEventListener("click", function () {
        alert("hello1111");
      });
      btns[1].addEventListener("click", function () {
        alert("hello2222");
      });
    </script>
  </body>

注册事件兼容性解决方案


   <script>
      function addEventListener(element, eventName, fn) {
        //   判断当前浏览器是否支持addEventListener方法
        if (element.addEventListener) {
          element.addEventListener(eventName, fn); //第三个参数 默认是false
        } else if (element.attachEvent) {
          element.attachEvent("on" + eventName, fn);
        } else {
          // 相当于 element.onclick = fn
          element["on" + eventName] = fn;
        }
      }
    </script>

兼容性处理的原则:首先照顾大多数浏览器,再处理特殊浏览器

2.删除事件

(1)传统删除方式

eventTarget.onclick = null;

(2)方法监听删除方式

eventTarget.removeEventListener(type, listener[, useCapture]);

eventTarget.detachEvent(eventNameWithOn, callback);

删除事件兼容性解决方案

function removeEventListener(element, eventName, fn) {
        //   判断当前浏览器是否支持removeEventListener方法
        if (element.removeEventListener) {
          element.removeEventListener(eventName, fn); //第三个参数 默认是false
        } else if (element.detachEvent) {
          element.detachEvent("on" + eventName, fn);
        } else {
          element["on" + eventName] = null;
        }
      }

六、DOM事件流

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

DOM事件流:事件发生时会给元素节点之间按照特定是顺序传播 这个传播过程即DOM事件流

三个阶段:

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

注意:

  • JS代码中只能执行捕获或者冒泡其中的一个阶段
  • onclick 和 attachEvent 只能得到冒泡阶段
  • addEventListener(type, listener[, useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认false),表示在事件冒泡阶段调用事件处理程序
  • 实际开发中我们很少使用事件捕获,更关注事件冒泡
  • 有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave

事件对象

官方解释:event对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。

简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象,它有很多属性和方法。

使用语法:

        这个event是形参,系统帮我们设定为事件对象,不需要传递实参过去

        当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)

eventTarget.onclick = function(event){}

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

//这个event就是事件对象 还喜欢写成evt e

比如:

  • 谁绑定了这个事件。
  • 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置
  • 键盘触发事件的话,会得到键盘的相关信息,如按下哪个键

兼容性问题:

        在IE678中 浏览器不会给方法传递参数 如果需要的话 需要到window.event中获取查找

解决:e = e || window.event;

<script>
      var div = document.querySelector('div');
      // div.onclick = function(e){
      //   e = e || window.event;
      //   console.log(e);
      // }
      div.addEventListener('click',function(e){
        console.log(e);
      })
    </script>

事件对象的常见属性和方法 

事件对象属性方法        说明
e.target        返回触发事件的对象        标准
e.srcElement返回触发事件的对象        非标准 ie6-8使用
e.type返回事件的类型 比如 click mouseover 不带on
e.cancelBubble阻止冒泡 非标准 ie6-8使用
e.returnValue阻止默认事件(默认行为)非标准 ie6-8使用 比如不让链接跳转
e.preventDefault()阻止默认事件(默认行为)标准 比如不让链接跳转
e.stopPropagation()阻止冒泡 标准

1、e.target 与 this 的区别

e.target 返回的是触发事件的对象(元素)

this返回的是绑定事件的对象(元素)

<body>
    <ul>
      <li>123</li>
      <li>123</li>
      <li>123</li>
    </ul>
    <script>
      var ul = document.querySelector('ul');
      ul.addEventListener('click',function(e){
    //我们给ul绑定了事件 那么this 就指向ul
        console.log(this);  //<ul>...</ul>
    //e.target指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target指向的就是li
        console.log(e.target);//<li>...</li>
      })
    </script>
  </body>

2、返回事件类型

<body>
    <div>哈哈哈</div>
    <script>
      // 返回事件类型
      var div = document.querySelector('div');
      div.addEventListener('click',fn);
      div.addEventListener('mouseover',fn);
      div.addEventListener('mouseout',fn);

      function fn(e){
        console.log(e.type);  //根据触发情况返回click mouseover mouseout
      }
    </script>
  </body>

3、阻止默认行为(事件) 让链接不跳转

e.preventDefault()

e.returnValue

<body>
    <a href="baidu.com">百度</a>
    <script>
      // 阻止默认行为(事件) 让链接不跳转 或者提交按钮不提交
      var a = document.querySelector('a');
      a.addEventListener('click', function(e){
        e.preventDefault();
      })
      // 传统的注册方式
      a.onclick = function(e){
        // 普通浏览器 e.preventDefault(); 方法
        e.preventDefault();
        // 低版本浏览器IE678 returnValue 属性
        e.returnValue;
        // return false也能阻止默认行为 没有兼容性问题 特点 return后面的代码不执行了而且只限于传统的注册方式
        return false;
      }
    </script>
  </body>

4、阻止事件冒泡的两种方式

e.stopPropagation()

e.cancelBubble

<body>
    <div class="father">
      <div class="son">son儿子</div>
    </div>
    <script>
      // 阻止冒泡 dom标准 stopPropagation()
      var son = document.querySelector('.son');
      son.addEventListener('click',function(e){
        alert('son');
        if(e && e.stopPropagation){
          e.stopPropagation();
        }else{
          window.event.cancelBubble = true;
        }
      },false);
      
      var father = document.querySelector('.father');
      father.addEventListener('click',function(){
        alert('father');
      },false);
    </script>
  </body>

 5、事件委托(代理、委派)

原理

        不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点

作用:只操作了一次DOM,提高了程序的性能

  <body>
    <ul>
      <li>zhi</li>
      <li>我是2</li>
      <li>我是3</li>
    </ul>
    <script>
      var ul = document.querySelector('ul');
      ul.addEventListener('click',function(e){
      // alert("我弹出来啦");
      //  e.target这个可以得到我们点击的对象
      e.target.style.backgroundColor = 'pink';
      })
    </script>
  </body>

6、常用鼠标事件

(1)禁止鼠标右键菜单 contextmenu

(2)禁止鼠标选中文字(selectstart 开始选中)

<body>
  我是一段不愿意分享的文字
  <script>
    // 1.contextmenu 禁用右键菜单
    document.addEventListener('contextmenu',function(e){
      e.preventDefault();
    })

    // 2.禁止选中文字 selectstart
    document.addEventListener('selectstart',function(e){
      e.preventDefault();
    })
  </script>
</body>

(3)鼠标事件MouseEvent

鼠标事件对象

说明
e.clientX返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX返回鼠标相对于文档页面的X坐标 IE9+支持
e.pageY返回鼠标相对于文档页面的Y坐标 IE9+支持
e.screenX返回鼠标相对于电脑屏幕的X坐标
e.screenY返回鼠标相对于电脑屏幕的Y坐标
  <script>
    document.addEventListener('click',function(e){
      console.log(e.pageX);
      console.log(e.pageY);
    })
  </script>

(4)键盘事件KeyboardEvent

键盘事件

触发条件
onkeyup某个键盘按键被松开时触发
onkeydown某个键盘按键被按下时触发
onkeypress某个键盘按键被松开时触发 但它不识别功能键(ctrl、shift等)
  •  如果使用addEventListener不需要加on
  • 三个事件的执行顺序是:keydown--keypress--keyup

键盘事件对象属性——keyCode        返回该键的ASCII值

  • onkeydown 和 onkeyup不区分字母大小写,onkeypress区分字母大小写
  • 在实际开发中,我们更多的使用keydown和keyup,它能识别所有的键(包括功能键)
  • keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值
<script>
      // keyup 按键被松开时触发(两种写法都可以) 不区分字母大小写 a和A都是65
      // document.onkeyup = function(){
      //   console.log('我弹起来了');
      // }
      document.addEventListener("keyup", function (e) {
        console.log("up:" + e.keyCode);
        // 我们可以利用keyCode返回的ASCII码值来判断用户按下了哪个键
        if (e.keyCode === 65) {
          alert("你按下的是a键");
        } else {
          alert("你按下的不是a键");
        }
      });
      // keydown 按键被按下时触发 识别功能键 不区分字母大小写 a和A都是65
      document.addEventListener("keydown", function (e) {
        console.log("down:" + e.keyCode);
      });
      // keypress 按键被按下时触发 不识别功能键 区分字母大小写 a是97 A是65
      document.addEventListener("keypress", function (e) {
        console.log("press:" + e.keyCode);
      });
    </script>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值