js event advanced

1. Event basis

1. Event function

  • When an event is triggered, the function called is the event function
function fn() {
    console.log('I did');
}

div.onclick = fn; // fn is an event function

fn(); // fn is not an event function

2. Event object

  • Event object: when an event occurs, some information related to the event is saved in a global object, which is the event object.
  • IE and Google: global event objects
  • Standard browser: first parameter of event function
  • Compatibility: for IE9 and above, use the first parameter of the event function, while for IE8 and below, use the global event
    • var ev = ev || event;
var box = document.getElementById('box');

box.onclick = function (ev) {
    // console.log(event); // IE and Google
    // console.log(ev); //  Other standard browsers
    var ev = ev || event;
    console.log(ev); // Event object is compatible. It is an object, and you can get a lot of things from it

    console.log(ev.type); // Event type

    console.log(ev.target); // Event source for standard browser
    console.log(ev.srcElement); // Event source for IE
    var target = ev.target || ev.srcElement; // Event source compatibility
    target.style.backgroundColor = 'green';

    console.log(ev.clientX, ev.clientY); // The position of the mouse relative to the viewing area when the event occurs
    console.log(ev.pageX, ev.pageY); // The position of the mouse relative to the document when the event occurs (not supported by IE8 and below)

    console.log(ev.shiftKey); // Is the shift key pressed when the event occurs
    console.log(ev.ctrlKey); // Is the ctrl key pressed when the event occurs
    console.log(ev.altKey); // Is the alt key pressed when the event occurs
}

2. Event binding and cancellation

1. Event binding

  • Format: element. Addeventlistener (do not use on event name, function, capture or not);
  • Format: element. Attachevent (name of event to be on, function);
<div id="box"></div>

<script>
    // Requirement: bind multiple event handling functions to the same event of the same element

    var box = document.getElementById('box');
    function fn1() {
        console.log(1);
        // console.log(this === window);
    }
    function fn2() {
        console.log(2);
    }

    // -----------------------------------------
    // The writing method of assignment, and the later overwrites the previous
    box.onclick = fn1;
    box.onclick = fn2;

    // -------------------------------------------------
    // Listener listening
    // Element. Addeventlistener (do not use on event, function, capture or not); Not supported for IE8 and below
    // The third parameter is false by default. true is capture and fasle is bubbling
    box.addEventListener('click', fn1, false);
    box.addEventListener('click', fn2, false);

    // -------------------------------------------------
    // Attach attach
    // Element. Attachevent (event with on, function); IE8 and below support
    // Only bubbling
    box.attachEvent('onclick', fn1);
    box.attachEvent('onclick', fn2);

    // --------------------------------------------
    // Difference: Understanding
    // The difference between event binding of standard browser and ie browser:
    // ● ie no capture, standard capture
    // ● the event name of ie is preceded by on, but the standard is not
    // ● standards shall be executed in positive order and IE shall be executed in reverse order
    // ● this of ie is window. The standard is the object that triggers this event

    // -------------------------------------
    // Compatibility principle: browser capability judgment
    // Return the function in the standard browser, and return undefined in IE8 and below
    // console.log(box.addEventListener); 
    if (box.addEventListener) {
        box.addEventListener('click', fn1, false);
        box.addEventListener('click', fn2, false);
    } else {
        box.attachEvent('onclick', fn1);
        box.attachEvent('onclick', fn2);
    }


    // ------------------------------------------
    // Compatible implementation
    // Parameters: element event function
    function bind(ele, attr, callback) {
        if (ele.addEventListener) {
            ele.addEventListener(attr, callback, false);
        } else {
            ele.attachEvent('on' + attr, callback);
        }
    }
    bind(box, 'click', fn1);
    bind(box, 'click', fn2);
</script>

2. Unbind event

Standard browser

  • Format: element. Addeventlistener (do not use on event name, function, capture or not);
  • Unbind: element. Removeeventlistener (do not use on event name, function, capture or not);

IE8 and below

  • Format: element. Attachevent (name of event to be on, function);
  • Unbound: element. Detachevent (name of event to be on, function);
<div id="box"></div>

<script>
    // Requirement: bind multiple event handling functions to the same event of the same element

    var box = document.getElementById('box');
    function fn1() {
        console.log(1);
    }
    function fn2() {
        console.log(2);
    }

    // -----------------------------------------
    // The writing method of assignment, and the later overwrites the previous
    box.onclick = fn1;
    box.onclick = null;

    // -------------------------------------------------
    // Listener listening
    // Element. Addeventlistener (do not use on event, function, capture or not); Not supported for IE8 and below
    // Element. Removeeventlistener (event not on, function, capture or not);

    box.addEventListener('click', fn1, false);
    box.addEventListener('click', fn2, false);
    box.removeEventListener('click', fn2, false);

    // -------------------------------------------------
    // Attach attach detach
    // Element. Attachevent (event with on, function); IE8 and below support
    // Element. Detachevent (event with on, function);

    box.attachEvent('onclick', fn1);
    box.attachEvent('onclick', fn2);
    box.detachEvent('onclick', fn2);


    // ------------------------------------------
    // Compatible implementation
    // Add binding, parameters: element event function
    function bind(ele, attr, callback) {
        if (ele.addEventListener) {
            ele.addEventListener(attr, callback, false);
        } else {
            ele.attachEvent('on' + attr, callback);
        }
    }
    
    // Unbound, parameter: element event function
    function unbind(ele, attr, callback) {
        if (ele.removeEventListener) {
            ele.removeEventListener(attr, callback, false);
        } else {
            ele.detachEvent('on' + attr, callback);
        }
    }

    bind(box, 'click', fn1);
    bind(box, 'click', fn2);
    unbind(box, 'click', fn2);
</script>

3. DOM event flow

1. Event flow

  • Event flow: when an event occurs, the event will propagate between the root node and each element node in a certain order. The nodes passing through will trigger the corresponding event.

  • The event flow is divided into three stages:

    • 1. Capture phase: event propagation is from the least specific event target to the most specific event target. That is, from the root to the leaf of the DOM tree. document - html - body - box1 - box2 - box3

    • 2. In the target phase: determine the specific element that triggers the event by capturing. At target stage

    • 3. Bubbling stage: event propagation is from the most specific event target to the least specific event target. That is, from the leaves to the roots of the DOM tree. box3 - box2 - box1 - body - html - document

      When an event passes through this element, it will be triggered if there is an event bound to the element

<div id="box1">
    <div id="box2">
        <div id="box3"></div>
    </div>
</div>
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');

function fn() {
    console.log(this.id);
}

box1.onclick = fn; // This form of binding is triggered in the bubbling phase
box2.onclick = fn;
box3.onclick = fn;

2. Capture and bubbling

  • Bubbling, the event occurs in the child element, the child element is processed first, and then the child element is passed to the parent element
  • Capture: when an event occurs in a child element, it passes through the parent element first. The parent element processes it first and distributes it to the child element
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');

function fn() {
    console.log(this.id);
}

// Third parameter: capture
// false bubble true capture
box1.addEventListener('click', fn, true);
box2.addEventListener('click', fn, true);
box3.addEventListener('click', fn, true);

// Capture trigger can be set, while bubble trigger is the default

3. Stop bubbling

  • Standard browser: event.stopPropagation();
  • IE browser: event.cancelBubble = true;

Case: secondary menu

<button>Button</button>
<div></div>

<script>
    // div is hidden by default. Click the button to display div. click anywhere on the page to hide div

    // Stop bubbling
    // Propagation Bubble
    // Standard browser: ev.stopPropagation();
    // IE browser: ev.cancelBubble = true;

    var btn = document.querySelector('button');
    var div = document.querySelector('div');


    // Click the button to display the div
    btn.onclick = function (ev) {
        var ev = ev || event;
        // ev.stopPropagation(); //  Standard browser
        // ev.cancelBubble = true; // IE8 and below

        stopPropagation(ev); // Stop bubbling
        div.style.display = 'block';
    }

    // Click anywhere on the page to hide the div
    document.onclick = function () {
        // setTimeout(function () {
        div.style.display = 'none';
        // }, 3000);
    }


    function stopPropagation(ev) {
        if (ev.stopPropagation) {
            // Standard browser
            ev.stopPropagation();
        } else {
            // IE8 and below
            ev.cancelBubble = true;
        }
    }
</script>

4. Event default behavior

Some events, that is, give elements special operations

  • Element. Added event: return false;
  • Element. addEventListener(): ev.preventDefault();
  • Element. attachEvent(): ev.returnValue = false;
var a = document.querySelector('a');

// prevent block 

// Element. Added event: return false;
// Element. addEventListener(): ev.preventDefault();
// Element. attachEvent(): ev.returnValue = false;

