您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關在HTML頁面中如何添加自定義右鍵菜單,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
首先將這三個功能以一個列表<ul>的形式放置。鼠標移入時樣式改變,移出時還原
<style> body{margin: 0;} ul{ margin: 0; padding: 0; list-style: none; } .list{ width: 100px; text-align: center; cursor: pointer; font:20px/40px '宋體'; background-color: #eee; } .in:hover{ background-color: lightblue; color: white; font-weight:bold; } </style> <ul id="list" class="list"> <li class="in">頂部</li> <li class="in">點贊</li> <li class="in">評論</li> </ul>
菜單邏輯共包括阻止默認行為、顯隱效果和位置判斷三個部分
通常,點擊右鍵時,會彈出瀏覽器的默認右側菜單
通過return false可以實現(xiàn)阻止默認行為的效果,當然也可以使用preventDefault()和returnValue,詳細信息移步至此
document.oncontextmenu = function(){ return false; }
右鍵菜單默認隱藏,點擊右鍵時顯示,點擊左鍵時再隱藏
關于元素顯隱,個人總結過共9種思路,本文就用最簡單的display屬性
<div id="test" ></div> <script> document.onclick = function(){ test.style.display = 'none'; } document.oncontextmenu = function(){ test.style.display = 'block'; return false; } </script>
鼠標對象共有6對坐標位置信息,若把右鍵菜單設置為fixed固定定位,則選擇clientX/Y即可
一般地,右鍵菜單的左上角位置應該是當前鼠標的坐標處
但是,還有另外2種情況需要考慮
【1】如果鼠標的位置到視口底部的位置小于菜單的高度,則鼠標的位置為菜單的底部位置
【2】如果鼠標的位置到視口右側的位置小于菜單的寬度,則視口的右側為菜單的右側
元素的尺寸信息共有偏移尺寸offset、可視區(qū)尺寸client和滾動尺寸scroll,此時菜單的寬高應該為偏移尺寸offsetWidth/offsetHeight(全尺寸包含width、padding、border)
<div id="test" ></div> <script> document.onclick = function(){ test.style.display = 'none'; } document.oncontextmenu = function(e){ e = e || event; test.style.left = e.clientX + 'px'; test.style.top = e.clientY + 'px'; //注意,由于加法、減法的優(yōu)先級高于大于、小于的優(yōu)先級,所以不用加括號,詳細情況移步至此 if(document.documentElement.clientHeight - e.clientY < test.offsetHeight){ test.style.top = e.clientY - test.offsetHeight + 'px'; } if(document.documentElement.clientWidth - e.clientX < test.offsetWidth){ test.style.left = document.documentElement.clientWidth - test.offsetHeight + 'px'; } test.style.display = 'block'; return false; } </script>
共用有回到頂部、點贊和評論三個功能需要實現(xiàn)
回到頂部共有5種實現(xiàn)方法,下面使用可讀寫的scrollTop屬性進行效果實現(xiàn)
<body > <button id="test" >回到頂部</button> <script> var timer = null; test.onclick = function(){ cancelAnimationFrame(timer); timer = requestAnimationFrame(function fn(){ var oTop = document.body.scrollTop || document.documentElement.scrollTop; if(oTop > 0){ document.body.scrollTop = document.documentElement.scrollTop = oTop - 160; timer = requestAnimationFrame(fn); }else{ cancelAnimationFrame(timer); } }); } </script> </body>
但是,上面的代碼有一個問題,就是當頁面內(nèi)容較多時,回到頂部的動畫效果將持續(xù)很長時間。因此,使用時間版的運動更為合適,假設回到頂部的動畫效果共運動500ms,則代碼如下所示
<body > <button id="test" >回到頂部</button> <script> var timer = null; test.onclick = function(){ cancelAnimationFrame(timer); //獲取當前毫秒數(shù) var startTime = +new Date(); //獲取當前頁面的滾動高度 var b = document.body.scrollTop || document.documentElement.scrollTop; var d = 500; var c = b; timer = requestAnimationFrame(function func(){ var t = d - Math.max(0,startTime - (+new Date()) + d); document.documentElement.scrollTop = document.body.scrollTop = t * (-c) / d + b; timer = requestAnimationFrame(func); if(t == d){ cancelAnimationFrame(timer); } }); } </script> </body>
點贊函數(shù)是博客園自己寫的,我們看不到內(nèi)部函數(shù)也無法使用。如果想在右鍵菜單中使用點贊功能,就需要模擬點擊事件。點擊右鍵菜單中的點贊項時,觸發(fā)博客園的自帶的點贊項的click事件
由下圖可知,點贊函數(shù)加在<div class="diggit">上
由一個小例子來說明模擬點擊事件如何實現(xiàn)
點擊按鈕1時,顯示1;點擊按鈕2時,也要實現(xiàn)同樣的功能
<button id="btn1">按鈕1</button> <button id="btn2">按鈕2</button> <div id="result" ></div> <script> btn1.onclick= function(){ result.innerHTML += '1'; } btn2.onclick = btn1.onclick; </script> 如法炮制 <div id="test">點贊</div> <script> window.onload = function(){ test.onclick = document.getElementById('div_digg').children[0].onclick; } </script>
增加獲取最新點贊數(shù)的功能
當id為'menuFavour'的div元素被點擊時,更新點贊數(shù)。但,由于從服務器獲取最新數(shù)據(jù)以及相關元素的內(nèi)容發(fā)生變化,都需要時間,所以增加2秒的延遲
<div id="menuFavour">點贊(<span id="favourNum">0</span>贊)</div> <script> //模擬原始點贊按鈕的點擊事件 menuFavour.onclick = document.getElementById('div_digg').children[0].onclick; //獲取贊成數(shù)的函數(shù) function getfavourNum(){ favourNum.innerHTML = document.getElementById('digg_count').innerHTML; } //頁面載入時獲取贊成數(shù) getfavourNum(); //點擊菜單中的贊成項后,再獲取最新的贊成數(shù) menuFavour.addEventListener('click',function(){ setTimeout(function(){ getfavourNum(); },2000); }) </script>
點擊右鍵菜單中的評論項時,頁面定位到評論區(qū)的位置
由圖中可知,評論區(qū)為<div id="comment_form_container">
將元素置于可視區(qū)域內(nèi)有很多方法,如scrollTo()、scrollBy()、通過scrollTop計算、scrollIntoView()方法等等,詳細情況移步至此
下面利用scrollIntoView()方法滾動當前元素,進入瀏覽器的可見區(qū)域
<div id="test">評論</div> <script> window.onload = function(){ test.onclick = function(){ document.getElementById('comment_form_container').scrollIntoView(); } } </script>
將HTML結構和CSS樣式寫成javascript生成的行為,最終形成一份js文件,代碼如下
//requestAnimationFrame兼容寫法 if(!window.requestAnimationFrame){ var lastTime = 0; window.requestAnimationFrame = function(callback){ var currTime = new Date().getTime(); var timeToCall = Math.max(0,16.7-(currTime - lastTime)); var id = window.setTimeout(function(){ callback(currTime + timeToCall); },timeToCall); lastTime = currTime + timeToCall; return id; } } if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function(id) { clearTimeout(id); }; } //事件處理程序兼容寫法 function addEvent(target,type,handler){ if(target.addEventListener){ target.addEventListener(type,handler,false); }else{ target.attachEvent('on'+type,function(event){ return handler.call(target,event); }); } } /*******生成元素*******/ var list = document.createElement('ul'); list.id = 'list'; list.innerHTML = '<li id="menuTop">回到頂部</li>\ <li id="menuFavour">點贊(<span id="favourNum">0</span>贊)</li>\ <li id="menuCommand">評論</li>'; document.body.appendChild(list); /*******添加樣式**********/ function loadStyles(str){ var style = document.createElement("style"); style.type = "text/css"; try{ style.innerHTML = str; }catch(ex){ style.styleSheet.cssText = str; } var head = document.getElementsByTagName('head')[0]; head.appendChild(style); } loadStyles("#list{margin: 0!important;\ padding: 0!important;\ width: 120px;\ text-align: center;\ cursor: pointer;\ font:20px/40px '宋體';\ background-color: #eee;\ position:fixed;\ display:none;}\ #list li{list-style:none!important;}\ #list li:hover{background-color: lightblue;color: white;font-weight:bold;}"); //DOM結構穩(wěn)定后,再操作 addEvent(window,'load', contextMenuLoad); function contextMenuLoad(){ /********顯示和隱藏菜單***********/ addEvent(document,'click',function(){ list.style.display = 'none'; }) //右鍵點擊時,菜單顯示 document.oncontextmenu = function(e){ e = e || event; //通常情況下,菜單的位置就是鼠標的位置 list.style.left = e.clientX + 'px'; list.style.top = e.clientY + 'px'; //當鼠標的位置到視口底部的位置小于菜單的高度,則鼠標的位置為菜單的底部位置 if(document.documentElement.clientHeight - e.clientY < list.offsetHeight){ list.style.top = e.clientY - list.offsetHeight + 'px'; } //當鼠標的位置到視口右側的位置小于菜單的寬度,則視口的右側為菜單的右側 if(document.documentElement.clientWidth - e.clientX < list.offsetWidth){ list.style.left = document.documentElement.clientWidth - list.offsetHeight + 'px'; } list.style.display = 'block'; //點擊右鍵的同時按下ctrl鍵,那么將顯示默認右鍵菜單 if(e.ctrlKey){ list.style.display = 'none'; //如果只是點擊右鍵,則顯示自定義菜單 }else{ return false; } } /*********回到頂部功能*********/ var timer = null; menuTop.onclick = function(){ cancelAnimationFrame(timer); //獲取當前毫秒數(shù) var startTime = +new Date(); //獲取當前頁面的滾動高度 var b = document.body.scrollTop || document.documentElement.scrollTop; var d = 500; var c = b; timer = requestAnimationFrame(function func(){ var t = d - Math.max(0,startTime - (+new Date()) + d); document.documentElement.scrollTop = document.body.scrollTop = t * (-c) / d + b; timer = requestAnimationFrame(func); if(t == d){ cancelAnimationFrame(timer); } }); }; /*********點贊功能**********/ //模擬原始點贊按鈕的點擊事件 var digg = document.getElementById('div_digg'); if(digg){ menuFavour.onclick = digg.children[0].onclick; } //獲取贊成數(shù)的函數(shù) function getfavourNum(){ if(digg){ favourNum.innerHTML = digg.children[0].children[0].innerHTML; } } //頁面載入時獲取贊成數(shù) getfavourNum(); if(menuFavour.addEventListener){ menuFavour.addEventListener('click',function(){ setTimeout(function(){ getfavourNum(); },2000); }) }else{ menuFavour.attachEvent('onclick',function(){ setTimeout(function(){ getfavourNum(); },2000); }) } /*********評論功能*********/ menuCommand.onclick = function(){ document.getElementById('comment_form_container').scrollIntoView(); } }
關于“在HTML頁面中如何添加自定義右鍵菜單”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。