day12JS-Event事件

1. 事件的分类

事件类型包括有系统事件自定义事件

2. 初始化事件

1. 创建事件对象,Event事件对象。

bubbles:true 表示支持冒泡。

var/let 变量名 = new Event(事件类型,事件选项是否支持冒泡(可省略));

2. 创建一个事件目标对象实例化对象

var/let 变量名 = new EventTarget();

 EventTarget 事件目标对象用来侦听事件(Event)事件对象就是被侦听的事件内容 。

3. 自定义事件

1. 创建一个事件目标对象的实例化对象

var target = new EventTarget();

2. 侦听事件:使用EventTarget的addEventListener()方法。

使用侦听事件语法:

实例对象名.addEventListener(事件类型,事件回调函数,是否捕获侦听/事件侦听选项{是否捕获侦听,是否只侦听一次})

删除侦听事件内容的语法:

实例对象名.removeEventListener(事件类型,事件回调函数);

target.addEventListener("xiaoxiao",xiaoxiaoHandler);//xiaoxiaoHandler是回调函数

function xiaoxiaoHandler(){
   // 事件回调函数必须和事件侦听时的回调函数引用指向完全相同
   // 删除事件侦听内容,removeEventListener(事件类型,事件回调函数)
   target.removeEventListener("xiaoxiao",xiaoxiaoHandler);
   console.log("aaa")

};


//尽量不要写的示范:事件回调函数尽量不要使用匿名函数。因为使用匿名函数后,这个事件将无法被删除。
target.addEventListener("xiaoxiao",function(){});

侦听事件

参数一:事件类型的注意事项!!!

1. 事件类型中自定义事件名称可以任意使用任何字符串

2. 当接受到自定义事件这个事件类型时,直接调用事件的回调函数。

参数二:事件回调函数的注意事项!!!

1. 所有事件回调函数命名都需要使用Handler单词结尾

2. 事件回调函数尽量不要使用匿名函数。因为使用匿名函数后,这个事件将无法被删除

3. 事件的回调函数有且仅有一个参数,这个参数就是抛发的事件对象。

4. 事件回调函数必须和事件侦听时的回调函数引用指向完全相同

3. 抛发事件

抛发事件的语法:

实例对象名.dispatchEvent(事件对象名);

var evt = new Event("xiaoxiao");
target.dispatchEvent(evt);

注意!!!

1. 创建事件时,事件类型必须和侦听事件时的事件类型完全一致

2.EventTarget使用dispatchEvent()抛发事件 ,把Event这个事件对象抛发给EventTarget。

3. 事件侦听的对象要抛发给目标对象必须一致

4. bubbles:true 表示支持冒泡。

自定义事件总结:

  • 事件侦听的目标对象必须和事件要抛发的目标对象一致。
  • 事件侦听的事件类型和要发抛发事件的事件类型必须一致。
  • 必须先侦听,后抛发

完整的案列:

//1.创建事件的实例对象     
var target=new EventTarget();
//2.侦听事件
target.addEventListener("xietian",xietianHandler);
//3.抛发事件
var evt=new Event("xietian");
target.dispatchEvent(evt);

function xietianHandler(){
     target.removeEventListener("xietian",xietianHandler);
     console.log("aaa")
}

 事件的作用:解耦。

4. 事件的基础

4.1 事件的三个阶段

案列讲解:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        .div1 {
            width: 200px;
            height: 200px;
            background-color: red;
        }

        .div2 {
            width: 120px;
            height: 120px;
            background-color: orange;
        }

        .div3 {
            width: 75px;
            height: 75px;
            background-color: gold;
            /* 设置div3不接受事件 */
            /* pointer-events: none; */
        }

        /* 水平垂直居中 */
        div {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            margin: auto;
        }
    </style>
</head>

<body>
    <!-- 系统事件内容讲解事件基础 -->
    <div class="div1">
        <div class="div2">
            <div class="div3"></div>
        </div>
    </div>

    <script>
        var div1 = document.querySelector(".div1");
        var div2 = document.querySelector(".div2");
        var div3 = document.querySelector(".div3");

        // click 系统事件点击
          div1.addEventListener("click", clickHandler1);
          div2.addEventListener("click", clickHandler2);
          div3.addEventListener("click", clickHandler3);

          function clickHandler1(e){
            console.log("div1被点击")
          }

          function clickHandler2(e){
            console.log("div2被点击")
          }

          function clickHandler3(e){
            console.log("div3被点击")
          }
    
    </script>
</body>

</html>

案列效果:

黄色区域是div3,为什么点击黄色区域div1和div2会被点击?

 原理示意图:

 总结:

事件在嵌套容器中,是经历三个阶段:

第一个捕获阶段,从外向内。

第二个目标阶段, 到达目标。

第三个冒泡阶段从内向外。

默认收到事件的顺序是冒泡阶段,从内向外。所以上述案列控制台输出的案列才是那样的。

注意:事件的顺序是可以改变的

4.2 修改事件顺序的方法

1. 在侦听事件的方法上设置第三个参数为true,表示捕获阶段触发

捕获阶段触发的目的可以设置在嵌套容器中谁先被触发 。

2. once:true只能触发一次事件,然后这个事件就会被删除

 再次点击是不会在触发了。

3. 既要捕获阶段触发又要只触发一次。

 4.停止冒泡的方法

        停止冒泡就是停止事件的继续传递。可以在捕获和冒泡阶段使用,捕获阶段使用:事件禁止传递给子元素,冒泡阶段使用:事件禁止传递给父元素。

停止冒泡的方法:e.stopPropagation();

5. 让某一个元素不接收事件的方法 

某一个元素的样式上设置pointer-events: none;属性。

5. 事件委托

事件委托 :子元素的事件委托给父元素侦听。(在是嵌套关系时,一般让父级使用侦听方法),使用事件委托时不需要使用停止冒泡

5.1 为什么使用事件委托

1. 每个元素都侦听会占有内存。把事件委托给父元素,这样可以保证只侦听一个,减少内存的占有。

2. 因为每个元素侦听,都会触发对应的函数,就会执行多个函数,事件委托只会执行一个函数

案列:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        .div1 {
            width: 200px;
            height: 200px;
            background-color: red;
        }

        .div2 {
            width: 120px;
            height: 120px;
            background-color: orange;
        }

        .div3 {
            width: 75px;
            height: 75px;
            background-color: gold;
            /* 设置div3不接受事件 */
            /* pointer-events: none; */
        }

        /* 水平垂直居中 */
        div {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            margin: auto;
        }
    </style>
</head>

<body>
    <!-- 系统事件内容讲解事件基础 -->
    <div class="div1">
        <div class="div2">
            <div class="div3"></div>
        </div>
    </div>

    <script>
        var div1 = document.querySelector(".div1");
        var div2 = document.querySelector(".div2");
        var div3 = document.querySelector(".div3");

        // 事件委托  子元素的事件委托给父元素侦听
        div1.addEventListener("click",clickHandler1);

        function clickHandler1(e){
            // console.log(e.target,e.currentTarget,e.srcElement,this);
            console.log(e);
        }
    </script>
</body>

</html>

5.2 事件委托中回调函数自带属性

使用5.1中的案列做详解

        div1.addEventListener("click",clickHandler1);

        function clickHandler1(e){
            // e 就是事件传递的Event对象
            // DOM事件传递时会自带一些属性  target  currentTarget srcElement
            // e.target  e.srcElement(IE兼容的) 是事件实际触发的目标对象
            // e.currentTarget  this  事件侦听的对象
            // console.log(e.target,e.currentTarget,e.srcElement,this);
            console.log(e);
        }

注意!!!

1. e 就是事件传递的Event对象

2. DOM事件传递时会自带一些属性  :targetcurrentTargetsrcElement

        e.target e.srcElement(IE兼容的) 是事件实际触发的目标对象

        e.currentTarget this 事件侦听对象(谁侦听this就是谁)

5.3 系统事件自定义触发事件委托

方法一:var 事件对象名 = new Event("click",{bubbles:true});

1. 系统事件除了使用点击触发以外,还可以通过自定义抛发事件触发

