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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM