Understanding Event bubbling model

This article explores what a few small bug Event bubbling process and beginners encounter

DOM Event Overview

Event interfaces are all events detected in the DOM, we have been using, and from an early version of the DOM would have been using. The early Netscape (later Firefox) and IE are fighting each other until the W3C dominate the political arena, DOM version all the way from development, through the DOM-0 (prehistoric times), DOM-1 (core only two chapters), DOM 2 (a version of the landmark, we learn of the Event in this version, but now also used this version), DOM-3, DOM- 4 ( draft stage).

  • Wake understanding through an example of the Event
//1、有一个js函数如下
function print(){
  console.log(1)
}

//2、在html的button里面点击触发上面的函数
<button id=button onclick="?">点我</button>
//问号处填可以填什么 A. print() B.print C.print.call()

//在js里面的onclick里面触发
button.onclick = ?
//问号处可以填什么 A. print() B.print C.print.call()
  • Obviously the first question mark should choose A Cthe second option should be a question markB
  • The first is in HTM, the click event code is to be executed immediately, certainly chose to take (), and the second in the JS, onclick is an attribute that does not require immediate implementation, such as user clicks, and then react browser, no ().

Now onclickand other events on a property in JS, then the latter will overwrite the previous, so DOM2 which introduces an important EventListener, is a queue.

addEventListener

This is a queue, example 1 , the characteristics of the FIFO, to prepare for the following model bubbling.

function f(){
  console.log("eventListener不会覆盖")
}

button2.addEventListener('click', function(){
  console.log("eventListener不会覆盖1")
})
button2.addEventListener('click', f)
button2.removeEventListener('click', f)
button2.addEventListener('click', function(){
  console.log("eventListener不会覆盖3")
})
  • It will print out what answer iseventListener不会覆盖1 eventListener不会覆盖3
  • So now on you can print out a result, it can help removeto achieve onethe implementation of the last operation
function f(){
  console.log("eventListener不会覆盖2")
  button2.removeEventListener('click', f)
}


button2.addEventListener('click', f)

Only printed once , it would not have been printed, which is the oneprinciple.

  • Specific models can be seen W3C

W3C model

Bubble Model

Above the official document, I only look at the capture stage (capture phase) and bubbling phases (bubbling phase).

  • What is bubbling it? We look at a piece of code
grand.addEventListener('click', function(){
  console.log('我是你爷爷')
})
dad.addEventListener('click', function(){
  console.log('我是你爸爸')
})

son.addEventListener('click', function(){
  console.log('我是你儿子')
})
  • These are the three divevents, when you click on the console print there must be order. So what should be the order of it, thinking nothing more than the normal two results

    • The first: I am your son, I am your father I am your grandfather
    • The second: I am your grandfather I am your father I'm your son
    • In the end it is the kind, W3C said all right, see you how to write the code, the code above is the first print order, that is bubbling.

Bubble Sort

  • If you want to implement the second printing mode, that is, the capture phase, should modify the code as follows
grand.addEventListener('click', function(){
  console.log('我是你爷爷')
}, true)
dad.addEventListener('click', function(){
  console.log('我是你爸爸')
}, true)

son.addEventListener('click', function(){
  console.log('我是你儿子')
}, true)
  • That addEventListenerthe latter parameter determines the order when you do not write time it is the undefined, which is the falsemean.
  • Review the five falseyvalues

    • 0 NaN '' null undefined In addition to alltrue

Simple graphic

The figure is a simple illustration, note that the priority for the operation truepart, run falseportion.

Simple example ====================> Demo

  • A variant
grand.addEventListener('click', function(){
  console.log('我是你爷爷')
}, true)
dad.addEventListener('click', function(){
  console.log('我是你爸爸')
})