2. 默认事件的抛发不会向父容器冒泡,解决方案使用{bubbles:true}{bubbles:true}设置当前自定义事件允许向父容器冒泡。

案列:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        .div1 {
            width: 200px;
            height: 200px;
            background-color: red;
        }

        .div2 {
            width: 120px;
            height: 120px;
            background-color: orange;
        }

        .div3 {
            width: 75px;
            height: 75px;
            background-color: gold;
            /* 设置div3不接受事件 */
            /* pointer-events: none; */
        }

        /* 水平垂直居中 */
        div {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            margin: auto;
        }
    </style>
</head>

<body>
    <!-- 系统事件内容讲解事件基础 -->
    <div class="div1">
        <div class="div2">
            <div class="div3"></div>
        </div>
    </div>

    <script>
        var div1 = document.querySelector(".div1");
        var div2 = document.querySelector(".div2");
        var div3 = document.querySelector(".div3");

        // 事件委托  子元素的事件委托给父元素侦听
        div1.addEventListener("click",clickHandler1);

        function clickHandler1(e){
            // e 就是事件传递的Event对象
            // DOM事件传递时会自带一些属性  target  currentTarget srcElement
            // e.target  e.srcElement(IE兼容的) 是事件实际触发的目标对象
            // e.currentTarget  this  事件侦听的对象
            console.log(e.target,e.currentTarget,e.srcElement,this);
        }

        // 系统事件也可以通过自定义抛发事件触发
        var evt=new Event("click",{bubbles:true});
        div3.dispatchEvent(evt);
    </script>
</body>

</html>

注意!!!

Event是基类,向上在向上继承MouseEvent类。所以可以使用方法二使用MouseEvent类抛发。

方法二:var 鼠标对象名 = new MouseEvent("click",{bubbles:true,clientX:100,clientY:100})

自定义抛发鼠标点击事件,在这里使用clientX,clientY分别设置被点击的位置。

 5.4 事件委托案列

