JavaScript之DOM基础

news2024/11/27 2:39:03

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>

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android逆向猿人学2022年app比赛第四题grpc与Protobuf使用(步步验证)

教程 前言一、起步二、抓包三、分析四、验证五、HOOK借鉴 前言 前面2-3题和第一题解题思路基本上一样的&#xff0c;这里就不出教程了&#xff0c;这篇文章比较繁琐&#xff0c;基本上描述了我做这题的思路&#xff0c;有很多走不通的地方也有对应的方法&#xff0c;所以会比较…

linux网络初探

linux网络 1.1查看本机ip IP地址 IP地址网络地址主机地址&#xff0c;网络地址&#xff08;网络号&#xff09;相同的主机为本地网络中的主机&#xff0c;可以直接相互通信&#xff0c;而网络地址不同的主机为远程网络中的主机&#xff0c;相互通信必须通过本地网关&#xf…

Flutter Windows开发环境搭建教程与学习资料推荐

Windows应用软件开发有很多框架可以选择&#xff0c;例如比较流行的Electron、Qt、CEF、WPF、WinForm、MFC、DuiLib、SOUI等等。Flutter是近几年流行的全平台应用开发框架&#xff0c;可以进行Android、IOS、Web、MacOS、Windows、Linux等平台的应用软件开发。 一、Flutter介绍…

启动U盘制作工具Rufus 4.0.2035

Rufus是是一款小巧实用免费开源的帮助格式化和创建可启动USB闪存驱动器的工具&#xff0c;如USB钥匙/软盘、记忆棒等&#xff0c;可快速制作linux系统或者win启动u盘&#xff0c;可快速的将ISO镜像文件制作成可引导启动的USB启动盘&#xff0c;支持ISO镜像、GPT和UEFI&#xff…

设置参考文献编号与文中插入引用的具体步骤

目录 一、前言 二、操作步骤 &#xff08;一&#xff09;参考文献设置编号 &#xff08;二&#xff09;文章中引用参考文献方式 一、前言 本教程使用的软件是WPS 二、操作步骤 &#xff08;一&#xff09;参考文献设置编号 1.把引用文献的这个编号全部删掉 2.右键点击段…

学习笔记——vue中使用el-dropdown组件报错

今天在工作中&#xff0c;发现使用el-select做的下拉框&#xff0c;下拉菜单展开后&#xff0c;鼠标点击下拉框之外的区域时&#xff0c;下拉菜单没有收起。然后&#xff0c;我打开控制台&#xff0c;发现了这个错误。 Uncaught TypeError: Cannot read properties of null (re…

《Linux0.11源码解读》理解(四) head之重新设置IDT/GDT

上节提到&#xff0c;现在cs:ip指向0地址&#xff0c;此处存储着作为操作系统核心代码的system模块&#xff0c;是由head.s和 main.c以及后面所有源代码文件编译链接而成。head.s(以下简称head)紧挨着main.c&#xff0c;我们先执行head。 重新设置内核栈 _pg_dir: _startup_3…

堆(堆排序 模拟堆)

目录 一、堆的数据结构二、堆的操作方法往下调整的示意图往上调整的示意图相关功能的实现思路1.插入一个数2.求最小值3.删除最小值4.删除任意一个元素5.修改任意一个元素 三、堆的实战运用堆排序模拟堆 一、堆的数据结构 堆是一个完全二叉树&#xff1a;除了最后一层结点以外&…

C语言三子棋,五子棋,n子棋的代码实现

C语言三子棋&#xff0c;五子棋&#xff0c;n子棋的代码实现 这里以五子棋为例&#xff0c;来说明开发过程开发思路菜单打印棋盘的打印棋子的打印电脑下棋&#xff08;随机数&#xff09;判断输赢代码整合注意事项 这里以五子棋为例&#xff0c;来说明开发过程 其中该项目包含…

《用户增长方法论》从产品、渠道、营销创意等多个维度,搭建了一套完整的用户增长方法体系

