JavaScript之DOM基础

1. 初识DOM

DOM: 文档对象模型
是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。
w3c已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式。
DOM树:
    文档:一个页面就是一个文档, DOM中使用document来表示;
    元素:页面中的所有标签都是元素,DOM中用element表示;
    节点:网页中的 [所有内容] 都是节点(标签,属性,文本,注释等),DOM中使用node表示。

1.1 获取元素1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="time">Hello World</div>
    <ul>
        <li>A</li>
        <li>B</li>
        <li>C</li>
        <li>D</li>
        <li>E</li>
    </ul>
    <ul id="ID">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
//1. getElementById():以对象的形式返回
        var obj = document.getElementById('time');
        // console.log(obj);
        // console.log(typeof obj);
        //console.dir():       列出了对象的详细信息
        // console.dir(obj);

//2. getElementsByTagName():以伪数组的形式返回:所有的li的集合
    var lis = document.getElementsByTagName('li');
    console.log(lis);
    for(var i =0;i < lis.length;i++) {
        console.log(lis[i]);
    }

    console.log('--------------------------');
    var ul = document.getElementById("ID");     //ID下的li的集合
    var liss = ul.getElementsByTagName("li");
    console.log(liss);
    for(var i =0;i < liss.length;i++) {
        console.log(liss[i]);
    }

    </script>
</body>
</html>

1.2 获取元素2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=b, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 
        getElementsByClassName():  => html5  
        querySelector('选择器')    => html5  返回指定选择器的第一个对象,选择器要加符号,.box,#nav; 
        querySelectorAll:         => html5  返回选择器里的所有元素对象的集合 ;  
     -->
    <div class="box">盒子1</div>
    <div class="box">盒子2</div>
    <div id="nav">
        <ul>
            <li>首页</li>
            <li>产品</li>
        </ul>
    </div>
    <script>
        //
        var Box = document.getElementsByClassName('box');
        console.log(Box);
        //
        var firstbox = document.querySelector('.box');
        console.log(firstbox);
        var nav = document.querySelector('#nav');
        console.log(nav);
        var firstli = document.querySelector('li');
        console.log(firstli);
        //
        var allbox = document.querySelectorAll('.box');
        console.log(allbox);
    </script>
</body>
</html>

1.3 获取元素3

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
            //1.获取body元素
        console.log(document.body);
            //2获取html元素
        console.log(document.documentElement);
    </script>
</body>
</html>

2. 属性操作

2.1 修改样式属性1

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <title>Document</title> 
    <style>  
        div {
            width: 200px; 
            height: 200px; 
            background-color: red; 
        }
    </style>
</head>
<body>
    <!-- 
         通过element.style 修改样式; 
     -->
    <div></div>
    <script>
        var div = document.querySelector('div');
        div.onclick = function() {
            this.style.backgroundColor = 'purple';
        }
    </script>
</body>
</html>

2.2 修改样式属性2

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 100px;
            height: 100px;
            background-color: pink;
        }

        .change {
            background-color: purple;
            color: #fff;
            font-size: 25px;
            margin-top: 100px;
        }
    </style>
</head>


<body>
    <!-- 
        通过element.className 修改样式; 
     -->
    <div class="first">文本</div>
    <script>
        // [1.] 使用 element.style 获得修改元素样式  如果样式比较少 或者 功能简单的情况下使用
        var test = document.querySelector('div');
        test.onclick = function () {
            // this.style.backgroundColor = 'purple';
            // this.style.color = '#fff';
            // this.style.fontSize = '25px';
            // this.style.marginTop = '100px';


            // [2.] 我们可以通过 修改元素的className更改元素的样式 适合于样式较多或者功能复杂的情况;
            // [3.] className会覆盖原先的类名; (通过浏览器调试就可以看出)
            // this.className = 'change';

            // [4.] 如果想要保留原先的类名,我们可以这么做 多类名选择器;
            this.className = 'first change';
        }
    </script>
</body>

</html>

2.3 获取修改属性

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- 
        1. element.属性; 
        2. getAttribute()/setAttribute(); 
        3. removeAttribute(); 
     -->
</head>

