- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个包含计算机代码的 pre
标签的页面。我有一个 mouseover
事件监听器,它突出显示 pre
标记中的所有代码。我还让它删除了 mouseout
事件上的突出显示。如果您使用键盘复制 (ctrl-C),效果非常好。
但是如果你想从上下文菜单中右键单击并复制,那就有问题了。当鼠标进入上下文菜单时,会触发pre
标签的mouseout
事件。
我需要一种方法来测试上下文菜单当前是否打开或显示。然后我可以取消删除突出显示。有没有办法测试上下文菜单是否打开或显示?
我不需要任何 jquery,拜托。
我对这个问题的最终选择可能是 oncontextmenu
,但我不知道如果它关闭我将如何发现。除非我尝试为上下文菜单的 mouseout
事件监听事件,如果可能的话。
到目前为止,这是我的代码:
window.onload = function(){
function selectText(element) {
var range, selection;
if(window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
}
function unSelectText() {
window.getSelection().removeAllRanges();
}
preTags = document.getElementsByTagName('PRE');
for(var i = 0; i < preTags.length; i++) {
preTags[i].onmouseover = function() {selectText(this)};
preTags[i].onmouseout = function() {unSelectText(this)};
}
codeTags = document.getElementsByTagName('CODE');
for(var i = 0; i < codeTags.length; i++) {
codeTags[i].onmouseover = function() {selectText(this)};
codeTags[i].onmouseout = function() {unSelectText(this)};
}
};
最佳答案
由于 JS 中没有事件触发上下文菜单框的关闭操作,也没有可靠的解决方法:据我从不同的研究中了解到,您的问题的答案是否定的。
但是如果您考虑类似的方法,可以使用自定义上下文菜单来解决您的问题。
简短说明
code
和 pre
元素。在您的情况下,只需要一个项目copy
(在示例中快速!非常!简化!演示为简单框)。简化示例
请注意:该示例是一个快速、肮脏且非常简单的示例,用于演示该技术。 I tsure needs to be adapt to your special project.
window.onload = function(){
// general vars
let isOpenContextMenu = false;
const $contextMenu = document.getElementById('contextMenu');
// all code/pre elements in one object to use in one loop
const $codeElements = document.querySelectorAll('pre, code');
let $actualCodeElement = {};
// methods
function selectText(element) {
var range, selection;
if(window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
}
function unSelectText() {
window.getSelection().removeAllRanges();
}
// listeners
// block right clicke when context menu on code/pre element is open
function listenerContextMenuBlocked(evt){
evt.preventDefault();
}
// clicks when context menu on code/pre elements is open
function listenerMenuClick(ev){
let $clickedElement = ev.target;
do{
if($clickedElement == $contextMenu){
// clicked on context menu
// --> copy action
let codeToCopy = $actualCodeElement.innerText;
let temporaryInput = document.createElement('input');
temporaryInput.type = 'text';
temporaryInput.value = codeToCopy;
document.body.appendChild(temporaryInput);
temporaryInput.select();
document.execCommand('Copy');
document.body.removeChild(temporaryInput);
// --> close menu and reset
$contextMenu.classList.remove('contextMenu--active');
isOpenContextMenu = false;
window.removeEventListener('contextmenu', listenerContextMenuBlocked);
return;
}
$clickedElement = $clickedElement.parentNode;
} while($clickedElement)
// clicked outside context menu
// --> close and reset
$contextMenu.classList.remove('contextMenu--active');
isOpenContextMenu = false;
window.removeEventListener('contextmenu', listenerContextMenuBlocked);
}
// open custom context menu when right click on code/pre elements
function listenerOpenContextMenuCodeBlock(e) {
e.preventDefault();
// used to copy conten in listenerMenuClick()
$actualCodeElement = e.target;
if(false === isOpenContextMenu){
// open context menu
$contextMenu.style.top = e.clientY + 2 + 'px';
$contextMenu.style.left = e.clientX + + 2 + 'px';
$contextMenu.classList.add('contextMenu--active');
isOpenContextMenu = true;
window.addEventListener('click', listenerMenuClick);
window.addEventListener('contextmenu', listenerContextMenuBlocked);
}
}
for(var i = 0; i < $codeElements.length; i++) {
//$actualElement = $codeElements[i]; //
$codeElements[i].addEventListener('contextmenu', listenerOpenContextMenuCodeBlock);
$codeElements[i].onmouseover = function() {
if(false === isOpenContextMenu){
selectText(this)
}
};
$codeElements[i].onmouseout = function() {
if(false === isOpenContextMenu){
unSelectText(this)
}
};
}
};
/* styles needed for custom context menu */
html {
position: relative;
}
#contextMenu {
display: none;
position: absolute;
font-family: sans-serif;
font-size: 11px;
line-height: 12px;
padding: 2px 5px;
background-color: #eeeeee;
border: 1px solid #a5a5a5;
box-shadow: 2px 3px 1px -1px rgba(0,0,0,0.4);;
cursor: context-menu;
z-index: 10;
}
#contextMenu:hover {
background-color: #aad7f3;
}
#contextMenu.contextMenu--active {
display: block;
}
<!-- SIMPLIFIED custom context menu for code/pre elements = hidden on page -->
<nav id="contextMenu" style="top: 50px; left: 30px" >
<div>Copy Codeblock</div>
</nav>
<!-- example elements for code presentation / testing -->
<pre>
Lorem, ipsum dolor sit amet consectetur adipisicing elit.
Provident magni blanditiis, ea necessitatibus esse nihil,
quae iste explicabo beatae perspiciatis quibusdam tempora minima,
eos molestias illum voluptatum voluptate ipsum perferendis!
</pre>
<code>
Li Europan lingues es membres del sam familie. Lor separat existentie
es un myth. Por scientie, musica, sport etc, litot Europa usa li sam vocabular.
Li lingues differe solmen in li grammatica, li pronunciation e li plu commun vocabules.
Omnicos directe al desirabilite de un nov lingua franca: On refusa continuar payar
custosi traductores.
</code>
关于javascript - 如何测试上下文菜单是否打开或显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66285475/
出现以下错误 Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable D
在调试应用程序时出现以下错误。 The CLR has been unable to transition from COM context 0x3b2d70 to COM context 0x3b2
在 GAE Go 中,为了记录,我们需要使用 appengine.NewContext(r) 创建一个新的上下文,它返回 context.Context。 如何使用此上下文在请求范围内设置/获取变量?
我想使用 Puppeteer 从放置在页面上 iframe 内的选择器中获取数据,该页面在与其父框架域不同的域上运行。因此,我不是任何域的所有者 - 无法使用 frame.postMessage。 试
我正在尝试获取可用的应用程序上下文并想切换到 webview 上下文,但 appium 仅获取 Navive App。 应用程序还启用了 WebView。 Appium 版本:1.10.1 Chrom
这个问题在这里已经有了答案: How to fix this nullOk error when using the flutter_svg package? (7 个回答) 7 个月前关闭。 当我尝
我观看了关于 Core Data 的 2016 WWDC 视频并查看了各种教程。我见过使用 Core Data Framework 创建对象以持久保存到 managedObjectContext 中的
这是代码 obj = { a: 'some value'; m: function(){ alert(this.a); } } obj.m(); 结果是'som
我正在尝试做类似的事情 $(".className").click(function() { $(this).(".anotherClass").css("z-index","1");
var User = { Name: "Some Name", Age: 26, Show: function() { alert("Age= "+this.Age)}; }; fun
我目前正在使用我见过的常见 Context 模式,它允许子组件通过传递修饰函数来更新父组件的状态(即 Provider)通过共享的 Context。 我遇到的问题是,修改函数只引用原始状态,不引用最新
有没有办法让 React Context类型安全与流类型? 例如: Button.contextTypes = { color: React.PropTypes.string }; 最佳答案 不幸
我想知道是否有一种方法可以为不同的功能使用不同的上下文类。 我希望有一个功能使用 MinkExtensions 进行浏览器测试,另一个功能使用和 HTTP 客户端(如 Guzzle)进行 API 测试
我有这个配置文件 apiVersion: v1 clusters: - cluster: server: [REDACTED] // IP of my cluster name: stag
我在实现非抢先式调度时遇到了用于初始化TCB的代码。 typedef struct TCB_t { struct TCB_t *next; struct TCB_t
我想将一个函数设置为数组中每个元素的属性,但使用不同的参数调用它。我想我会使用匿名函数来解决它: for ( var i = 0; i < object_count; i++ ) { obje
这个问题已经有答案了: How to access the correct `this` inside a callback (15 个回答) 已关闭 7 年前。 我正在做一些练习,但我在管道方法中丢
我正在尝试通过 Java 和 Android Studio 学习和制作 Android 应用程序。我对Java的了解程度是两年前几个小时的youtube学习和大学基础类(class)。不过我确实知道如
我在(这个)上遇到了问题。错误ImageView无法应用。我在 fragment 类中执行此代码。 ViewFlipper v_flipper; @Nullable @Override public
我想使用 openGL 的某些功能,但与渲染视觉内容无关。有没有办法在没有任何依赖性的情况下创建它(不是对 Windows,也不是某些包[SDL,SFML,GLUT])?只允许使用没有外部库的库,就像
我是一名优秀的程序员,十分优秀!