DOM event mechanism (event flow, event delegation, event type) and BOM

The HTML DOM allows JavaScript to react to HTML events. JavaScript can be executed when an event occurs, such as when a user clicks on an HTML element. The interaction between JavaScript and HTML is achieved through events. Events are specific moments of interaction that occur within a document or browser window.

Although ECMAScript describes the Browser Object Model (BOM) as the core of JavaScript, in fact the BOM is the core of developing Web applications using JavaScript. The BOM provides browser functionality objects that are independent of web pages. Over the years, BOM was developed in the context of a lack of specifications, making it both interesting and problematic. After all, browser developers contribute to it as they see fit. Eventually, the common parts between browser implementations became de facto standards, providing a basis for inter-browser interoperability for Web development. Part of the HTML5 specification covers the main content of the BOM, because the W3C hopes to standardize the most basic parts of JavaScript in browsers.

Table of contents

The event is composed of three parts

Steps to execute an event

Common events:

event stream

Event bubbling (IE event stream)

Stop event bubbling event.stopPropagation()

Event Capture (Netscape Event Streaming)

DOM event flow

Dom level 0 events and level 2 events

Prevent event default behavior preventDefault()

event delegation

event type

User interface events--UIEvent

Focus event--FocusEvent

Mouse event--MouseEvent

Keyboard event--KeyboardEvent

BOM

Page jump Window.open()

parameter

URL

name

System dialog box

alert()

confirm()

prompt()

location

Attributes

method

assign()

replace()

reload()

history

length

back()

forward()

go()

Intermittent calls and timeout calls

setTimeout()

parameter:

setInterval()

parameter:


The event is composed of three parts

Event source, event type, and event handler are also called the three elements of an event.

1. Event source: the object where the event is triggered --> button object

2. Event type: How to trigger? What event is triggered? For example, mouse clicks, keyboard presses, etc...

3. Event handler: assignment through a function

Steps to execute an event

1. Get the event source

2. Register event (bind event)

3. Add event handlers in the form of function assignment

Common events:

  • when the user clicks the mouse

  • When the web page loads

  • When the image is loaded

  • When the mouse is moved over the element

  • when the input field is changed

  • When the HTML form is submitted

  • When the user hits a key

  • ....................

event stream

Event bubbling (IE event stream)

The IE event stream is called event bubbling because events are defined to fire starting from the most specific element (the deepest node in the document tree) and then propagate upward to less specific elements (the document).

<!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>
        .outer{
            width: 300px;
            height: 300px;
            background-color: red;
            margin: 0 auto;
            padding: 50px;
            box-sizing: border-box;
        }
        .center{
            width: 200px;
            height: 200px;
            background-color: pink;
            padding: 50px;
            box-sizing: border-box;
        }
        .inner{
            width: 100px;
            height: 100px;
            background-image: linear-gradient(to right,red,pink,blue);
        }
    </style>
    <script>
        window.onload = function(){
            var outer = document.querySelector('.outer');
            var center = document.querySelector('.center');
            var inner = document.querySelector('.inner');
            outer.onclick = function(){
                console.log('我是outer');
                // alert('我是outer');
                console.log(event.target,'触发事件的目标源');
                console.log(event.currentTarget,'当前正在执行事件的dom元素');
            }
            center.onclick = function(){
                console.log('我是center');
                // alert('我是center');
                // event.stopPropagation();
                console.log(event.target,'触发事件的目标源');
                console.log(event.currentTarget,'当前正在执行事件的dom元素');
            }
            inner.onclick = function(){
                console.log('我是inner');
                // alert('我是inner');
                // 阻止事件冒泡 event表示当前的事件对象
                // console.log(event,'事件对象');
                // event.stopPropagation()
                console.log(event.target,'触发事件的目标源');
                console.log(event.currentTarget,'当前正在执行事件的dom元素');
            }
        }
    </script>
</head>
<body>
    <!-- 事件三要素   1.事件源   2.事件类型  3.事件处理程序 -->
    <!-- 事件流 描述的是页面接受事件的顺序 事件冒泡:事件由内向外触发 事件捕获:事件由外向内触发 事件流机制:事件捕获 --到达目标 --事件冒泡 -->
    <div class="outer">
        <div class="center">
            <div class="inner"></div>
        </div>
    </div>
</body>
</html>

 When clicking on the div element with the ID of inner in the page, the click event will occur in the following order

div#inner-----div#center-----div#outer-----body-----html-----document

In other words, the div#inner element, that is, the clicked element, triggers the click event first. Then, the click event goes all the way up the DOM tree, firing on each node it passes through until it reaches the document object.

Stop event bubbling         event.stopPropagation()

Event Capture (Netscape Event Streaming)

The Netscape Communicator team came up with an alternative event stream called event capture. Event capture means that the least specific node should receive the event first, and the most specific node should receive the event last. Event capture is actually about intercepting events before they reach their final destination. If the previous example uses event capture, clicking on a div element will trigger click events in the following order: document-----html ----- body ----- div

In event capture, the click event is first captured by the document element and then propagates down the DOM tree until it reaches the actual target element div.

<!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>
        .outer{
            width: 300px;
            height: 300px;
            background-image: radial-gradient(red,pink,blue);
            margin: 0 auto;
            padding: 50px;
            box-sizing: border-box;
        }
        .center{
            width: 200px;
            height: 200px;
            background-color: red;
            padding: 50px;
            box-sizing: border-box;
        }
        .inner{
            width: 100px;
            height: 100px;
            background-color: blue;
        }
    </style>
    <script>
        window.onload = function(){
            var outer = document.querySelector('.outer');
            var center = document.querySelector('.center');
            var inner = document.querySelector('.inner');
            function hander1(){
                console.log('outer');
            }
            function hander2(){
                console.log('center');
            }
            function hander3(){
                console.log('inner');
            }
            /**
             * false表示事件在冒泡阶段执行
             * true 表示事件在捕获阶段执行
            */
            outer.addEventListener('click',hander1,true);
            center.addEventListener('click',hander2,true);
            inner.addEventListener('click',hander3,true);

        }
    </script>
</head>
<body>
    <div class="outer">
        <div class="center">
            <div class="inner"></div>
        </div>
    </div>
</body>
</html>

 

DOM event flow

The DOM2 Events specification stipulates that the event flow is divided into three stages: event capture, reaching the target and event bubbling. Event capture occurs first, providing the possibility to intercept events in advance. The event is then received by the actual target element. The last stage is bubbling, and events must be responded to at this stage at the latest. Clicking on a div element will trigger events in the order shown.

In the DOM event flow, the actual target (div element) does not receive the event during the capture phase. This is because the capture phase ends from document to html and then to body. The next phase, the "reaching target" phase where the event is fired on the div element, is usually considered part of the bubbling phase in event handling. Then, the bubbling phase begins and events are propagated back to the document. Most browsers that support DOM event streaming implement a small extension. Although the DOM2 Events specification makes it clear that the capture phase does not hit the event target, modern browsers will trigger events on the event target during the capture phase. The end result is that there are two opportunities on the event target to handle the event.

Dom level 0 events and level 2 events

<!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>
    <script>
        window.onload = function(){
            var btn = document.querySelector('button');
            // dom 0级事件绑定 on事件类型
            btn.onclick = function(){
                console.log(this);
            }
            // 追加事件
            btn.onclick = function(){
                console.log('第二次事件触发');
            }
            // 结果看出不可追加同一类型的事件
            // dom 0级事件解绑
            btn.onclick = null;
            
            // dom 2级事件绑定 addEventListener() 参数: 事件类型 事件处理程序 true捕获/false默认冒泡
            // btn.addEventListener('click',function(){
            //     console.log(this);
            // })
            // // 追加事件
            // btn.addEventListener('click',function(){
            //     console.log('第二次事件触发');
            // })
            var handler1 = function(){
                console.log(this);
            }
            var handler2 = function(){
                console.log('第二次事件触发');
            }
            btn.addEventListener('click',handler1);
            btn.addEventListener('click',handler2);
            // 结果看出可以追加同一类型的事件
            // dom 2级事件解绑 removeEventListener() 参数: 事件类型 事件处理程序
            // btn.removeEventListener('click',handler1);
        }   
    </script>
    
</head>
<body>
    <button>点击这里</button>
</body>
</html>

dom0 level event

dom2 level event