<body>
    <div id="demo" index="1" class="nav"></div>
    <script>
        var div = document.querySelector('div');
        // [1.] 获取元素的属性值(获取内置的属性值, 元素本身自带的属性)
        // (1) element.属性; 
        console.log(div.id);

        // (2) element.getAttribute('属性') (既可以获取内置的属性值, 又可以获取自定义属性值)
        console.log(div.getAttribute('id'));
        console.log(div.getAttribute('index'));     //获取自定义属性值


/******************************************************************************************************/
        // [2.] 设置元素属性值
        // (1) element.属性= '值'; 
        div.id = 'test';
        div.className = 'navs';

        // (2) element.setAttribute('属性', '值');  主要针对于自定义属性
        div.setAttribute('index', 2);
        div.setAttribute('class', 'footer'); 


/******************************************************************************************************/
        // [3.] 移除属性 removeAttribute(属性)    
        div.removeAttribute('index');
    </script>
</body>

</html>

2.4 H5自定义属性

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div style="color: red" getTime="20" data-index="2" data-list-name="andy"></div>
    <script>
        var div = document.querySelector('div');
        console.log(div.getTime);                    //undefined(因为不是内置属性)
        console.log(div.getAttribute('getTime'));    //20
        console.log('-------------------------------');


        /* 
            通过以上可以看出:自定义属性的属性值不能通过element.属性来获取, 必须通过getAttribute()来获取;
            h5新增自定义属性的方法, 约定属性只能以data-开头; 
            dataset 是一个集合里面存放了所有以data开头的自定义属性; 
        */
        div.setAttribute('data-time', 20);
        console.log(div.getAttribute('data-index'));            // 2
        console.log(div.getAttribute('data-list-name'));        // andy
        console.log('-------------------------------');


        // 1. dataset是一个集合, 里面存放了所有以data开头的自定义属性; 
        console.log(div.dataset);               //是一个集合
        console.log(div.dataset.index);         //相当于获取data-index属性值, 2
        console.log(div.dataset['index']);      //同上
        // 2. 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
        console.log(div.dataset.listName);      //andy
        console.log(div.dataset['listName']);   //同上
    </script>
</body>

</html>

3. 节点操作

3.1 init

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 
        背景:获取元素通常有两种方式:
            (1) 利用DOM提供的方法来获取元素;    
                document.getElementById(), .getElementByTagName(),,, 
                逻辑型不强, 繁琐; 
            (2) 利用节点层级关系来获取元素; 
                利用父子兄弟节点关系来获取元素; 
     -->
</head>
<body>
    <!-- 
        一般地,节点至少拥有nodeType, nodeName, nodeValue这三个基本属性; 
            元素节点: nodeType = 1;
            属性节点: nodeType = 2;
            文本节点: nodeType = 3; (文本节点包括:文字,空格,换行等)
            Notice: 在实际开发中, 节点操作主要操作的是元素节点; 
     -->
</body>
</html>

3.2 获取父子节点

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>

    <script>
/* 通过属性获取父子节点: */
/***********************************************************************/
        // 1. 获取父节点
        var erweima = document.querySelector('.erweima');
        var box = document.querySelector('.box');           //之前写法
        console.log(erweima.parentNode);                    //现在写法

/***********************************************************************/
        // 2. 获取子节点
        // (0) 之前:
        var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');

        // (1) childNodes: 获取[所有子节点]: 包含 元素节点, 文本节点等等; 
        console.log(ul.childNodes);
        console.log(ul.childNodes[0].nodeType);     // 3 
        console.log(ul.childNodes[1].nodeType);     // 1 

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

</html>

3.3 获取首尾子节点

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

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

        // 2. firstElementChild: 返回第一个子元素节点, ie9才支持; 
        console.log(ol.firstElementChild);
        console.log(ol.lastElementChild);

        // 3. 实际开发的写法:  
        console.log(ol.children[0]);
        console.log(ol.children[ol.children.length - 1]);
    </script>
</body>

</html>

3.4 获取兄弟节点

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');

        // 1.nextSibling: 下一个兄弟节点, 包含元素节点或者 文本节点等等; 
        console.log(div.nextSibling);
        console.log(div.previousSibling);

        // 2. nextElementSibling: 得到下一个兄弟元素节点; 
        console.log(div.nextElementSibling);
        console.log(div.previousElementSibling);
    </script>
