Baidu Front-end Technical College 2017 - Custom Right-click Menu

Keywords: IE Attribute

Reprinted from: http://www.jianshu.com/p/731488a8a3e6

Effect preview

I. Event Flow

1. Bubble

  • What is event bubbles
    The official definition is from the most specific event target to the least specific event target.
    That is to say, if a user clicks on an element and the element has a click event, the same event will be triggered by its ancestors. This event bubbles from the element to the top of the DOM tree. This process is called event bubbles.

Example:

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Custom right-click menu</title>
</head>
<body>
    <ul id='menu'>
        <li>menu item 1</li>
        <li>menu item 2</li>
    </ul>
</body>
</html>

js

document.oncontextmenu =function (){
    alert('Triggered);
}

Effect

2. Capture

  • What is event capture
    Event capture is the opposite of an event, that is, when an event is triggered by a user, the event starts at the top of the DOM tree until it is captured to the event source.

Standard ways of listening for events (standard browsers are available, IE9 or more)

    element.addEventListener(eventType, fn, false)
Explain:
  • The first parameter: eventType: Event type
  • Second parameter: callback function triggered by fn
  • The third parameter: a Boolean value indicating whether bubbles or captures. false means bubbles, true means capture

Interception Events under IE (IE proprietary)

· attachEvent(eventType,fn). IE is proprietary.

Explain:

Only bubbles are not captured in this way.

Be careful:
  • Standard monitoring method does not need to add on

       document.addEventlistener('contextmenu',function (){
       alert('I'm the standard. I don't need it. on')
     },false)
  • IE's way of monitoring events must be added on

    document.attachEvent('contextmenu',function(){
             alert('I am IE I need on')
    })

Generally use the standard, if it is compatible with IE 8 or below, then consider the second, do compatible writing.

oncontextmenu

It belongs to mouse event, triggered by right click of mouse.

Usage:

I bound this event on the document and triggered it through the event bubbling mechanism.

document.oncontextmenu =function (){
    alert('Triggered);
}

3. Event object event

Concept:

Event objects represent the state of events, such as the elements in which events occur, the state of keyboard keys, the position of the mouse, and the state of mouse buttons.
Events are usually used in conjunction with functions, which are not executed before events occur.

  • First parameter in standard browser as event callback function
        document.addEventlistener('contextmenu',function(ev){
             alert(ev)
    })
  • Low version IE as an attribute of window object
        document.attachEvent('contextmenu',function(){
             alert(window.event)
    })

Generally, if it is not compatible with ie 8 or below, use event under the standard.

4. Cancel Default Behavior

event.preventDefault()

5. Preventing bubbles

event.stopPropagation()

Explain:

return false can prevent default behavior as well as bubbles

6. Obtain rolling distance

  • chrome:

document.body.scrollTop(scrollLeft)

  • Non chrome:

document.documentElement.scrollTop(scrollLeft)

  • Compatible Writing:
      var scrollTop = document.documentElement.scrollTop||document.body.scrollTop,
        var scrollLeft = document.documentElement.scrollLeft||document.body.scrollLeft,

7,clientX(Y)

It provides the horizontal coordinates (different from page coordinates) of the application client area when an event occurs. For example, when you click on the upper left corner of the client area, the clientX value of the mouse event is 0, which is independent of whether the page scrolls horizontally.

That is, the distance to the browser's visual window (excluding the browser's toolbar)

8. Obtain the specific dimensions of elements

  • offsetHeight/offsetWidth

Typically, offset Height is a measure of an element, including its borders, vertical (horizontal) inner margins, horizontal (vertical) scrollbars (if present and rendered) and CSS height (width) of the element.

Be careful:

The difference from clientWidth/clientHeight is `clientWidth/clientHeight'. The width (height) of the vertical (horizontal) scrollbar and the border are not included.

9. Getting the Size of Viewport of Browser

    var   browserHeight = document.documentElement.clientHeight,//Height of Viewport of Browser
                    browserWidth = document.documentElement.clientWidth;
Be careful:

Initially, window.innerWidth/window.innerHeight was used to obtain the viewport size, and the result was covered partly by the scroll bar in the extreme case. Later, it was found that window.innerWidth/window.innerHeight included the scroll bar as well.

10. Converting Class Array to Array

Array. prototype. slice. call (class array, 0)

11. Implementing Thought of Customizing Right-click Menu

1. Make the custom menu absolutely positioned relative to the browser viewport by changing the left/top value to change the position of each menu.
2. Cancel the default behavior of the original right-click menu
3. Considering the limit case, determine whether the offsetWidth/event.clientY+offsetHeight of event.clientX+menu is greater than or equal to document.documentElement.clientWidth/document.documemtElement.clientHeight. If it is greater than or equal, assign left/top to offsetWidth/event.clientY-menu offsetHeight of event.clientX-menu, otherwise assign event.clientX/event.clientY-menu offsetHeight.

js code:
    window.onload = function (){
  var oClick = document.getElementById('click_region'),
      oMenu = document.getElementById('menu'),
      aLi = oMenu.getElementsByTagName('li'),
      browserHeight = document.documentElement.clientHeight,//Height of Viewport of Browser
      browserWidth = document.documentElement.clientWidth; //Fast reading of browser viewport, excluding the width of vertical scroll days

  document.oncontextmenu = function (ev){
    oMenu.style.display = 'block';
    var ev = ev||window.event,
        scrollTop = document.documentElement.scrollTop||document.body.scrollTop,
        scrollLeft = document.documentElement.scrollLeft||document.body.scrollLeft,
        clientX = ev.clientX,
        clientY = ev.clientY,
        // Note: Only when the hidden element becomes display:block can its width and height be obtained.
        offsetWidth = oMenu.offsetWidth,
        offsetHeight = oMenu.offsetHeight,
        top,
        left;

    if(clientY+offsetHeight>=browserHeight){
       top = clientY-offsetHeight
    }else{
      top = clientY
    }

    if(clientX+offsetWidth>=browserWidth){
      left = clientX-offsetWidth
      console.log(left);
    }else{
      left = clientX
    }

    oMenu.style.left = left+'px';
    oMenu.style.top =scrollTop+top+'px';
    return false//Prevent default behavior and bubbles
  }

  // Cancel custom menu
  document.onclick = function (){
      oMenu.style.display = 'none';
  }

    var lis = Array.prototype.slice.call(aLi,0); //Converting class arrays to arrays


    //foreach
    lis.forEach(function (item,index,arr){
      aLi[index].onclick = function (event){
        alert(this.innerHTML)
         event.stopPropagation();
      }
    })

}
In the process of learning the front-end, I have collated a lot of information, but also hope to share it to help more students who have just contacted or recently contacted the front-end. However, in order to control the quality of Weixin group, the group must be a small front-end partner. When I join the group, I will send the information to everyone, and every day I will select the front-end high-quality articles and send them to the group for everyone to learn. Want to join the students can add Wechat: iamaixiaoxiao, pull you into the group. Again, to ensure the quality of the group, the group does not add front-end, please forgive me. Scanning Wechat 2-D codes is also possible.

Posted by user___ on Fri, 05 Apr 2019 20:09:30 -0700