方法一:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        ul[show="true"] {
            max-height: 2000px;
            overflow: hidden;
            transition: all 1s;
        }

        ul[show="false"] {
            max-height: 0px;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <ul id="city">
        <li>
            北京
            <ul show="true">
                <li>朝阳</li>
                <li>海淀</li>
                <li>
                    昌平
                    <ul show="true">
                        <li>回龙观</li>
                        <li>霍营</li>
                        <li>龙泽</li>
                        <li>老牛湾</li>
                    </ul>
                </li>
                <li>东城</li>
                <li>西城</li>
            </ul>
        </li>
        <li>
            河北
            <ul show="true">
                <li>邯郸</li>
                <li>石家庄</li>
                <li>保定</li>
                <li>承德</li>
                <li>衡水</li>
            </ul>
        </li>
        <li>
            山西
            <ul show="true">
                <li>临汾</li>
                <li>大同</li>
                <li>太原</li>
                <li>晋城</li>
            </ul>
        </li>
        <li>
            陕西
            <ul show="true">
                <li>西安</li>
                <li>咸阳</li>
                <li>宝鸡</li>
                <li>延安</li>
            </ul>
        </li>
        <li>
            山东
            <ul show="true">
                <li>烟台</li>
                <li>威海</li>
                <li>青岛</li>
                <li>济南</li>
            </ul>
        </li>
    </ul>
    <script>
        //方法一:
        let lis;
        init();
        function init() {
            //1.返回一个NodeList(迭代器)类型的集合
            lis = document.querySelectorAll("li");
            //2.遍历迭代器列表
            lis.forEach(item => {
                item.addEventListener("click", clickHandler);
            })
        }
        function clickHandler(e) {
            //3.停止冒泡
            e.stopPropagation();
            //4.获取到第一个子元素
            if (!this.firstElementChild) return;//该编写技巧是真值缩小
            //5.获取DOM标签上的属性值
            if (this.firstElementChild.getAttribute("show") === "true") {
                this.firstElementChild.setAttribute("show", "false");
            } else {
                this.firstElementChild.setAttribute("show", "true");
            };
        }
    </script>
</body>

</html>

方法二:事件委托

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        ul[show="true"] {
            max-height: 2000px;
            overflow: hidden;
            transition: all 1s;
        }

        ul[show="false"] {
            max-height: 0px;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <ul id="city">
        <li>
            北京
            <ul show="true">
                <li>朝阳</li>
                <li>海淀</li>
                <li>
                    昌平
                    <ul show="true">
                        <li>回龙观</li>
                        <li>霍营</li>
                        <li>龙泽</li>
                        <li>老牛湾</li>
                    </ul>
                </li>
                <li>东城</li>
                <li>西城</li>
            </ul>
        </li>
        <li>
            河北
            <ul show="true">
                <li>邯郸</li>
                <li>石家庄</li>
                <li>保定</li>
                <li>承德</li>
                <li>衡水</li>
            </ul>
        </li>
        <li>
            山西
            <ul show="true">
                <li>临汾</li>
                <li>大同</li>
                <li>太原</li>
                <li>晋城</li>
            </ul>
        </li>
        <li>
            陕西
            <ul show="true">
                <li>西安</li>
                <li>咸阳</li>
                <li>宝鸡</li>
                <li>延安</li>
            </ul>
        </li>
        <li>
            山东
            <ul show="true">
                <li>烟台</li>
                <li>威海</li>
                <li>青岛</li>
                <li>济南</li>
            </ul>
        </li>
    </ul>
    <script>
        //方法二:
        let city;
        init();
        function init() {
            //1.根据id获取元素
            city = document.getElementById("city");
            //2.设置侦听对象
            city.addEventListener("click", clickHandler);
        }

        function clickHandler(e) {
            //3.方法一:大写的标签名
            if (e.target.nodeName !== "LI") return;
            //方法二:判断点击标签不是LI
            // if (!(e.target instanceof HTMLLIElement)) return;
            //方法三:判断点击标签不是LI
            // if (!(e.target.constructor !== HTMLLIElement)) return;
            if (e.target.firstElementChild.getAttribute("show") === "true") {
                e.target.firstElementChild.setAttribute("show", "false");
            } else {
                e.target.firstElementChild.setAttribute("show", "true");
            };

        }
    </script>
</body>

</html>

6. 表单中事件阻止默认行为

6.1  表单中的默认行为网页跳转

1. 网址中的 ? 是 search#是hash

2. 页面跳转的方式:

SSR(Server Side Render) : 服务器渲染。跳转到另外的页打开。

CSR( Client Side Render) :客户端渲染。在当前页面打开。

SPA:单页面应用。 SPA 是一种特殊的 Web 应用,是加载单个 HTML 页面并在用户与应用程序交互时动态更新该页面的。一旦页面加载完成, SPA 不会因为用户的操作而进行页面的重新加载或跳转,而是利用 JavaScript 动态的变换 HTML(采用的是 div 切换显示和隐藏),从而实现UI与用户的交互。

6.2 阻止默认行为的方法

 侦听对象.preventDefault();

案列:使用preventDefault()后,form表单就不会在提交数据时进行页面跳转。

<body>
    <form action="#" method="get">
        <input type="text" name="user">
        <button type="submit">提交</button>
    </form>
    <script>
        //1.获取元素
        var form = document.querySelector("form");
        //2.侦听事件,当点击提交按钮触发这个事件
        form.addEventListener("submit", submitHandler);
        function submitHandler() {
            e.preventDefault();//阻止默认行为
            console.log("aaa");
        }
    </script>
</body>

 阻止事件默认行为:

  • 提交表单 :默认提交表单会自动跳转页面,是submit事件被阻止以后不会跳转。
  • 重置表单 :默认会清空表单里的数据  ,是reset事件被阻止后不会清除。
  • 容器中文本 :默认可以选中文本,是 mousedown事件被阻止后不能选中文本。
  • 图片拖拽 :默认拖拽中会产生禁拖标志 ,是mousedown事件被阻止后不会产生禁拖标志。
  • 单击右键菜单时 :默认会有浏览器的菜单 ,是contextmenu事件被阻止后不会有菜单。

6.3 阻止后续事件函数的执行

侦听对象.stopImmediatePropagation();

案列:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div1 {
            width: 200px;
            height: 200px;
            background-color: red;
        }

        .div2 {
            width: 120px;
            height: 120px;
            background-color: orange;
        }

        .div3 {
            width: 75px;
            height: 75px;
            background-color: gold;
            /* 设置div3不接受事件 */
            /* pointer-events: none; */
        }

        /* 水平垂直居中 */
        div {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            margin: auto;
        }
    </style>
</head>

<body>

    <!-- 系统事件内容讲解事件基础 -->
    <div class="div1">
        <div class="div2">
            <div class="div3"></div>
        </div>
    </div>

    <script>

        var div1 = document.querySelector(".div1");
        var div2 = document.querySelector(".div2");
        var div3 = document.querySelector(".div3");

        div1.addEventListener("click", clickHandler1);
        div1.addEventListener("click", clickHandler2);
        div1.addEventListener("click", clickHandler3);

        function clickHandler1(e) {
            console.log("1");
        }
        function clickHandler2(e) {
            // 阻止后续事件函数的执行 同一个事件
            e.stopImmediatePropagation();
            console.log("2");
        }
        function clickHandler3(e) {
            console.log("3");
        }
    </script>
</body>

</html>


7. Event事件有哪些?

submit :表单提交事件。

reset :表单重置事件。

change :表单修改事件。

select :input文本框文本选中事件。

load :加载事件(图片加载、文件加载、通信加载)。

error :错误事件。

scroll :滚动条事件。

8. submit 表单提交事件

8.1 表单中name的作用

作用一:输入文本框必须设置name属性,标签中的name属性在提交时就会把对应的内容放在search部分。

<body>
    <!-- 输入文本框 必须设置name属性,标签中的name属性在提交时就会把对应的内容放在search部分 -->
    <form action="#" method="get">
        <input type="text" name="user">
        <button type="submit">提交</button>
    </form>
</body>

 作用二:在checkboxradio,name的作用是群组但必须设置value值

8.2 在表单中怎样侦听

 注意!!!

提交表单和重置表单时,不能侦听按钮的click事件,必须使用表单侦听submit事件和reset事件。

 

 8.3 Event对象事件中的属性

1. 这四个常量属性代表事件触发的时机

e.AT_TARGET  : 值为2 目标阶段

e.BUBBLING_PHASE :值为3冒泡阶段

e.CAPTURING_PHASE  :值为1捕获阶段

e.NONE :值为0

2.  e.eventPhase 触发时机

案列: 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div1 {
            width: 200px;
            height: 200px;
            background-color: red;
        }

        .div2 {
            width: 120px;
            height: 120px;
            background-color: orange;
        }

        .div3 {
            width: 75px;
            height: 75px;
            background-color: gold;
            /* 设置div3不接受事件 */
            /* pointer-events: none; */
        }

        /* 水平垂直居中 */
        div {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            margin: auto;
        }
    </style>
</head>

<body>

    <div class="div1">
        <div class="div2"></div>
    </div>
  
    <script>
        let div1 = document.querySelector(".div1");
        let div2 = document.querySelector(".div2");
        div1.addEventListener("click", clickHandler1);
        div2.addEventListener("click", clickHandler2);
        function clickHandler1(e) {
            console.log(e.eventPhase, "div1");
        }
        function clickHandler2(e) {
            console.log(e.eventPhase, "div2");
        }
    </script>
</body>

</html>

 

3.  e.bubbles当前事件是否冒泡是只读属性系统事件会自动冒泡,自定义事件不会自动冒泡。

4. e.cancelBubble 阻止当前事件冒泡,早期IE浏览器使用,等同于e.stopPropagation()

5. e.isTrusted :触发当前事件时是系统触发还是自定义触发true表示系统事件触发false表示自定义事件触发

<body>
    <!-- 输入文本框 必须设置name属性,标签中的name属性在提交时就会把对应的内容放在search部分 -->
    <form action="#" method="get">
        <input type="text" name="user">
        <input type="checkbox" name="hobby" value="游戏">游戏
        <input type="checkbox" name="hobby" value="唱歌">唱歌
        <input type="checkbox" name="hobby" value="跳舞">跳舞
        <input type="checkbox" name="hobby" value="跑步">跑步
        <button type="submit">提交</button>
    </form>

    <script>
        //1.获取表单元素
        var form = document.querySelector("form");
        //2.添加侦听事件
        form.addEventListener("submit", submitHandler);
        //3.侦听回调函数
        function submitHandler(e) {
            //4.阻止默认行为(提交表单时,表单的跳转行为)
            e.preventDefault();
            console.log(e);
        }
        //4.创建事件对象
        var evt = new Event("submit");
        //5.自定义触发,向form表单抛发
        form.dispatchEvent(evt);
    </script>
  
</body>

6. e.defaultPrevented判断是否阻止默认事件

7. returnValue阻止默认行为(早期IE浏览器的) ,等同于e.preventDefault();

8. e.timeStamp :从页面打开到当前事件触发经过毫秒数。

9. e.type事件触发的类型,侦听的事件类型。

9. reset 表单重置事件

注意!!!

使用e.preventDefault();阻止默认行为后,表单就不会被清除数据

<body>
    <form action="#" method="get">
        <input type="text" name="user">
        <input type="checkbox" name="hobby" value="游戏">游戏
        <input type="checkbox" name="hobby" value="唱歌">唱歌
        <input type="checkbox" name="hobby" value="跳舞">跳舞
        <input type="checkbox" name="hobby" value="跑步">跑步
        <button type="submit">提交</button>
        <button type="reset">重置</button>
    </form>

    <script>
        //1.获取表单元素
        var form = document.querySelector("form");
        //2.添加侦听事件
        form.addEventListener("reset", resetHandler);
        //3.侦听回调函数
        function resetHandler(e) {
            //4.使用阻止默认行为后,表单就不会被清除数据
            e.preventDefault();
            console.log("aaa");
        }
    </script>
</body>

10. change表单修改事件

注意!!!

1. change事件的触发需要改变表单数据中内容,并且失去焦点才能触发。

2. change事件可以事件委托,可以委托给form。form侦听change事件,当表单元素中任意一个触发change都会收到冒泡。

<body>
    <form action="#" method="get">
        <input type="text" name="user">
        <input type="checkbox" name="hobby" value="游戏">游戏
        <input type="checkbox" name="hobby" value="唱歌">唱歌
        <input type="checkbox" name="hobby" value="跳舞">跳舞
        <input type="checkbox" name="hobby" value="跑步">跑步
        <button type="submit">提交</button>
        <button type="reset">重置</button>
    </form>

    <script>
         //form侦听change,当表单元素中任意一个触发change都会收到冒泡
         var form=document.querySelector("form");
         input.addEventListener("change",changeHandler);
         form.addEventListener("change",changeHandler);

         function changeHandler(e){
             console.log("change");
          }
    </script>
</body>

11. select文本框文本选中事件

注意!!!

1. select事件针对input标签的。

2. input.selectionStart :得到文本框中选中文本的开始下标

3. input.selectionEnd :得到文本框中选中文本的结束下标

<body>
 
    <form action="#" method="get">
        <input type="text" name="user">
        <input type="checkbox" name="hobby" value="游戏">游戏
        <input type="checkbox" name="hobby" value="唱歌">唱歌
        <input type="checkbox" name="hobby" value="跳舞">跳舞
        <input type="checkbox" name="hobby" value="跑步">跑步
        <button type="submit">提交</button>
        <button type="reset">重置</button>
    </form>
 
    <script>
        var input = document.querySelector("input");
        input.addEventListener("select", selectHandler);
        function selectHandler() {
            // console.log("select");
            // 得到文本框中选中文本的起始下标和结束下标
            console.log(input.selectionStart, input.selectionEnd);
        }
    </script>
</body>

12. scroll滚动条事件

注意!!!

1. scrollTop:滚动条上下的位移
2. scrollLeft:滚动条左右的位移

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div1 {
            width: 200px;
            height: 200px;
            background-color: red;
            overflow: scroll;
        }

        .div2 {
            width: 1200px;
            height: 1200px;
            background-color: orange;
        }

        .div3 {
            width: 75px;
            height: 75px;
            background-color: gold;
            /* 设置div3不接受事件 */
            /* pointer-events: none; */
        }
    </style>
</head>

<body>
    <div class="div1">
        <div class="div2"></div>
    </div>

    <script>
        var div1 = document.querySelector(".div1");
        div1.addEventListener("scroll", scrollHandler);

        function scrollHandler(e) {
            // scrollTop 滚动条上下的位移
            // scrollLeft 滚动条左右的位移
            console.log(div1.scrollTop, div1.scrollLeft)
        }
    </script>
</body>

</html>

 13. load加载事件

var img = document.createElement("img")

// 等同于document.createElement("img") 创建图片
// 创建图片容器的宽高
var img=new Image(width,height);

1. ArrayBuffer :二进制流数组类型。

2. 图片的类型:位图、矢量图、像素图。

3. 图片中的二进制流数组  [255,255,255,255,255,255,255,255],这里有两组颜色。

 RGBA :255 255 255 255,四个为一组。

4. 图片加载时会得到一个meta数据。图片加载的流程:创建文档-->创建CSS树-->创建DOM树-->创建DOM渲染树-->加载完成-->执行页面script中module内容。

<body>
    <div class="div1">
        <div class="div2"></div>
    </div>
    <img src="./img/img_23.jpg">

    <script>
        var img = document.createElement("img");
        console.log(img.width, img.height);
    </script>
</body>

注意!!!

1. link标签加载css,同步加载

2. script标签加载js ,默认同步加载,可以异步。

3. img标签加载图片,异步加载

4. video标签加载视频 ,异步加载

        图片加载是一个异步 ,谷歌浏览器先加载meta同步后在继续异步加载图片,所以可以看到图片的宽高。

什么是同步?什么是异步?

 举例说明:

张三  吃饭用了10分钟
李四  洗碗用了5分钟
王五  洗衣服用了30分钟
        
同步:
张三-->李四--->王五  
总共用了45分钟

异步:
张三-->10
李四-->5
王五-->30
总共用了30分钟

 script标签什么时候是同步?什么时候是异步?

<!-- 默认script同步加载完成后执行js,才会继续向后 -->
<script></script>

<!-- async异步加载什么时候加载完成js,什么时候执行js,一般都会在DOM树创建完成后执行 -->
<script async></script>

<!-- defer异步加载在DOM树渲染完成后执行js -->
<script defer></script>

for循环是同步。 

<script>
//循环是同步,同时创建了10次异步setTimeout,1秒后才会执行10次timeout中函数
for (var i = 0; i < 10; i++) {
      var s = i;
      setTimeout(() => {
      console.log(i);//最后打印 i已经变成10了,执行10次就会打印10个10
      // console.log(s);
      }, 1000);
      console.log(i);//先打印0-9
      }
      console.log(i);//再打印10
</script>

图片加载案例:

        for (var i = 23; i < 26; i++) {
            var img = new Image();
            img.src = `./img/img_${i}.jpg`
            // onload加载完成后,加载完成是有时间,异步
            img.onload = function () {
                console.log(img.src);
                // console.log(this.src);
            }
        }

通过了解同步和异步,所以使用this代替img。

        for (var i = 23; i < 26; i++) {
            var img = new Image();
            img.src = `./img/img_${i}.jpg`
            // onload加载完成后,加载完成是有时间,异步
            img.onload = function () {
               console.log(this.src);
            }
        }

load加载事件的案例:

<body>
    <img src="./img/img_23.jpg">
   
    <script>
        // for循环加载比这种一个加载完加载下一个的速度要快
        let i = 23;
        let arr = [];

        loadImage(i);

        function loadImage(i) {
            var img = new Image();
            img.src = `./img/img_${i}.jpg`;
            img.addEventListener("load", loadHandler, { once: true });
            img.addEventListener("error", errorHandler);
        }

        function loadHandler(e) {
            arr.push(this);
            i++;
            if (i < 28) return loadImage(i);
            arr.forEach(item => {
                console.log(item.src);
            })
        }

        function errorHandler(e) {
            console.log(e)
        }
    </script>
</body>

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值