</body>

</html>

3.5 创建添加节点

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <ul>
        <li>我是li</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');

        // 1. 创建添加元素节点 (appendChild)
        var li = document.createElement('li');
        li.style.backgroundColor = 'green';
        ul.appendChild(li);

        // 3. 创建添加元素节点 (insertBefore)
        var lili = document.createElement('li');
        lili.style.backgroundColor = 'purple';
        ul.insertBefore(lili, ul.children[0]);

    </script>
</body>

</html>

3.6 删除节点

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <button>删除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        btn.onclick = function() {
            if (ul.children.length == 0) {
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>

</html>

3.7 克隆节点

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <ul>
        <li>1111</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        // 1. node.cloneNode(false):     括号为空或者里面是false, 则是浅拷贝, 只复制标签不复制里面的内容
        // 2. node.cloneNode(true):     括号为true,则是深拷贝,既复制标签同时又复制里面的内容
        var ul = document.querySelector('ul');
        var copyLi = ul.children[0].cloneNode(true);
        ul.appendChild(copyLi);
    </script>
</body>

</html>

3.8 3种动态创建元素的区别

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- 
        1. document.write();  //很少使用
        2. element.innerHTML; 
        3. document.createElement(); 
     -->
</head>

<body>
    <button>点击</button>
    <p>abc</p>
    <div class="inner"></div>
    <div class="create"></div>
    <script>
        // window.onload = function() {
        //         document.write('<div>123</div>');

        //     }
        // 三种创建元素方式区别 
        // 1. document.write() 创建元素;
        // 如果页面文档流加载完毕,再调用这句话会导致页面重绘; 
        var btn = document.querySelector('button');
        btn.onclick = function() {
            document.write('<div>123</div>');
        }

/**************************************************************************************************/
        // 2. innerHTML 创建元素
        var inner = document.querySelector('.inner');
        // for (var i = 0; i <= 100; i++) {
        //     inner.innerHTML += '<a href="#">百度</a>'
        // }
        var arr = [];
        for (var i = 0; i <= 100; i++) {
            arr.push('<a href="#">百度</a>');
        }
        inner.innerHTML = arr.join('');
        console.log(arr.join(''));

/**************************************************************************************************/
        // 3. document.createElement() 创建元素
        var create = document.querySelector('.create');
        for (var i = 0; i <= 100; i++) {
            var a = document.createElement('a');
            a.innerText = 'Hello';
            create.appendChild(a);
        }

        var Arr = ['1','2','3','4'];
        console.log(Arr.join(''));      //1234
    </script>
</body>

</html>

3.9 效率测试

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

<head>
    <meta charset="UTF-8">
    <title>效率测试</title>
<!--     
    (1) document.write是直接将内容写入页面的内容流,但是文档流执行完毕, 则它会导致页面全部重绘; 
    (2) innerHTML 是将内容写入某个DOM节点, 不会导致页面全部重绘; 
    (3) innerHTML 创建多个元素效率更高(不要拼接字符串,采用数组形式拼接),但结构稍微复杂; 
    (4) createElement() 创建过个元素效率稍微低点, 但是结构更为清晰;  
-->
</head>

<body>
</body>
<script>
    function fn() {
        var d1 = +new Date();
        var str = '';
        for (var i = 0; i < 1000; i++) {
            document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
        }
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    fn();
/**********************************************************************************************/
    function _fn() {
        var d1 = +new Date();
        var array = [];
        for (var i = 0; i < 1000; i++) {
            array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
        }
        document.body.innerHTML = array.join('');
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    // _fn();

/**********************************************************************************************/
    function __fn() {
        var d1 = +new Date();
        for (var i = 0; i < 1000; i++) {
            var div = document.createElement('div');
            div.style.width = '100px';
            div.style.height = '2px';
            div.style.border = '1px solid red';
            document.body.appendChild(div);
        }
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    // __fn();
</script>

</html>

4. 事件基础

4.1 响应机制

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 
        事件:事件源 + 事件类型 + 事件处理程序; 
        事件源:例如,按钮; 
        事件类型:比如,鼠标经过,键盘按下; 
        事件处理程序:函数; 

        常见鼠标事件:
            onclick,onmouseover,onmouseout,onfocus,onblur,onmousemove,
            onmouseup,onmousedown; 
    -->
</head>

<body>
    <button id='btn'>Hello World!</button>
    <script>
        var btn = document.getElementById('btn');
            btn.onclick = function () {
                alert('触发了!');
        }

        console.log('------------');
        var a = [];
        var b = a;
        b[0] = 1;
        console.log(a);
        console.log(b);
        console.log(a == b); //=>true,b实际上是变量a的引用,并不是拷贝

        var num = 6;
        console.log(num.toString(2)); //二进制
        console.log("0" + num.toString(8)); //八进制
        console.log("0x" + num.toString(16)); //16进制

        //Js中 => 函数时可以嵌套定义的
        function test() {
            console.log('hello');

            function tt() {
                console.log('world');
            }
            tt();
        }
        test();
    </script>
</body>

</html>

4.2 操作元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>Hello</div>
    <p>
        我是文字
        <span>1324</span>
    </p>
    <script>
        var div = document.querySelector('div');
//innerText 和 innerHTML的区别
    //一、
        //1. innerText不识别HTML标签(当做寻常的text内容使用即可), 去除空格会换行; 
        // div.innerText = '<strong>今天是:</strong>jlkkj', 保留空格和换行;

        //2. innerHTML识别HTML标签; 
        div.innerHTML = '<strong>今天是:</strong>lljl';
        
    //二、
        var p = document.querySelector('p');
        console.log(p.innerText);        //我是文字 1324
        console.log(p.innerHTML);        //我是文字  [换行]  <span>1324</span> 
    </script>
</body>
</html>

4.2 案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id='first'>第一张图片</button>
    <button id='second'>第二张图片</button> <br/>
    <img src="./images/1.jpg" alt="" title="第一张图片">
    <link rel="stylesheet" href="" id="test">
    <script>
        var first = document.getElementById('first');
        var second = document.getElementById('second');
        var img = document.querySelector('img');
        first.onclick = function() {
            img.src = './images/2.jpg'; 
            img.title = '第二张图片'; 
        }
        second.onclick = function() {
            img.src = './images/1.jpg'; 
            img.title = '第一张图片'; 
        }
    </script>
</body>
</html>

请添加图片描述

5.事件高级

5.1 注册事件

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <button>传统注册事件</button>
    <button>方法监听注册事件</button>
    <button>ie9 attachEvent</button>
    <script>
        var btns = document.querySelectorAll('button');
        // [1.] 传统方式注册事件: 同一个元素,同一个事件只能设置一个处理函数, 后面注册的事件处理函数会覆盖之前的...
        btns[0].onclick = function () {
            alert('hi');
        }
        btns[0].onclick = function () {
            alert('hao a u');
        }

        // [2.] 事件监听注册事件 addEventListener 
        // (1) 里面的事件类型是字符串, 必定加引号, 而且不带on; (看官方文档即可知道); 
        // (2) 同一个元素,同一个事件,可以添加多个监听器(事件处理程序); 
        // (3) ie9之前不支持此方法, 可用attachEvent来代替; 
        btns[1].addEventListener('click', function () {
            alert(22);
        })
        btns[1].addEventListener('click', function () {
            alert(33);
        })

        // [3.] attachEvent ie9以前的版本支持(不要使用它)
        btns[2].attachEvent('onclick', function () {
            alert(11);
        })
    </script>
</body>

</html>

请添加图片描述

5.2 删除事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: red;
            border: 2px solid black;
        }
    </style>
</head>
<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script>
        //1.传统方式的删除事件
        var divs = document.querySelectorAll('div');
        divs[0].onclick = function() {
            alert(11);
            divs[0].onclick = null; //删除事件
        }

        //2.监听方式的删除事件: removeEventListener
        divs[1].addEventListener('click',fn)
        function fn() {
            alert('listen');
            divs[1].removeEventListener('click', fn);
        }

        //3.attach方式的删除事件
        divs[2].attachEvent('onclick',fn1);
        function fn1(){
            alert('attach');
            divs[2].detachEvent('onclick',fn1);
        }
    </script>
</body>
</html>

请添加图片描述

5.3 dom事件流

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .father {
            width: 200px;
            height: 200px;
            background-color: red;
        }
        .son {
            width: 100px;
            height: 100px;
            background-color: green;
        }
    </style>
</head>
<body>
    <!-- 
        事件流描述的是从页面中接收事件的顺序; 
        事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流; 
        DOM事件流分为3个阶段:
            1.捕获阶段; 
            2.当前目标阶段; 
            3.冒泡阶段; 
            可以这么理解:捕获阶段 => 从最外层开始 向目标元素 层层靠近; 
                        冒泡阶段 => 从目标元素开始 向外 逐层冒泡; 
        (1) JS代码只能处于其中一个阶段,要么是冒泡阶段,要么是捕获阶段; 
        (2) onclick 和 attachEvent只能得到冒泡阶段; 
        (3) addEventListener()的第3个参数可以决定处于哪个阶段:冒泡阶段还是捕获阶段; 
            true        =>  捕获阶段;       
            false或省略 =>  冒泡阶段; 
     -->
     <div class="father">
         <div class="son"></div>
     </div>
     <script>
        //  1.捕获阶段
        // body-father->son
        document.addEventListener('click', function() {
            alert('document-捕获');
        }, true);
        var father = document.querySelector('.father');
        father.addEventListener('click',function(){
            alert('father-捕获');
        }, true);
        var son = document.querySelector('.son');
        son.addEventListener('click',function(){
            alert('son-捕获');
        }, true);

        
        // 2.冒泡阶段
        // son->father->body
        var son = document.querySelector('.son');
        son.addEventListener('click',function(){
            alert('son-冒泡');
        }, false);
        var father = document.querySelector('.father');
        father.addEventListener('click',function(){
            alert('father-冒泡');
        }, false);
        document.addEventListener('click',function(){
            alert('document-冒泡');
        }, false);

     </script>
</body>
</html>

在这里插入图片描述

请添加图片描述

5.4 事件对象

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 100px;
            height: 100px;
            background-color: green;
        }
        span {
            display: block;
            width: 100px;
            height: 100px;
            background-color: purple;
        }
    </style>
</head>

<body>
    <!-- 
        事件对象:事件发生后,跟事件相关的一系列信息数据的集合都放在这个对象里面,
        这个对象就是事件对象event,它有很多属性和方法。
     -->
    <div>123</div>
    <span>HelloWorld</span>
    <script>
        var div = document.querySelector('div');
         div.onclick = function(event) {    
             console.log(event);
         }
         /*
            上述函数中的形参event就是一个事件对象; 
            事件对象只有有了事件才会存在, 它是系统自动给我们创建的; 
            事件对象是与此事件相关的一系列数据的集合; 
         */


        var span = document.querySelector('span');
        span.addEventListener('click', function (event) {
             console.log(event);
            // console.log(window.event);
            event = event || window.event;      //考虑兼容性问题
        })
        //另外,事件对象可以自己命名,event,ev,e都可以的!
        //兼容性问题: IE678通过 window.event进行获得事件对象!
    </script>
</body>

</html>

在这里插入图片描述

5.5 事件对象的属性和方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 50px;
            height: 50px;
            background-color: green;
        }
        ul li {
            width: 50px;
            height: 50px;
            background-color: red;
            border: 2px solid black;
        }
        a {
            width: 50px;
            background-color: yellow;
        }

        .father {
            width: 100px;
            height: 100px;
            background-color: purple;
        }
        .son {
            width: 50px;
            height: 50px;
            background-color: blue;
        }

        /* 事件对象的属性和方法
            e.target:                   返回触发事件的对象; 
            e.srcElement:               返回事件的对象  非标准IE6—8使用; 
            e.type:                     返回事件的类型, 比如click,mouseover,,,; 
            e.cancelBubble:             该属性阻止冒泡; 
            e.returnValue:              该属性阻止默认事件,比如不让链接跳转; 
            e.preventDefault():         该方法阻止默认事件,比如不让链接跳转; 
            e.stopPropagation():        阻止冒泡; 
         */
    </style>
</head>
<body>
    <div>123</div>
    <ul>
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
    </ul>
    <a href="www.baidu.com">百度</a>
    <div class="father">
        <div class="son">儿子</div>
    </div>

    <script>
/****************************************************************************/
        // [1.] event.target返回的是触发事件的对象,this返回的是绑定事件的对象; 
        var div = document.querySelector('div');
        div.addEventListener('click',function(event) {
            console.log(event.target);      //div
            console.log(this);              //div
        });
        //
        var ul = document.querySelector('ul');
        ul.addEventListener('click',function(event) {
            console.log(this);              //ul
            console.log(event.target);      //li
        });

/****************************************************************************/
        // [2.] preventDefault():阻止默认行为,让链接不跳转或者让提交按钮不提交; 
        var a = document.querySelector('a');
            //监听注册
        a.addEventListener('click',function(event) {
            event.preventDefault();
        })  
            //传统注册
        a.onclick = function(event) {   
            event.preventDefault();    //普通浏览器
            // event.returnValue;      //低版本IE-678
            return false;              //也可以阻止默认行为, 没有兼容性问题,但是return后的代码无法执行了
        };

/****************************************************************************/
        // [3.] 阻止冒泡标准:stopPropagation()      //false:冒泡阶段
        var son = document.querySelector('.son');
        son.addEventListener('click',function(event) {
            alert('son-冒泡');
            event.stopPropagation();
            // event.cancelBubble = true;           //低版本
        }, false);     
        var father = document.querySelector('.father');
        father.addEventListener('click',function(event) {
            alert('father-冒泡');
        },false); 
        document.addEventListener('click',function(event) {
            alert('document');
        });         //第三个参数useCapture:默认就是false

    </script>
</body>
</html>

请添加图片描述

5.6 事件委托

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <Ul>
        <li>Hello World</li>
        <li>Hello World</li>
        <li>Hello World</li>
        <li>Hello World</li>
        <li>Hello World</li>
    </Ul>
    <div>禁止复制文字</div>

    <script>
        /* 
            事件委托:也称为事件代理,jQuery里面称为事件委派; 
            事件委托的原理:不用给每个子结点单独设置事件监听器了,而是给其父结点安装事件监听器,然后利用冒泡影响设置每个子结点; 
            冒泡: li -> ul -> body -> html -> document -> window; 
        */
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {      //给父结点ul安装事件监听器
            e.target.style.backgroundColor = 'blue';    //e.target => li
        })
        /* 
            之前的话,把所有小li都给获取过来, 然后用依次给每个小li绑定click事件;(如果小li多就麻烦了) 
            现在,给小li的父结点添加点击事件, 因为点击li,会冒泡,冒到ul上,此时event.target => 就是点击的小li; 
            事件委托作用:只操作了一次dom, 提高了程序的性能; 
        */
        

        //两个事件: 菜单事件, 选择事件
            // 1.禁用右键菜单
        document.addEventListener('contextmenu', function(event){
            event.preventDefault();
        })
            // 2.禁用鼠标选择
        document.addEventListener('selectstart', function(event) {
            event.preventDefault();
        })
    </script>
</body>
</html>

请添加图片描述

5.7 鼠标事件对对象

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            height: 3000px;
        }
    </style>