The difference between dom0 level and dom2 level events

            1. Use the on keyword to bind and unbind events at dom level 0, and set the event type to null when unbinding;

            2. Use addEventListener() to bind events at dom level 2, and removeEventListener() to unbind them;

            3. Dom level 0 events cannot be appended to events of the same type. Appending is overwriting.

            4.Dom level 2 events can be appended with events of the same type and executed sequentially after appending.

Prevent event default behavior         preventDefault()

<!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>
    <script>
        window.onload = function () {
            var input = document.querySelector('input');
            var a = document.querySelector('a');
            // 阻止默认行为 preventDefault()
            input.onclick = function () {
                event.preventDefault();
            }
            a.onclick = function () {
                event.preventDefault();
            }
        }
    </script>
</head>

<body>
    <form action="text.php">
        <input type="submit" value="提交">
    </form>
    <a href="https://www.baidu.com">百度</a>
</body>

</html>

event delegation

In JavaScript, the number of event handlers on a page is directly related to the overall performance of the page. there are many reasons. First of all, each function is an object and takes up memory space. The more objects there are, the worse the performance. Secondly, the number of DOM visits required for a given event handler will cause an initial delay in the entire page interaction. You can improve page performance by just paying a little more attention when using event handlers.

Event delegation is to delegate what needs to be done to the parent element (or the parent element's parent element) when an event is triggered. That is to say: use the principle of bubbling to add events to the parent, and perform corresponding operations by determining the subset of event sources. Using event delegation technology allows you to avoid adding event listeners to specific each node.

Event delegation leverages event bubbling, allowing you to use only one event handler to manage one type of event. For example, click events bubble up to document. This means that you can specify an onclick event handler for the entire page, rather than specifying separate event handlers for each clickable element.

<!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>
    <script>
        window.onload = function(){
            var ul = document.querySelector('ul');
            // 在这里加的li可以变色
            // var newLi = document.createElement('li');
            // newLi.innerText = '第11个li';
            // ul.appendChild(newLi);
            // var lis = document.querySelectorAll('li');
            // for(var i=0;i<lis.length;i++){
            //     lis[i].onclick = function(){
            //         this.style.backgroundColor = 'red';
            //     }
            // }
            // 在这里加的li不可变色
            var newLi = document.createElement('li');
            newLi.innerText = '第11个li';
            ul.appendChild(newLi);

            // 事件委托,将子元素事件代理给父元素 绑定依次事件 管理一类事件
            ul.onclick = function(){
                // event 事件对象 event.target
                event.target.style.backgroundColor = 'red';
            }
        }
    </script>
</head>
<body>
    <ul>
        <li>第1个li</li>
        <li>第2个li</li>
        <li>第3个li</li>
        <li>第4个li</li>
        <li>第5个li</li>
        <li>第6个li</li>
        <li>第7个li</li>
        <li>第8个li</li>
        <li>第9个li</li>
        <li>第10个li</li>
    </ul>
</body>
</html>

 Event delegation (event proxy)

            Using event bubbling, you can manage a certain type of event by specifying only one event handler.

            Bind the child element's event to the parent element

            Purpose: Optimize page performance, reduce event execution, reduce browser rearrangement and reflow, and bind events to new elements.

event type

User interface events--UIEvent

Focus event--FocusEvent

Mouse event--MouseEvent

<!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;
            border: 1px solid blue;
            overflow: auto;
        }
    </style>
    <script>
        window.onload = function(){
            var input = document.querySelector('input');
            // select事件  在输入框中选择字符时触发
            input.onselect = function(){
                console.log('我被选择了');
                console.log(window.getSelection().toString());
            }

            // resize事件 窗口缩放时触发方法
            document.body.onresize = function(){
                console.log(window.outerHeight,window.outerWidth);
            }

            // scroll事件 绑定滚动事件
            var div = document.querySelector('div');
            div.onscroll = function(){
                console.log('正在滚动');
            }

            // 聚焦focus 失焦blur
            input.onfocus = function(){
                console.log('选中');
            }
            input.onblur = function(){
                console.log('取消选中');
            }

            // 双击 dblclick
            div.ondblclick = function(){
                console.log('被双击');
            }

            // 鼠标移入mouseenter 移除mouseleave 一直移动mousemove
            div.onmouseenter = function(){
                console.log('鼠标移入');
            }
            div.onmouseleave = function(){
                console.log('鼠标移出');
            }
            div.onmousemove = function(){
                console.log('鼠标一直在移动');
            }
        }
    </script>
</head>
<body>
    <div>我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
        我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
        我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
    </div>
    <input type="text">
</body>
</html>

Keyboard event--KeyboardEvent

<!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>
    <script>
        window.onload = function(){
            var input = document.querySelector('input');
            // 键盘按下事件 keydown 按键keyCode
            input.onkeydown = function(){
                console.log(event.keyCode);
            }
            // 键盘抬起事件 keyup
            input.onkeyup = function(){
                console.log('抬起');
            }
            // 键盘持续按下事件 keypress
            input.onkeypress = function(){
                console.log('持续按下');
            }
            // 输入框输入事件 获取文本输入值
            input.addEventListener('textInput',function(event){
                console.log(event.data);
            })

        }
    </script>
</head>
<body>
    <input type="text">
</body>
</html>

BOM

Page jump Window.open()

 open opens the page parameter url name configurable object true opens itself false opens a new window

The window.open() method can be used to navigate to a specified URL or to open a new browser window. This method accepts 4 parameters: the URL to load, the target window, an attribute string, and a Boolean value indicating whether the new window should replace the currently loaded page in the browser history. Usually, only the first three parameters are passed when calling this method, and the last parameter is only used when not opening a new window.

parameter
URL

Optional. Opens the URL of the specified page. If no URL is specified, a new blank window opens.

name

Optional. Specify the target attribute or the name of the window. The following values ​​are supported:

  • _blank - URL loads into a new window. This is the default

  • _parent - URL loaded into parent frame

  • _self - URL to replace the current page

  • _top - URL replacement for any loadable frameset

  • name - window name

<!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>
    <script>
        window.onload = function(){
            var btn1 = document.querySelectorAll('button')[0];
            var btn2 = document.querySelectorAll('button')[1];
            btn1.onclick = function(){
                // open 打开页面 参数 url name 可配置对象 true自身打开 false 新窗口打开
                w = window.open('https://www.baidu.com','_blank','height = 600px,width = 600px');
                // 设置新窗口的宽高 resizeTo()
                w.resizeTo(400,400);
                // 设置新窗口的位置 moveTo()
                w.moveTo(100,100);
            }
            btn2.onclick = function(){
                // 关闭窗口
                w.close();
            }
        }
    </script>
</head>
<body>
    <button>百度页面</button>
    <button>关闭页面</button>
</body>
</html>

System dialog box

Using the alert(), confirm(), and prompt() methods, you can let the browser call the system dialog box to display messages to the user. These dialog boxes have nothing to do with the web page displayed in the browser, and they do not contain HTML. Their appearance is determined by the operating system or browser and cannot be set using CSS. In addition, these dialog boxes are synchronous modal dialog boxes, that is, code execution will stop when they are displayed, and code execution will not resume until they disappear.

alert()

alert() receives a string to be displayed to the user. Unlike console.log, which can receive any number of parameters and print them all at once, alert() only receives one parameter. When alert() is called, the passed string is displayed in a system dialog box. The dialog box has only one "OK" button. If the parameter passed to alert() is not a raw string, the value's toString() method will be called to convert it to a string.

Warning boxes (alerts) are usually used to display messages to users that they have no control over, such as error reports. The user's only option is to close the warning box after seeing it.

confirm()

The confirmation box is displayed by calling confirm(). Confirmation boxes are similar to warning boxes in that they both display messages to the user. But the difference is that the confirmation box has two buttons: "Cancel" and "OK". Users indicate what action they want to take next by clicking different buttons. For example, confirm("Are you sure?");

To know whether the user clicked the OK button or the Cancel button, you can determine the return value of the confirm() method: true means the OK button was clicked, false means the Cancel button was clicked or the confirmation was turned off by clicking the X icon in a corner. frame.

prompt()

Prompt box, displayed by calling prompt() method. The purpose of the prompt box is to prompt the user to enter a message. In addition to the OK and Cancel buttons, the prompt box also displays a text box for the user to enter content. The prompt() method receives two parameters: the text to be displayed to the user, and the default value of the text box (which can be an empty string). Call prompt("What's your name?"). If the user clicks the OK button, prompt() will return the value in the text box. If the user clicks the Cancel button, or the dialog box is closed, prompt() will return null.

<!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>
    <script>
        window.onload = function(){
            // 弹框 alert()
            alert('弹框');
            // 确认框 confirm()
            var res = confirm('你确定么?')
            if(res){
                console.log('确定');
            }else{
                console.log('取消');
            }
            // 输入框 prompt()
            var res = prompt('请输入你的姓名');
            console.log(res);
        }
    </script>
</head>
<body>
    
</body>
</html>

location

The location object is one of the most useful BOM objects, providing information about the document loaded in the current window and also providing some navigation functions.

Location is a magical object, which is both a window object and a document object. After our comparison, we found that it is also possible to use the location object directly.

Attributes

host returns the server name and port number

hostname returns the server name without the port number

href returns the full URL of the currently loaded page

pathname returns the directory and file name of the URL

port returns the port number specified in the URL

protocol returns the protocol used by the page

search returns the query string of the URL. This string starts with a question mark

method
assign()

Pass a url parameter, open the new url, and generate a record in the browsing history.

replace()

The parameter is a url, which will cause the browser location to change, but will not generate a new record in the history.

reload()

Reload the currently displayed page. The parameter can be of boolean type and defaults to false, which means reloading in the most efficient way, possibly directly from the cache. If the parameter is true, force a reload from the server.

<!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>
    <script>
        window.onload = function(){
            console.log(location.href);
            console.log(location.host);
            console.log(location.hostname);
            console.log(location.protocol);
            console.log(location.port);

            var btn1 = document.body.children[0];
            var btn2 = document.body.children[1];
            var btn3 = document.body.children[2];
            btn1.onclick = function(){
                // assign() 页面跳转 参数:url 会在浏览器中生成一条历史记录
                location.assign('./2-测试页面.html');
            }
            btn2.onclick = function(){
                // replace() 页面跳转 替换页面 参数:url  不会在浏览器中生成历史记录
                location.replace('./2-测试页面.html')
            }
            btn3.onclick = function(){
                // reload()  刷新页面 参数:默认是false请求缓存资源   true强制从服务器请求数据
                // 小刷和大刷区别   
                // 小刷f5刷新文档 请求浏览器缓存资源
                // 大刷 请求服务器资源
                location.reload();
            }
        }
    </script>
</head>
<body>
    <button>跳转页面</button>
    <button>替换页面</button>
    <button>刷新页面</button>
</body>
</html>

Property output:

 Method jump

The difference lies in whether to generate history records. Assingn() can go forward and backward, but replace() cannot.

history

  This object saves the user's online history. For security reasons, developers cannot know the URLs that users have browsed. However, through the list of pages that users have visited, they can also go back and forward without knowing the actual URLs. Note: There is no application to the History object. Public standard, but all browsers support this object.

length

Returns the number of URLs in the history list. Note: Internet Explorer and Opera start at 0, while Firefox, Chrome, and Safari start at 1.

back()

Load the previous URL in the history list

forward()

Load the next URL in the history list

go()

Load a specific page in the history list. A negative number means jumping backward, and a positive number means jumping forward.

Intermittent calls and timeout calls

JavaScript is a single-threaded language, but code execution can be scheduled at specific times through timeout values ​​and interval times.

setTimeout()

This method returns a numeric ID that represents the timeout call. This timeout call ID is a unique identifier of the planned execution code through which the timeout call can be canceled. You can pass clearTimeout(ID);

parameter:

1. The code to be executed 2. The time in milliseconds.

For example, execute the output statement after 1 second

<script>
  var id = setTimeout(() => {
    console.log('Hello World');
  }, 1000);
  console.log(id);
  // 清除超时调用
  clearTimeout(id);
</script>
setInterval()

Repeats code execution at specified intervals until the intermittent call is canceled or the page is unloaded. Calling this method will also return an intermittent call ID, which allows the user to cancel the intermittent call at some point in the future.

parameter:

1. The code to be executed 2. The time in milliseconds.

Such as dynamically displaying time

<script>
  var div = document.createElement('div');
  // 间歇调用
  var id = setInterval(() => {
    div.innerHTML = new Date().toLocaleString();
  }, 1000);
  document.body.appendChild(div);
  // 清除计时器
  clearInterval(id);
</script>

Guess you like

Origin blog.csdn.net/qq_53866767/article/details/131564347