Two ways to bind events/level of DOM events

We covered the concept of events in our previous article, 04-JavaScript/22-DOM Introduction and DOM Manipulation. Here are two ways to bind (register) events, using the onClick event as an example.

DOM0 is written onclick

    element.onclick = function () {}Copy the code

For example:

<body>
<button>Am I</button>
<script>
    var btn = document.getElementsByTagName("button") [0];

    If there are more than one binding, the last one overwrites the previous one
    btn.onclick = function () {
        console.log("1");
    }

    btn.onclick = function () {
        console.log("Event 2");
    }

</script>
</body>

Copy the code

After clicking the button, the printed result of the code above:

Event 2Copy the code

We can see the DOM object. Event = functions bind events in such a way that only one response function can be bound to an event of an element. If more than one response function is bound, the latter overrides the former.

DOM2: addEventListener (advanced version browser)

    element.addEventListener('click'.function () {},false);
Copy the code

Parameter Description:

  • Parameter 1: String of event name (note, no on)

  • Parameter 2: Callback function: This function is executed when an event is triggered

  • Parameter 3: true indicates capture phase trigger, false indicates bubble phase trigger (default). If not, the default is false. “Important”

For example:

<body>
<button>button</button>
<script>
    var btn = document.getElementsByTagName("button") [0];

    // addEventListener: event listener. When the original event is executed, subsequent events are executed as well
    // There is no overwriting of the response function. (More suitable for team development)
    btn.addEventListener("click", fn1);
    btn.addEventListener("click", fn2);

    function fn1() {
        console.log("1");
    }

    function fn2() {
        console.log("Event 2");
    }

</script>
</body>
Copy the code

After clicking the button, the printed result of the code above:

Event 1 Event 2Copy the code

We can see that addEventListener() binds events:

  • An event of an element that can bind multiple response functions. No response function is overwritten. The order of execution is: when the event is fired, the response function is executed in the order in which the function is bound.

  • This in addEventListener() is the object to which the event is bound.

  • AddEventListener () does not support Internet Explorer 8 and below. AttachEvent can be used to bind events in IE8 (see the next section).

DOM2: attachEvent (Internet Explorer 8 or later)

    element.attachEvent('onclick'.function () {});Copy the code

Parameter Description:

  • Parameter 1: String of event name (note, on)

  • Parameter 2: Callback function: This function is executed when an event is triggered

For example:

    <body>
        <button>button</button>
        <script>
            var btn = document.getElementsByTagName('button') [0];

            btn.attachEvent('onclick'.function() {
                console.log(Events' 1 ');
            });

            btn.attachEvent('onclick'.function() {
                console.log(Events' 2 ');
            });
        </script>
    </body>
Copy the code

On a lower version of Internet Explorer, after clicking the button, the code above prints:

Event 2 Event 1Copy the code

We can see how attachEvent() binds events:

  • An event of an element that can bind multiple response functions. No response function is overwritten. Note: The order of execution is, the last binding is executed first.

  • This in attachEvent() is window

Compatibility writing

In the above content, it should be emphasized that:

  • This in addEventListener() is the object to which the event is bound.

  • This in attachEvent() is window.