</head>

<body>
    <script>
        // 鼠标事件对象 MouseEvent

        document.addEventListener('click', function(e) {
            console.log(e);

            // 1. client 鼠标在可视区的x和y坐标
            console.log(e.clientX);
            console.log(e.clientY);
            console.log('---------------------');

            // 2. page 鼠标在页面文档的x和y坐标
            console.log(e.pageX);
            console.log(e.pageY);
            console.log('---------------------');

            // 3. screen 鼠标在电脑屏幕的x和y坐标
            console.log(e.screenX);
            console.log(e.screenY);

        })
    </script>
</body>

</html>

请添加图片描述

5.8 键盘事件对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 
        keyup:    可以识别功能键; 
        keydown:  可以识别功能键; 
        keypress: 不能识别功能键(control,shift,<-, ->,,,);  
        执行顺序:   keydown -> keypress -> keyup; 
     -->
     <!-- 
         onkeydown和onkeyup不区分字母大小写,onkeypress区分字母大小写。
         在实际开发中,更多的使用的是keydown和keyup,因为它能识别所有的键(包括功能键)
         keypress: 不识别功能键(比如 ctrl shift 左右箭头,,,); 
         keydown/keyup: 识别功能键; 
         keyCode属性:返回该键的ASCII码值!
         keyup 和keydown事件不区分字母大小写    =>      a 和 A 得到的都是65; 
         keypress 事件 区分字母大小写           =>      a-97 和 A-65; 
      -->
      <script>
          document.addEventListener('keydown', function(event) {
                console.log('keydown' + event.keyCode);
          }); 
          document.addEventListener('keypress', function(){
              console.log('press' + event.keyCode);
          }); 
          document.addEventListener('keyup', function(event) {
              console.log('keyup' + event.keyCode);
          }); 
      </script>
</body>
</html>

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/23462.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode_DFS_困难_1377.T 秒后青蛙的位置

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一棵由 n 个顶点组成的无向树&#xff0c;顶点编号从 1 到 n。青蛙从 顶点 1 开始起跳。规则如下&#xff1a; 在一秒内&#xff0c;青蛙从它所在的当前顶点跳到另一个未访问过的顶点&#xff08;如果它…

redis【stream】:对redis流数据类型的详细介绍

目录 stream产生原因 stream的概念 stream底层实现 stream的常用指令 常用命令一览&#xff1a; xadd命令 xread命令 xlen命令 xrange命令 xrevrange命令 xtrim命令 xdel命令 xgroup命令 xinfo命令 xpending命令 xreadgroup命令 xack命令 xclaim命令 stream产…

linux周六串讲

esc. //粘贴复制上一条命令的参数 cat /etc/resolv.conf //查看DNS地址 route -n //查看网关 hostname //临时修改主机名 hostnamectl set-hostname 名称 //永久修改主机名 ssh root192.168.10.233 //用windows远程的格式&#xff0c;在CMD窗口输入这个命令 …

zabbix部署

zabbix 是什么&#xff1f; zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 zabbi…

ZooKeeper快速入门学习+在springboot中的应用+监听机制的业务使用

目录 前言 基础知识 一、什么是ZooKeeper 二、为什么使用ZooKeeper 三、数据结构 四、监听通知机制 五、选举机制 使用 1 下载zookeeper 2 修改 3 排错 在SpringBoot中的使用 安装可视化插件 依赖 配置 安装httpclient方便测试 增删查改 新建控制器 创建节点…

云计算:优势与未来趋势

文章目录 前言一、云计算的优势1. 降低IT成本2. 提高工作效率3. 提高业务的可靠性和稳定性4. 提升安全性 二、未来发展趋势1. AI与云计算的融合2. 边缘计算的发展3. 多云的趋势4. 服务器和存储的创新 三、 行业应用案例1.金融行业2.医疗保健行业3.教育行业4.零售和物流行业 四、…

【章节1】git commit规范 + husky + lint-staged实现commit的时候格式化代码

创建项目我们不多说&#xff0c;可以选择默认的&#xff0c;也可以用你们现有的项目。 前言&#xff1a; git commit 的时候总有人填写一堆花里胡哨乱写的内容&#xff0c;甚至看了commit 的描述都不知道他这次提交到底做了个啥&#xff0c;那我们有没有办法规范大家的commit提…

边沿检测电路

目录 同步信号的边沿检测 异步信号的边沿检测 所谓的边沿检测&#xff08;幼教边沿提取&#xff09;&#xff0c;就是检测输入信号的上升沿和下降沿。在设计数字系统时&#xff0c;边沿检测是一种很重要的思想&#xff0c;实际编程时用的最多的时序电路应该就是边沿检测电路和…

docker网络管理

1、常用的网络模式 Docker 容器的网络默认与宿主机、与其他容器都是相互隔离。 1.1、host 使用主机的网络命名空间&#xff0c;这意味着容器与主机共享同一个IP地址和端口号。使用host网络可以提高容器的网络性能&#xff0c;但是会降低容器的隔离性(容器直接使用宿主机网络栈…

浅谈电解电容在电路设计中的作用

谈起电解电容我们不得下多了解一下它的作用 1、滤波作用 在电源电路中&#xff0c;整流电路将交流变成脉动的直流&#xff0c;而在整流电路之后接入一个较大容量的电解电容&#xff0c;利用其充放电特性(储能作用)&#xff0c;使整流后的脉动直流电压变成相对比较稳定的直流电…

C++是如何从代码到游戏的

有一个Student类。C怎么创建一个学生类的对象&#xff1f; // 嗯我会&#xff01;有两种方式&#xff1a; Student s; Student *s2 new Student("张三");现在这学生的行为有&#xff1a;吃饭&#xff0c;睡觉&#xff0c;上网课。现在你执行个上网课的行为&#xf…

次氯酸消毒剂制备中的全氟醚橡胶密封耐腐蚀电动阀门解决方案

摘要&#xff1a;次氯酸作为是一种新型消毒剂&#xff0c;近年来广泛应用于医疗卫生机构、公共卫生场所和家庭的一般物体表面、医疗器械、医疗废物等。由于次氯酸的酸性和强氧化性&#xff0c;使得次氯酸生产制备过程中会给流量调节阀门带来腐蚀并影响寿命和控制精度&#xff0…

UE5电脑配置要求是什么?2023虚幻5电脑配置推荐

虚幻引擎对于游戏创作者来说已经不再陌生。该软件为程序员构建和设计终极视频游戏&#xff0c;以创建壮观的游戏场景和流畅的动作。此外&#xff0c;它还处理音效、物理碰撞效果和控制。尤其是人工智能对角色的控制。与其他软件一样&#xff0c;Unreal Engine也有最低系统要求才…

数据类型的陷进,从表象看本质!

哪些值转为布尔值为false 1、undefined&#xff08;未定义&#xff0c;找不到值时出现&#xff09; 2、null&#xff08;代表空值&#xff09; 3、false&#xff08;布尔值的false&#xff0c;字符串"false"布尔值为true&#xff09; 4、0&#xff08;数字0&…

notepad++查询指定内容并复制

背景说明 记录一下使用notepad进行文本内容查找以及替换的相关场景,简单记录方便后期查看,场景内容: 1.从指定的给出内容中筛选出所有的人员id集合 2.将每一行后面添加逗号 1.从指定的给出内容中筛选出所有的人员id集合 要求从指定的给出内容中筛选出所有的人员id集…

如何增加网站权重?有效提高网站权重的技巧方法

权重对于网站优化来说非常的重要&#xff0c;那什么是网站权重呢&#xff1f;网站权重是指搜索引擎给网站&#xff08;包括网页&#xff09;赋予一定的权威值&#xff0c;对网站&#xff08;含网页&#xff09;权威的评估评价。一个网站权重越高&#xff0c;在搜索引擎所占的份…

Spring 初始导读

1.Spring初始 1. 为什么要学框架 学习框架相当于从"小作坊"到"工厂"的升级 , 小作坊什么都要做 , 工厂是组件式装配 , 特点就是高效. 2.框架的优点展示(SpringBoot Vs Servlet) 使用SpringBoot 项目演示框架相比 Servlet 所具备的以下优点: 无需配置 …

【原创】生成文件MD5图像,类似于GitHub的像素风格头像

前言 我想通过文件的md5生成关于这个md5的图像&#xff0c;类似于GitHub的随机像素头像&#xff0c;用处是让这个md5更加直观&#xff0c;也能用于生成各种用户头像&#xff0c;跟GitHub一样。 网上搜了一下&#xff0c;没有现成的方法&#xff0c;只能有一篇类似的文章可以借…

Android 图片编码之必备技能

在进行 Android 开发时&#xff0c;不可避免地会接触到许多图片格式&#xff0c;例如 JPEG、PNG 等。就以 JPEG 格式为例&#xff0c;它是一种有损压缩模式&#xff0c;使用 YCbCr 的颜色空间来保存色彩信息。当需要在屏幕上显示图片时&#xff0c;会将 JPEG 数据解码成 RGB 进…

如何对项目进度进行跟踪?逐步完善项目计划

我接手了一个小项目&#xff0c;但是无论是我还是领导&#xff0c;都认为这是个简单的项目&#xff0c;最多一月时间就能搞定。但是&#xff0c;随着时间推移&#xff0c;三个月也没有将内容完善。于是我进行了反思总结&#xff0c;我认为存在如下问题&#xff1a; 1、资源协…