D3.js-javascript-自定义右键菜单+禁用默认右键菜单

问题描述

前端有一个svg绘制的circle,我需要实现这样的效果:首先,在圆环上点击左键,然后拖动,最后抬起左键。这样可以选中圆环的一段区域(这段区域会加阴影),此时点击右键可以弹出自定义的菜单。

问题在于,右键菜单出现时,浏览器默认的右键菜单也会出现,因此需要禁用。

解决方案

// 右键点击事件
svg.addEventListener('contextmenu', (e) => {
	// 阻止浏览器的默认右键菜单
	event.preventDefault();
	// 如果选中区域可见,显示右键菜单
	// arcPath是我选中的区域,此时会出现阴影
    if (arcPath.style.display === "block") {
    	// startSelectSeqPos, curSelectSeqPos是经过计算的起终位置
        showContextMenu(e, startSelectSeqPos, curSelectSeqPos);
    }
});

// 显示右键菜单
function showContextMenu(event, start, end) {
	console.log(start);
    event.preventDefault(); 

    // 创建右键菜单
    const menu = d3.select("body").append("div")
        .attr("class", "context-menu")
        .style("position", "absolute")
        .style("left", `${event.pageX}px`)
        .style("top", `${event.pageY}px`)
        .html("<div id='copy-sequence'>复制</div>");

    // 复制序列
    menu.select("#copy-sequence").on("click", function() {
        const selectedSequence = plasmidSequence.slice(start, end);
        navigator.clipboard.writeText(selectedSequence);
        menu.remove();
    });

    // 点击其他地方隐藏菜单
    d3.select("body").on("click", function() {
        menu.remove();
    });
}


但是这个代码有个问题是,当你选中了序列,在其他地方右键的时候会出现好几个右键菜单。下面会做修改,同时使用bootstrap5。
在这里插入图片描述

使用bootstrap5

首先引入bootstrap5:

<!-- 地址省略 -->
<link href="/.../bootstrap.min.css" rel="stylesheet">
<!-- 引入 Bootstrap 5 JS(包括 Popper.js) -->
<script src="/.../bootstrap.bundle.min.js"></script>

在body里增加菜单:

<!-- 右键菜单 -->
<div id="contextMenu" class="dropdown-menu">
	<button class="dropdown-item" id="copy-sequence">复制</button>
</div>

然后修改函数showContextMenu()

function showContextMenu(event, start, end) {
    event.preventDefault(); // 禁止默认右键菜单

    // 获取右键菜单元素
    const contextMenu = document.getElementById("contextMenu");

    // 设置菜单位置
    contextMenu.style.display = "block";
    contextMenu.style.position = "absolute";
    contextMenu.style.left = `${event.pageX}px`;
    contextMenu.style.top = `${event.pageY}px`;

    // 复制序列
    document.getElementById("copy-sequence").onclick = function() {
        const selectedSequence = plasmidSequence.slice(start, end);
        navigator.clipboard.writeText(selectedSequence);
        contextMenu.style.display = "none"; // 隐藏菜单
    };

    // 点击其他地方隐藏菜单
    document.addEventListener("click", function hideMenu() {
        contextMenu.style.display = "none";
        document.removeEventListener("click", hideMenu);
    });
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值