son.addEventListener('click', function(){
  console.log('我是你儿子')
  • The code should be in what order it

Variants

  • Who is the truefirst print who are false, in accordance with bubbling order to continue printing.

A wonderful question

son.addEventListener('click', function(){
  console.log('我是你儿子true')
}, true)

son.addEventListener('click', function(){
  console.log('我是你儿子false')
})
  • To the same elements false true, what should print it
  • The answer is: in the order written, who is in front of the first printing whom.

Wonderful

Unexpected Bug

parentKeywords can not be used accidentally use the word go wrong.

Unexpected bug

  • Do you use the keyword variables, the mouse can not see the bad effects.

Click the blank dialog box disappears cases

  • Leaders say there is a demand, click a button, pop-up dialog box, click on the blank will disappear.
  • Your first thought: first div is set to none, click the button, let the divthe display is block, click elsewhere becomes none.
  • Well, you go to achieve it.

The first bug

  • Soon you will come across the first bug

    • The first error: the wrong object monitor

Monitor the wrong object

Normally, the body should click on the Print Console number 1, you rotten point your Logitech mouse did not come out. why?

  • 我们使用border大法,看看它到底在哪

body position

使用了红色border之后,发现body的高度太矮了,点击不到啊。

  • 你明白监听错对象了,那你就换了一个对象,监听文档呗,肯定没问题了。

第二个bug

  • 很好,你进入了第二个bug了

    • 第二个bug:你都能点击到,但是弹不出对话框了

The second bug

根据图片 中的控制台可以发现,确实都点击到了,监听没问题,而且点击后,也是按照冒泡的顺序打印的结果。

  • 那为什么没有对话框了呢

normal phenomenon

注释掉出问题的代码后,上图是正常的点击出现对话框啊,说明问题就出在注释的代码上。

  • bug出现的原因就在于:默认冒泡的影响,当你点击的浮层那个div,之后,往 body document上冒泡,在document上立刻被杀死,display变为none,你做梦能看到 弹出框啊。

Stop bubbling

修复第二个bug

我们既然知道了第二个bug产生的原因,那么我们阻止冒泡顺序

  • 解决的方案,不让其往上冒泡,自己管理。
clickMe.addEventListener('click', function(){
  popover.style.display = 'block'
  console.log('点击浮层了') 
})

wrapper.addEventListener('click', function(e){
  e.stopPropagation()
})


document.addEventListener('click', function(){
  popover.style.display = 'none'
  console.log('点击文档了') 
})
  • 但是随之而来的是一个关于内存占用的问题,现在你是只有一个popover,只有一个函数,等你有了很多个popover,如果按照这个写法会有很多个函数,所以不能这么写,采用下面的写法,节省内存。
$(clickMe).on('click', function(){
  $(popover).show()
  console.log('show')
  setTimeout(function(){
    console.log('one click')
    $(document).one('click', function(){
     console.log('我觉的他不会执行')
     $(popover).hide()            
    })
  },0)
  
})
// $(wrapper).on('click', function(e){
//   e.stopPropagation()
// })

$(document).on('click', function(){
  console.log('走到document啦')
})
  • 只有点击的时候才用,设置settimeout是为了让他异步,不至于立刻隐藏,产生第一个bug。
  • 注意一下,jQuery的 show() hide()

jQuery save memory

  • 当你点击按钮,只会打印图中这两句话,另外两句只有再次点击才会打印。

Specific analysis

JS版本的节省内存的版本==================>节省内存

jQuery版本的节省内存版本=================>jQuery节省内存

对话框小三角的制作

.popover{
  display: inline-block;
  border: 1px solid red;
  position: relative;
  padding: 10px;
  margin:10px;
}
.popover::before{
  position: absolute;
  content: '';
  top: 5px;
  right: 100%;
  border: 10px solid transparent;
  border-right-color:red;
}
.popover::after{
  content: '';
  border: 10px solid transparent;
  position: absolute;
  right: 100%;
  top: 5px;
  border-right-color: white;
  margin-right: -1px;
}

主要利用boder-right-color以及两个伪元素。

Examples of floating layers triangle =============================> Demo

Bubbling visual expression

Click there will be surprises https://github.com/codevvvv9/bubble/blob/master/bubble.gif

Take a bubble

Guess you like

Origin www.cnblogs.com/jlfw/p/12054043.html