Since the two ways of writing this are different, is there a compatible way to ensure that the two binding ways of writing this are the same? We can encapsulate it. The code is as follows:

    <body>
        <button>button</button>
        <script>
            var btn = document.getElementsByTagName('button') [0];

            myBind(btn , "click" , function(){
                alert(this);
            });



            // Define a function that binds the response function to the specified element
            /* * This in addEventListener(), which is the object to bind to the event * attachEvent(), which is the window * Need to unify the two methods this */
            /* * Argument: * Element the object to which the event is bound * eventStr the string of events (not on) * callback callback function */
            function myBind(element , eventStr , callback){
                if(element.addEventListener){
                    // Most browsers are compatible
                    element.addEventListener(eventStr , callback , false);
                }else{
                    /* * Callback. Call (element) */
                    / / IE8 and below
                    element.attachEvent("on"+eventStr , function(){
                        // Call the callback function in the anonymous functioncallback.call(element); }); }}</script>
    </body>
Copy the code

The event object

When the event response function is fired, an event object is produced. Each time the browser passes the event as an argument to the previous response function.

This object contains all information related to the current event. Such as the coordinates of the mouse, which key on the keyboard is pressed, the direction of the mouse wheel, etc.

Getting event objects (Compatibility issues)

All browsers support event objects, but in different ways. As follows.

(1) The common browser is written as event. Such as:

(2) Ie 678 is written as window.event. At this point, the event object is stored as a property of the Window object.

So, we can write it in a compatible way. As follows:

    event = event || window.event; // Compatibility
Copy the code

Code examples:

<! DOCTYPEhtml>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
    // Click any part of the page
    document.onclick = function (event) {
        event = event || window.event; //// Compatible notation

        console.log(event);
        console.log(event.timeStamp);
        console.log(event.bubbles);
        console.log(event.button);
        console.log(event.pageX);
        console.log(event.pageY);
        console.log(event.screenX);
        console.log(event.screenY);
        console.log(event.target);
        console.log(event.type);
        console.log(event.clientX);
        console.log(event.clientY);
    }
</script>
</body>
</html>
Copy the code

The event attributes

The event has many attributes, such as:

Since pageX and pageY are not compatible, we can do this:

  • Mouse position on the page = the distance of the scroll bar + the coordinates of the viewable area.

The Event, for example,

Example 1: Make the div move with the mouse

Code implementation:

<! DOCTYPEhtml>
<html>
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <style type="text/css">
      #box1 {
        width: 100px;
        height: 100px;
        background-color: red;
        /* * Enable the absolute positioning of box1 */
        position: absolute;
      }
    </style>

    <script type="text/javascript">
      window.onload = function() {
        /* * makes div move with mouse */

        / / get box1
        var box1 = document.getElementById("box1");

        // Bind the entire page to the mouse movement event
        document.onmousemove = function(event) {
          // Obtain the event object in a compatible manner
          event = event || window.event;

          // Mouse position on the page = the distance of the scroll bar + the coordinates of the viewable area.
          var pagex = event.pageX || scroll().left + event.clientX;
          var pagey = event.pageY || scroll().top + event.clientY;

          // Set the div offset relative to the entire page.
          // Note that if you want to set properties via style.left, you must enable absolute positioning for box1.
          box1.style.left = pagex + "px";
          box1.style.top = pagey + "px";
        };
      };

      // Scroll function encapsulation
      function scroll() {
        return {
          // The return value of this function is an object
          left: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop,
          right:
            window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft
        };
      }
    </script>
  </head>
  <body style="height: 1000px; width: 2000px;">
    <div id="box1"></div>
  </body>
</html>
Copy the code

Example 2: Obtain the distance between the mouse and the box

Key points:

Mouse distance from box = mouse position on the entire page - box position on the entire pageCopy the code

Code demo:

<! DOCTYPEhtml>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 300px;
            height: 200px;
            padding-top: 100px;
            background-color: pink;
            margin: 100px;
            text-align: center;
            font: 18px/30px "simsun";
            cursor: pointer;
        }
    </style>
</head>
<body>
<div class="box">

</div>

<script src="animate.js"></script>
<script>
    // Requirements: the mouse enters the box as long as the move, even 1 pixel, at any time display the mouse in the box coordinates.
    // Technical point: New event, onMousemove: On the event source, this event will be triggered even if the mouse moves 1 pixel.
    // To some extent, simulate timer
    / / steps:
    //1. Old three steps and new five steps
    //2. Get the mouse position on the entire page
    //3. Get the box position on the entire page
    //4. Assign the contents of the box to the position of the mouse minus the position of the box.

    //1. Old three steps and new five steps
    var div = document.getElementsByTagName("div") [0];

    div.onmousemove = function (event) {

        event = event || window.event;
        //2. Get the mouse position on the entire page
        var pagex = event.pageX || scroll().left + event.clientX;
        var pagey = event.pageY || scroll().top + event.clientY;
        //3. Get the box position on the entire page
        // var xx =
        // var yy =
        //4. Assign the contents of the box to the position of the mouse minus the position of the box.
        var targetx = pagex - div.offsetLeft;
        var targety = pagey - div.offsetTop;
        this.innerHTML = "The x-coordinate of the mouse in the box is:" + targetx + "px; 

The Y coordinate of the mouse in the box is:"
+ targety + "px;" }
</script> </body> </html> Copy the code

Effect:

Example 3: Commercial magnifying glass

Code implementation:

(1) index. HTML:

<! DOCTYPEhtml>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .box {
            width: 350px;
            height: 350px;
            margin: 100px;
            border: 1px solid #ccc;
            position: relative;
        }

        .big {
            width: 400px;
            height: 400px;
            position: absolute;
            top: 0;
            left: 360px;
            border: 1px solid #ccc;
            overflow: hidden;
            display: none;
        }

        /*mask */
        .mask {
            width: 175px;
            height: 175px;
            background: rgba(255.255.0.0.4);
            position: absolute;
            top: 0;
            left: 0;
            cursor: move;
            display: none;
        }

        .small {
            position: relative;
        }

        img {
            vertical-align: top;
        }
    </style>

    <script src="tools.js"></script>
    <script>
        window.onload = function () {
            // Need: mouse over the small box, make the pictures in the big box move in proportion with us.
            // Technical point: onmouseEnter == onmouseOver the first one does not bubble
            // Technical point: onmouseleave==onmouseout the first one does not bubble
            / / steps:
            //1. Mouse up to display the box, and remove the hidden box.
            //2. The old three steps and the new five steps (yellow box follows move)
            //3. Large image on the right, equal scale.

            //0. Get the relevant elements
            var box = document.getElementsByClassName("box") [0];
            var small = box.firstElementChild || box.firstChild;
            var big = box.children[1];
            var mask = small.children[1];
            var bigImg = big.children[0];

            //1. Mouse up to display the box, and remove the hidden box. (Bind events for small boxes)
            small.onmouseenter = function () {
                // Wrap method calls: display elements
                show(mask);
                show(big);
            }
            small.onmouseleave = function () {
                // Encapsulate method calls: hide elements
                hide(mask);
                hide(big);
            }

            //2. The old three steps and the new five steps (yellow box follows move)
            // The bound event is onMousemove and the event source is small(if you move 1 pixel on the small box, the yellow box will follow)
            small.onmousemove = function (event) {
                / / the new five steps
                event = event || window.event;

                // To move the yellow box, you must know where the mouse is in the small diagram.
                var pagex = event.pageX || scroll().left + event.clientX;
                var pagey = event.pageY || scroll().top + event.clientY;

                //x: mask left value, y: mask top value.
                var x = pagex - box.offsetLeft - mask.offsetWidth / 2; // Divide by 2 to ensure the middle of the mouse mask
                var y = pagey - box.offsetTop - mask.offsetHeight / 2;

                // Limit the range of box replacement
                // Left is greater than 0, the width of the small box - the width of the mask.
                if (x < 0) {
                    x = 0;
                }
                if (x > small.offsetWidth - mask.offsetWidth) {
                    x = small.offsetWidth - mask.offsetWidth;
                }
                / / top in the same way.
                if (y < 0) {
                    y = 0;
                }
                if (y > small.offsetHeight - mask.offsetHeight) {
                    y = small.offsetHeight - mask.offsetHeight;
                }

                // Move the yellow box
                console.log(small.offsetHeight);
                mask.style.left = x + "px";
                mask.style.top = y + "px";

                //3. Large image on the right, equal scale.
                // How to move a large image? Equal scale shift.
                // Big picture/big box = small picture /mask box
                // Mask distance = (big picture - big box)/(small picture - yellow box)
// var bili = (bigImg.offsetWidth-big.offsetWidth)/(small.offsetWidth-mask.offsetWidth);

                // Big picture distance /mask box distance = big picture/small picture
                var bili = bigImg.offsetWidth / small.offsetWidth;

                var xx = bili * x;  // If you know the scale, you can move the big picture
                var yy = bili * y;

                bigImg.style.marginTop = -yy + "px";
                bigImg.style.marginLeft = -xx + "px"; }}</script>
</head>
<body>
<div class="box">
    <div class="small">
        <img src="images/001.jpg" alt=""/>
        <div class="mask"></div>
    </div>
    <div class="big">
        <img src="images/0001.jpg" alt=""/>
    </div>
</div>
</body>
</html>
Copy the code

(2) tools. Js:

/** * Created by smyhvae on 2018/02/03. */

// Show and hide
function show(ele) {
    ele.style.display = "block";
}

function hide(ele) {
    ele.style.display = "none";
}

function scroll() {  // Start encapsulating your own scrollTop
    if (window.pageYOffset ! =null) {  // Ie9 + higher version browser
        // Window. PageYOffset is 0 by default
        return {
            left: window.pageXOffset,
            top: window.pageYOffset
        }
    }
    else if (document.compatMode === "CSS1Compat") {    // Standard browsers decide whether to declare a DTD
        return {
            left: document.documentElement.scrollLeft,
            top: document.documentElement.scrollTop
        }
    }
    return {   // No DTD is declared
        left: document.body.scrollLeft,
        top: document.body.scrollTop
    }
}

Copy the code

Effect demonstration: