javascript - 如何使用 VANILLA JS 按住右键单击来执行 eventListener
问题描述
我想在光标按住右键的任何地方显示 div。
就我而言,我有这个代码
<div class="d-none" id="item"></div>
#item{
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: royalblue;
/* transform: translate(calc(287px - 50%), calc(77px - 50%)); */
}
.d-none{
display: none;
}
var myMouseX, myMouseY;
function getXYPosition(e) {
myMouseX = (e || event).clientX;
myMouseY = (e || event).clientY;
getPosition(myMouseX, myMouseY);
function getPosition(x, y) {
console.log('X = ' + x + '; Y = ' + y);
let div = document.querySelector("#item");
if (div.classList.contains('d-none')) {
div.classList.remove('d-none');
} else {
div.classList.add('d-none');
}
divX = x + "px";
divY = y + "px";
div.style.transform = `translate(calc(`+divX+` - 50%) , calc(`+divY+` - 50%))`;
}
}
window.addEventListener('click', function () {
getXYPosition()
})
或者你可以看看我的小提琴
默认情况下,它在左键单击时使用window.addEventListener('click')
那么我如何从左键单击更改为按住右键单击几秒钟
解决方案
MouseEvent API(及其mousedown
和mouseup
事件)让我们检查event.button
属性以了解用户正在激活哪个鼠标按钮。我们可以跟踪之间经过了多少时间,mousedown
并mouseup
决定释放鼠标按钮时要做什么,例如运行自定义showOrHideDiv
函数。
并且在右键单击后触发contextmenu
事件(除非相关的上下文菜单已经可见,我猜。)如果需要,我们可以抑制默认的上下文菜单行为——尽管如果有的话,应该谨慎使用这种能力。
请注意,这里使用的技术是有问题的,因为它假定用户永远不会使用他们的键盘来查看上下文菜单,这最终会给用户带来可访问性混乱和其他令人不快的惊喜。right-click
这就是为什么如果可能的话应该避免劫持默认行为(可能有利于类似的东西Shift + right-click
),除非用户明确选择接受新行为。
// Defines constants and adds main (`mousedown`) listener
const
div = document.querySelector("#item"),
RIGHT = 2,
DELAY = 150;
document.addEventListener('mousedown', forceDelay);
// Main listener sets subsequent listeners
function forceDelay(event){
// Right mouse button must be down to proceed
if(event.button != RIGHT){ return; }
// Enables contextmenu and disables custom response
document.removeEventListener('contextmenu', suppressContextMenu);
document.removeEventListener('mouseup', showOrHideDiv);
// After 150ms, disables contextmenu and enables custom response
setTimeout(
function(){
document.addEventListener('contextmenu', suppressContextMenu);
document.addEventListener('mouseup', showOrHideDiv);
},
DELAY
);
}
// The `contextmenu` event listener
function suppressContextMenu(event){
event.preventDefault();
}
// The `mouseup` event listener
function showOrHideDiv(event){
if(event.button != RIGHT){ return; }
const
x = event.clientX,
y = event.clientY;
div.classList.toggle('d-none'); // classList API includes `toggle`
div.style.transform = `translate(calc(${x}px - 50%), calc(${y}px - 50%))`;
}
#item{ position: absolute; top: 0; left: 0; width: 100px; height: 100px; background: royalblue; }
.d-none{ display: none; }
<div id="item" class="d-none"></div>
编辑
注意:当使用 Chrome 在独立的 HTML 文件中进行测试时,该脚本可以正常工作,但是(至少在我笔记本电脑的触摸板中)在 Stack Overflow 代码段中运行时表现得很奇怪。如果您遇到类似问题,可以将其粘贴到 HTML 文件中的 <script> 元素中(在 <style> 元素中使用 CSS)以查看它是否正常工作。
推荐阅读
- android - 我想点击锁屏数
- jenkins - 获取从 Jfrog 工件到 Jenkins 部署作业的可用软件包版本列表
- powerbi - COUNTAX 和 COUNTX (DAX) 中的“表达式”是什么?
- python-3.x - 从 xlsx 文件中查询日期范围和产品大小
- ffmpeg - 使用 ffmpeg filter-complex 转换的输出 RTSP 流出现问题
- coq - “程序”策略产生的令人困惑的义务
- appsflyer - AppsFlyer:有没有办法找到用户是否重新安装应用程序
- python - 馅饼里面的馅饼| 高分辨率照片| CLIPARTO 带有平均值的圆环图python matplotlib
- caffe - LMDB:更改已制作的 lmdb 文件中的条目标签
- linux - 如何使用 ffmpeg 重叠和合并多个音频文件?