Bubbling and capture events

DOM after the incident, the spread (propagation) between the current and parent nodes.

Event propagation divided into three stages according to the propagation order. Event.prototype.eventPhase corresponding to three states:

  Phases = const {
     . 1: 'Capture', // capture 
    2: 'target',    // target 
    . 3: 'Bubble'    // bubbling 
  }

A. Event propagation phase

1. capture phase

Events in the window-> document (window.document) -> html (window.documentElement)

-> body (document.body) -> parent node -> the current node (target) sequence is transmitted

The corresponding monitor function is as follows:

element.addEventListener = function(type, function(e) {
   // TODO
}, true);  

2. Phase goal

When the trigger corresponding node is currently listening node.

Regardless third parameter of addEventListener is true or false, it will trigger execution.

3. bubbling phase

Events in the target-> parent -> document-> window delivery order> body-> html-.

Event html tags on [event] attributes and dom object on [event] methods are listening bubbling phase.

Example:

<body>
  <div id="container">
    <div id="root">
      <button id="btn">ClickMe</button>
    </div>    
  </div>

<script>  
  const phases = {
    1: 'capture',
    2: 'target',
    3: 'bubble'
  }
  container.addEventListener('click', function(e) {
    console.log('container->',phases[e.eventPhase]);
  },true);
  container.addEventListener('click', function(e) {
    console.log('container->',phases[e.eventPhase]);
  },false);
  root.addEventListener('click', function(e) {
    console.log('root->',phases[e.eventPhase]);
  },true);
  root.addEventListener('click', function(e) {
    console.log('root->',phases[e.eventPhase]);
  },false);
  btn.addEventListener('click', function(e) {
    console.log('btn->',phases[e.eventPhase]);
  }, true)
  btn.addEventListener('click', function(e) {
    console.log('btn->',phases[e.eventPhase]);
  }, false)
</script> 

operation result:

// 当单击button时
container->capture
root->capture
btn->target
btn->target
root->bubble
container->capture

// 当单击root时
container->capture
root->target
root->target
container->bubble

// 当单击container时
container->target
container->target

II. Related methods of dissemination events

1. event.stopPropagation()

Stop up / down spread; but you can also listen on the same event.

// incident spread element to element, it is no longer down spread 
element.addEventListener ( 'the Click', function (Event) { 
  that event.stopPropagation (); 
}, to true ); 

// incident bubbling element to element, no longer bubble up the 
element.addEventListener ( 'the Click', function (Event) { 
  that event.stopPropagation (); 
}, to false );

Example:

  <div id="container">
    <div id="root">
      <button id="btn">ClickMe</button>
    </div>    
  </div>
<script>  
  const phases = {
    1: 'capture',
    2: 'target',
    3: 'bubble'
  }
  container.addEventListener('click', function(e) {
    console.log('container->',phases[e.eventPhase]);
  },true);
  container.addEventListener('click', function(e) {
    console.log('container->',phases[e.eventPhase]);
  },false);
  root.addEventListener('click', function(e) {
    event.stopPropagation(); // 停止传播
    console.log('root->',phases[e.eventPhase]);
  },true);
  root.addEventListener('click', function(e) {
    console.log('root->',phases[e.eventPhase]);
  },false);
  btn.addEventListener('click', function(e) {
    console.log('btn->',phases[e.eventPhase]);
  }, true)
  btn.addEventListener('click', function(e) {
    console.log('btn->',phases[e.eventPhase]);
  }, false)
</script> 
View Code

Results are as follows:

// Click btn 
Container-> Capture 
root -> Capture 

// click root 
Container-> Capture 
root -> target 
root -> target   // will not intercept the target node event triggered multiple times

2. event.stopImmediatePropagation()

Stop event propagation, and stop event listener the same event again

element.addEventListener('click', function (event) {
  event.stopImmediatePropagation();
  console.log(1);
});

element.addEventListener('click', function(event) {
  // 不会被触发
  console.log(2);
});

Examples

<body>
  <div id="container">
    <div id="root">
      <button id="btn">ClickMe</button>
    </div>    
  </div>