关于作者 黄永鹏&#xff0c;目前在阿里巴巴担任高级用户增长专家。黄永鹏是一个典型的 “ 斜杠青年 ” &#xff0c;十年前从广告咨询行业转战互联网&#xff0c;在 BAT 三家 公司都待过&#xff0c;负责过多款用户和日活过亿的产品&#xff0c;比如腾讯手机管家、百度地图…

chatgpt赋能python:Python练手:提高你的SEO技能

Python练手&#xff1a;提高你的SEO技能 在当今数字化时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;成为了网站和企业在线成功的关键。优化技巧既可以提高网站的排名&#xff0c;还可以增加网站的可见性&#xff0c;从而吸引更多的流量和潜在客户。Python是一个适…

网络通信协议-ARP协议

目录 一、ARP协议 二、ARP协议通信过程 应用情景一&#xff1a;同一广播域内通信 &#xff08;1&#xff09;第一步&#xff1a;ARP协议通信 1.交换机接受消息 2.电脑2接收到广播消息 3.电脑2回复 4.交换机转发回复给电脑1 5.电脑1记录 &#xff08;2&#xff09;第二…

Go快速上手之基础语法 | 青训营笔记

Go快速上手之基础语法 &#xff5c; 青训营笔记 文章目录 Go快速上手之基础语法 &#xff5c; 青训营笔记系列介绍本文摘要1. Go 介绍2. Go 的环境配置2.1 :sparkles: IDE2.2 Gitpod 和 Jetbrians Gateway 的使用 3. Go的基础语法3.1 Hello World3.2 变量与常量3.3 条件控制语句…

Linux(进程间通信)

目录&#xff1a; 1.进程间通信的介绍 2.管道通信 3.管道的原理 ------------------------------------------------------------------------------------------------------------------------------- 1.进程间通信的介绍 2.管道通信 当我们在创建子进程时&#xff0c;我们的…

chatgpt赋能python:Python生成pyc文件的介绍

Python生成pyc文件的介绍 Python是一种解释型语言&#xff0c;但是在执行某些操作时&#xff0c;它会生成缓存文件&#xff0c;以便提高执行效率。这些缓存文件以 .pyc 扩展名保存在同一目录中。 在本文中&#xff0c;我们将重点介绍Python生成pyc文件&#xff0c;并探讨它们…

使用Python绘制M2货币供应率曲线

M2广义货币供应量&#xff1a;流通于银行体系之外的现金加上企业存款、居民储蓄存款以及其他存款&#xff0c;它包括了一切可能成为现实购买力的货币形式&#xff0c;通常反映的是社会总需求变化和未来通胀的压力状态。近年来&#xff0c;很多国家都把M2作为货币供应量的调控目…

Fedora安装并配置开启SSH服务相关命令

Ubuntu参考我这篇&#xff1a;虚拟机里安装ubuntu-23.04-beta-desktop-amd64&#xff0c;开启SSH(换源、备份)&#xff0c;配置中文以及中文输入法等 一、过程 1、检测是否安装了openssh-server $ rpm -qa | grep openssh-serveropenssh-server-7.9p1-5.fc30.x86_642、如果上…

【web框架】——Django——如桃花来

目录索引 web框架介绍&#xff1a;常见软件的架构&#xff1a;*CS架构&#xff1a;**BS架构&#xff1a;* 网络通信&#xff1a;socket知识复习&#xff1a;*服务端代码逻辑&#xff1a;**客户端代码逻辑&#xff1a;* socket代码演示&#xff1a;*服务端代码演示&#xff1a;*…

chatgpt赋能python:Python生成:深入了解Python编程中的生成

Python 生成&#xff1a;深入了解Python编程中的生成 简介 Python是一门多用途编程语言&#xff0c;广泛应用于 Web 开发&#xff0c;数据分析&#xff0c;人工智能和科学计算等领域。在Python编程中&#xff0c;生成是一个强大而又常用的概念。本文将介绍Python编程中的生成…

如何在华为OD机试中获得满分?Java实现【输入n个整数,输出其中最小的k个】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…