a.onclick = function (ev) {
    // return false;

    var ev = ev || event;
    // ev.preventDefault(); //  Standard browser
    // ev.returnValue = false; // IE8 and below
    preventDefault(ev);
}

// Block compatibility of default behavior
function preventDefault(ev) {
    if (ev.preventDefault) {
        ev.preventDefault();
    } else {
        ev.returnValue = false;
    }
}

Case: Customize right-click menu

5. Event delegation

Event delegation: also called event agent, it uses the event bubble principle to specify only one event handler to manage all events of a certain type.

Implementation: add the event to the parent element. When the event occurs, the parent element will find the child element corresponding to the trigger event to process. Benefit: this event still exists for child elements added later.

Benefits:

  • 1. The newly added element also has previous events
  • 2. Improve performance
<ul>
    <li>having dinner</li>
    <li>sleep</li>
    <li>Beat beans</li>
</ul>
<script>
    // Bind a click event to each li and click to change its color

    var ul = document.querySelector('ul');
    var li = ul.querySelectorAll('li');

    // Traditional practice (newly added elements, no previous events)
    for (var i = 0; i < li.length; i++) {
        li[i].onclick = function () {
            this.style.backgroundColor = 'pink';
        }
    }

    // --------------------------------------------
    // Event delegation (event agent)
    // Event delegation is to use event bubbling to specify only one event handler to manage all events of a certain type.
    // Implementation: add the event to the parent element. When the event occurs, the parent element will find the child element corresponding to the trigger event to process. Benefit: this event still exists for child elements added later.

    // Benefits:
    // 1. The newly added element also has previous events
    // 2. Improve performance
    ul.onclick = function (ev) {
        var ev = ev || event;
        var target = ev.target || ev.srcElement; // Event source

        // console.log(target);
        // target.tagName
        if (target.nodeName === 'LI') {
            target.style.backgroundColor = 'green';
        }
    }


    // Create one and add it
    var item = document.createElement('li');
    item.innerHTML = 'I'm Doudou';
    ul.appendChild(item);

</script>

6. Keyboard events

1. Keyboard events

  • onkeydown keyboard press
  • onkeyup keyboard lift

Triggered on elements that can respond to user input (form elements and document s can respond to keyboard events)

var input = document.querySelector('input');

// Press
input.onkeydown = function () {
    console.log(this.value);
}

// lift
input.onkeyup = function () {
    console.log(this.value);
}

2. Event object for keyboard events

var input = document.querySelector('input');

// Keyboard press
input.onkeydown = function (ev) {
    var ev = ev || event;
    // console.log(ev); //  Keyboard event object


    console.log(ev.key); // Specific keys (not supported for IE8 and below)
    console.log(ev.keyCode); // Key code 
    // a: 65 z:90 carriage return: 13 space: 32 ESC: 27

    console.log(ev.shiftKey); // shift pressed
    console.log(ev.ctrlKey); // ctrl pressed
    console.log(ev.altKey); // Is alt pressed
}	

7. Wheel event

Standards and IE:

  • Event: onmousewheel
  • Direction: ev.wheelDelta up: 120 down: - 120

Firefox:

  • Event: DOMMouseScroll must be bound with addEventListener
  • Direction: ev.detail up: - 3 down: 3
<div id="box"></div>

<script>
    // Demand: roll the roller in the box, roll down, increase the height, roll up, and decrease the height

    var box = document.getElementById('box');
    var h = box.clientHeight; // Gets the height of the element
    // console.log(h);

    function fn(ev) {
        var ev = ev || event;
        if (wheelDelta(ev) > 0) {
            // Up
            h--;
        } else {
            // down
            h++;
        }
        box.style.height = h + 'px';
    }

    bind(box, 'mousewheel', fn); // IE and standard browser
    bind(box, 'DOMMouseScroll', fn); // Firefox

    // Roller direction compatible up: 120 down: - 120
    function wheelDelta(ev) {
        if (ev.wheelDelta) {
            // IE and standard browser
            return ev.wheelDelta; // Up: 120 down: - 120
        } else {
            // Firefox
            return -40 * ev.detail; // Upper: - 120 lower: - 120
        }
    }

    function bind(ele, attr, callback) {
        if (ele.addEventListener) {
            ele.addEventListener(attr, callback, false);
        } else {
            ele.attachEvent('on' + attr, callback);
        }
    }
</script>

Tags: Javascript html5 html

Posted on Wed, 29 Sep 2021 13:54:08 -0400 by detrox