<script>  
  const phases = {
    1: 'capture',
    2: 'target',
    3: 'bubble'
  }
  container.addEventListener('click', function(e) {
    console.log('container->',phases[e.eventPhase]);
  },true);
  container.addEventListener('click', function(e) {
    console.log('container->',phases[e.eventPhase]);
  },false);
  root.addEventListener('click', function(e) {
    event.stopImmediatePropagation(); // 立即停止传播
    console.log('root->',phases[e.eventPhase]);
  },true);
  root.addEventListener('click', function(e) {
    console.log('root->',phases[e.eventPhase]);
  },false);
  btn.addEventListener('click', function(e) {
    console.log('btn->',phases[e.eventPhase]);
  }, true)
  btn.addEventListener('click', function(e) {
    console.log('btn->',phases[e.eventPhase]);
  }, false)
</script> 
View Code

Results are as follows:

// Click btn 
Container-> Capture 
root -> Capture 

// click root 
Container-> Capture 
root -> target // target node can only be triggered once an event

3. event.preventDefault()

Cancel the browser's default behavior for the current event. This method is effective provided that the cancelable property of the event was true.

All browsers and some sub-events (click, mouseover, etc.) This property is true;

Custom event default cancelable property is false, you need to manually set to true.

const event = new Event('myevent', {cancelable: true})

Event's default behavior common are:

1) typing the input, the input data will be displayed in the text box;

    By keypress event listener can stop text input, so you can not enter.

2) Click the radio button / check box, select the effect will appear;

    A click event listener can uncheck behavior, so that can not be selected.

3) Click on the link <a> label, there will be a jump;

    A click event listener can cancel the jump behavior, so that can not jump.

4) Space key to scroll down the page;

Example:

<!--
 * @Author: LyraLee
 * @Date: 2019-10-30 08:53:28
 * @LastEditTime: 2019-11-11 18:48:19
 * @Description: preventDefault()
 -->
<!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>串行异步操作</title>
  <style>
    body{
      height: 2000px;
    }
  </style>
</head>
<body>
  <input id="checkboxElement "type =" CheckBox "/> 
  <a id="toBaidu" href="http://www.baidu.com"> jump to Baidu </a>
  <INPUT ID = "inputElement" type = "text" /> 
<Script>   
  checkboxElement.addEventListener ( 'the Click', function (E) { 
    e.preventDefault (); // can not select 
  })   
  toBaidu.addEventListener ( 'the Click', function (E) { 
    e.preventDefault (); // can not Skip 
  }) 
  inputElement.addEventListener ( 'KeyPress', function (E) { 
    the console.log (E); 
    IF (e.charCode <e.charCode 97 || > 122 ) { 
      e.preventDefault (); // typed characters only AZ 
      Alert ( 'only lowercase Letters' );
    }
  }) 
  Document.body.addEventListener ( 'KeyPress', function (E) {
     IF (e.charCode === 32) { // is spacebar 
      e.preventDefault (); // slid down the page space to prevent 
    } 
  } )
 </ Script> 
</ body> 
</ HTML>
View Code

4. event.composedPath()

Returns an array members are all paths to the destination node bubbling window node.

Example:

<body>
  <div id="container">
    <div id="second">
      <div id='bottom'>
        ClickMe
      </div>
    </div>
  </div>
<script>  
  bottom.addEventListener('click', function(e) {
    console.log(e.composedPath()); 
    //[div#bottom, div#second, div#container, body, html, document, Window]
  },false)
</script> 

III. Events dissemination of relevant attributes

1. read-only attribute

1. event.eventBubbles

Return value: boolean; indicates whether bubbling

Native browser default events are true, can bubble;

By Event constructor, custom event default is false, not bubbling, need to manually set.

const event = new Event('lyra', {bubbles: true})

2. event.eventPhase

Returns: Digital 0-3; indicates the current phase in which the propagation of the current event.

0 : Event not occurred
 1 : Event Capture Stage
 2 : Target Stage
 3: Event bubbling phase

3. event.cancelable

Return value: boolean; indicates whether the default behavior can be canceled.

Native browser default events are true, you can cancel, you can call event.preventDefault () method;

By Event constructor, custom event default false, in order to invoke the need to manually set event.preventDefault ();

const event = new Event('lyra', { cancelable: true})

application:

Use can be used as preventDefault () method preconditions

  <input id="enter" type="text" />
  <script>
    enter.addEventListener('keypress', function(e) {
      if(e.cancelable) {
        e.preventDefault();
      }else {
console.warn('can not be cancelled')
} })
</script>

4. event.defaultPrevented

Return value: boolean; indicating whether it's called preventDefault () method

5.event.currentTarget

Returns: the listener element event bindings; equivalent to this; will not change

6.event.target

Returns: the role of the current element event; changes in real time with the trigger node;

7.event.type

Returns: type of event

8.event.timeStamp

Returns: milliseconds, to complete page load time from event-triggered; represents a timestamp

application:

By the difference between two timestamps mousemove trigger calculates the moving speed of the mouse.

var previousX;
var previousY;
var previousT;

window.addEventListener('mousemove', function(event) {
  if (
    previousX !== undefined &&
    previousY !== undefined &&
    previousT !== undefined
  ) {
    var deltaX = event.screenX - previousX;
    var deltaY = event.screenY - previousY;
    var deltaD = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));

    var deltaT = event.timeStamp - previousT;
    console.log(deltaD / deltaT * 1000);
  }

  previousX = event.screenX;
  previousY = event.screenY;
  previousT = event.timeStamp;
});
View Code

9.event.isTrusted

Return value: boolean; indicates whether the user behavior is triggered, rather than dispatch method of triggering.

General primary event return true; custom event returns false.

10. event.detail

Return Value: event-related information; custom events, the data is returned from the user-defined

Such as: Clicks click event; scroll wheel distance

container.addEventListener ( 'the Click', function (E) { 
  the console.log ( 'Container->' , e.detail); 
}, to true );
 // if you click returns 1 
// if you double-return 2 
// If N consecutive clicks, return N

application:

When you click a node in the event and double-click event to bind the same time, you can use this property.

2. writable property

1. event.cancelBubble

If true, it can prevent the spread of the event; not just stop bubbling, will prevent capture;

= event.cancelBubble to true ; 
 // corresponds to 
that event.stopPropagation ();

IV. Applications

When you need to add more than 1 byte points listen for events

  <! - realization of the mouse after the suspension, to modify the background color in the color notes li -> 
  <UL ID = "Container"> 
    <li> Red </ li> 
    <li> Yellow </ li> 
    <li> Purple < / li> 
    <li> Pink </ li> 
  </ ul> 
  <Script>   // this function should listen for events added to the parent, or need to add four to listen to events 
    container.addEventListener ( 'mouseOver', function (E ) {
       IF (e.target.tagName.toLowerCase () === 'Li' ) { 
        e.target.style.backgroundColor = e.target.innerHTML; 
      } 
    }) 
    container.addEventListener ( 'mouseOut',function (E) { // can not MouseLeave IF
    
       (e.target.tagName.toLowerCase() === 'li') {
        console.log('innner');
        e.target.style.backgroundColor = '#fff';
      } 
    })
  </script> 

2. Add the parent-child nodes simultaneously monitor events

Practical work, for where there is a complex operation, while adding the same situation byte father and son listening to events, but often implement different functions.

Example:

Click on a menu to select the required menu, assign it to a variable id; there is a right of the menu prompt icon, click the pop-up boxes.

Click Prompt icon when required, do not select the menu.

analysis:

Requirements child nodes event does not trigger the listener function parent node; use stopPropagation ();

  <ul id="container">
    <li id="menu1"><span>菜单1...</span><span class="arrow">▶️</span></li>
  </ul>
  <script>  
    let checked;
    menu1.addEventListener('click', function(e) {
      console.log(this.id);
      checked = this.id;
    })
    const arrow = document.querySelector('.arrow');
    arrow.onclick = function(e) { // 相当于addEventListen('click',fn,false)
      e.stopPropagation();)
      console.log ( '- arror ---'stop bubbling, parent listening to events triggered//
    }
  </script> 

 

Guess you like

Origin www.cnblogs.com/lyraLee/p/11839619.html