zoukankan      html  css  js  c++  java
  • js contextmenu 自定义右键菜单

    右键菜单的设定主要是通过contextmenu事件来激活,由于contextmenu事件是冒泡的,所以可以为document来指定事件,进行页面中该事件的统一处理。同时,因为contextmenu是一个鼠标事件,所以在event中包含有鼠标位置等一系列信息,可以通过这个来实现对浏览器右键菜单的模拟。

    为了兼容现在的主流浏览器,所以先做一个通用的事件加载函数:

    1 function eventHandler(dom,type,fn){
    2     if(typeof dom.addEventListener != 'undefined'){
    3         dom.addEventListener(type,fn,false);
    4     }else if(typeof dom.attachEvent != 'undefined'){
    5         dom.attachEvent('on'+type,fn);
    6     }else{
    7         dom['on'+type] = fn;
    8     }
    9 }

    这个函数首先检测是否有addEventListener,有的话就用这个,然后是attachEvent,因为IE中都是用这个来加载监听事件的,特别注意的是事件名前面要加上on,最后如果都不支持的话,就用最原始的方法添加事件。这个事件函数都是在冒泡阶段执行的,主要是考虑到IE和一些浏览器的早期版本对捕获的支持不佳,为了统一效果,就全部放在了冒泡阶段。

    接下来做一个能够检测的页面,主要是检测事件运行是否正常,特别是滚动以后右键菜单的位置

    <html>
    <head>
        <style type="text/css">
            div{
                margin-top:50px;
                margin-bottom: 50px;
            }
        </style>
        <script type="text/javascript">
            function eventHandler(dom,type,fn){
                if(typeof dom.addEventListener != 'undefined'){
                    dom.addEventListener(type,fn,false);
                }else if(typeof dom.attachEvent != 'undefined'){
                    dom.attachEvent('on'+type,fn);
                }else{
                    dom['on'+type] = fn;
                }
            }
        </script>
    </head>
    <body>
        <ul id='myContextMenu' style="padding:0;margin:0;list-style:none;position:absolute;visibility:hidden;background-color:silver;">
            <li>hi</li>
            <li><a href="#">hello</a></li>
        </ul>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
        <div>asdfasf</div>
    </body>
    </html>

    这样就完成了一个足够长的页面,同时做了右键菜单的element,就是那个myContextMenu。接下来就是对contextmenu的设定了。

    1 window.onload = function(){
    2     eventHandler(document,'contextmenu',function(event){
    3         event = event || window.event;
    4         event.preventDefault?event.preventDefault():(event.returnValue = false);
    5     });
    6 }

    首先是取消原有的默认右键事件。考虑到跨浏览器的兼容,就要考虑到IE下是用event.returnValue来取消的,所以写了个语句专门取消这个默认事件。

    接下来就是鼠标的位置了,在其余浏览器中,event下pageX和pageY中就保存了鼠标的位置信息,而且是相对于页面来说的,而不是以窗口client作为参考位置的,可以直接使用来设定右键菜单的位置,但是在IE中,部分版本是不支持pageX和pageY的,就需要用clientX和clientY再加滚动的距离来计算鼠标的位置

    1 var menu = document.getElementById('myContextMenu'),
    2 pageX = event.pageX?event.pageX:(event.clientX+(document.body.scrollLeft||document.documentElement.scrollLeft)),
    3 pageY = event.pageY?event.pageY:(event.clientY+(document.body.scrollTop||document.documentElement.scrollTop));

    在混杂模式下用document.body,在标准模式下用document.documentElement。再加一下style设置就可以完成对右键菜单的设置了。

     1 window.onload = function(){
     2     eventHandler(document,'contextmenu',function(event){
     3         event = event || window.event;
     4         event.preventDefault?(event.preventDefault()):(event.returnValue = false);
     5         var menu = document.getElementById('myContextMenu'),
     6         pageX = event.pageX?event.pageX:(event.clientX+(document.body.scrollLeft||document.documentElement.scrollLeft)),
     7         pageY = event.pageY?event.pageY:(event.clientY+(document.body.scrollTop||document.documentElement.scrollTop));
     8         menu.style.left = pageX+'px';
     9         menu.style.top = pageY+'px';
    10         menu.style.visibility = 'visible';
    11     });
    12 }

    接下来还有一个问题,就是要模拟浏览器的右键菜单,那么必须在点击其它地方后隐藏右键菜单,这个只要在document上加一个click事件就可以了

    1 eventHandler(document,'click',function(event){
    2     document.getElementById('myContextMenu').style.visibility = 'hidden';
    3 })

    click事件触发后,冒泡到document上,用来取消右键菜单的显示,同时也不会影响到其余click事件的处理。

    最后所以的代码集合一下:

     1 <html>
     2 <head>
     3     <style type="text/css">
     4         div{
     5             margin-top:50px;
     6             margin-bottom: 50px;
     7         }
     8     </style>
     9     <script type="text/javascript">
    10         window.onload = function(){
    11             eventHandler(document,'contextmenu',function(event){
    12                 event = event || window.event;
    13                 event.preventDefault?(event.preventDefault()):(event.returnValue = false);
    14                 var menu = document.getElementById('myContextMenu'),
    15                 pageX = event.pageX?event.pageX:(event.clientX+(document.body.scrollLeft||document.documentElement.scrollLeft)),
    16                 pageY = event.pageY?event.pageY:(event.clientY+(document.body.scrollTop||document.documentElement.scrollTop));
    17                 menu.style.left = pageX+'px';
    18                 menu.style.top = pageY+'px';
    19                 menu.style.visibility = 'visible';
    20             });
    21             eventHandler(document,'click',function(event){
    22                 document.getElementById('myContextMenu').style.visibility = 'hidden';
    23             })
    24         }
    25         function eventHandler(dom,type,fn){
    26             if(typeof dom.addEventListener != 'undefined'){
    27                 dom.addEventListener(type,fn,false);
    28             }else if(typeof dom.attachEvent != 'undefined'){
    29                 dom.attachEvent('on'+type,fn);
    30             }else{
    31                 dom['on'+type] = fn;
    32             }
    33         }
    34     </script>
    35 </head>
    36 <body>
    37     <ul id='myContextMenu' style="padding:0;margin:0;list-style:none;position:absolute;visibility:hidden;background-color:silver;">
    38         <li>hi</li>
    39         <li><a href="#">hello</a></li>
    40     </ul>
    41     <div>asdfasf</div>
    42     <div>asdfasf</div>
    43     <div>asdfasf</div>
    44     <div>asdfasf</div>
    45     <div>asdfasf</div>
    46     <div>asdfasf</div>
    47     <div>asdfasf</div>
    48     <div>asdfasf</div>
    49     <div>asdfasf</div>
    50     <div>asdfasf</div>
    51     <div>asdfasf</div>
    52     <div>asdfasf</div>
    53     <div>asdfasf</div>
    54     <div>asdfasf</div>
    55     <div>asdfasf</div>
    56     <div>asdfasf</div>
    57 </body>
    58 </html>
    View Code
  • 相关阅读:
    【转】python:让源码更安全之将py编译成so
    [转]Ubuntu python-config
    【转】动态复权(真实价格)模式原理详解!
    [转]Aroon Indicator
    LeetCode 852. Peak Index in a Mountain Array
    LeetCode 1257. Smallest Common Region
    LeetCode 1034. Coloring A Border
    LeetCode 348. Design Tic-Tac-Toe
    LeetCode 452. Minimum Number of Arrows to Burst Balloons
    LeetCode 733. Flood Fill
  • 原文地址:https://www.cnblogs.com/cyITtech/p/3558926.html
Copyright © 2011-2022 走看看