gpt4 book ai didi

javascript - 为什么从上下文菜单中复制停止工作?

转载 作者:太空宇宙 更新时间:2023-11-04 15:36:32 24 4
gpt4 key购买 nike

我在调试时遇到问题,我怀疑这是某种浏览器安全协议(protocol)。

这是一些代码的最小示例,这些代码是通过让每个部分都有一个可单击的图标来复制文本而进行重构的,并且有效。引入一个上下文菜单,该菜单应该委托(delegate)给之前负责复制的 View 模型。

我期望发生的是,当右键单击并选择复制时,蓝色、绿色和红色将 0、1、2 输出到剪贴板。

但是,自从我引入了上下文菜单后,事情就停止了。

我知道浏览器执行复制对用户交互有限制,但左键单击菜单选项肯定是用户交互吗?

或者我犯了一个我无法忘记的愚蠢错误?

ClickDirect 可以工作,因为它将函数直接绑定(bind)到点击处理程序。

但是其他 div 都不会复制。

var contextMenuVM = new function() {
var self = this;
var piece = {};
var args = [];

self.show = function(data, event) {
console.log('showargs:', arguments);
console.log('showthis:', this);
event.stopPropagation(true);
piece = this;
args = arguments;
event.stopPropagation();
var posx = event.clientX + window.pageXOffset; //Left Position of Mouse Pointer
var posy = event.clientY + window.pageYOffset; //Top Position of Mouse Pointer
$('#contextMenu').popup('open', {
x: posx,
y: posy,
positionTo: 'origin'
});
return false;
};

self.clickHandler = function(fn) {
return function(vm, event) {
event.stopPropagation();
event.preventDefault();
console.log('clickargs:', arguments);
console.log('clickthis:', this);
fn.apply(piece, args);
//$('#contextMenu').popup('close');
return false;
};
};
}();

copyToClipboard = function(pstrText) {

// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var origSelectionStart, origSelectionEnd;

// must use a temporary form element for the selection and copy
var target = document.getElementById(targetId);
if (!target) {
target = document.createElement("textarea");
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = pstrText;
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);

// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
console.log('succeed:', succeed);
} catch (e) {
succeed = false;
console.log('exception', e);
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
//currentFocus.focus();
}

// clear temporary content
// target.textContent = "";

return succeed;
};

toolbox = new function() {
var self = this;
self.copy = function() {
console.log('toolboxargs: ', arguments);
console.log('toolboxthis:', this);
copyToClipboard(this.number);
};
}();

var pieceVM = function(number) {
var self = this;
self.number = number;
};

var arr = ['bluemenu', 'greenmenu', 'redmenu', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'];

var count = 0;
$(function() {
$(".piece").each(function() {
ko.applyBindings(new pieceVM(arr[count++]), this);
});

ko.applyBindings(contextMenuVM, document.getElementById('contextMenu'));

});
<!DOCTYPE html>
<html lang="en">

<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" />
<script src="https://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>


</head>

<body>
<div data-role="page">
<div id="toolbox"></div>
<div data-role="content">
<div style="margin-top:100px">
demo
<div class="row">
<div class="piece col-xs-4 bg-info" data-bind="event:{contextmenu: contextMenuVM.show}">
blue contextmenu - not working (succeed: true)
</div>
<div class="piece col-xs-4 bg-success" data-bind="event:{contextmenu: contextMenuVM.show}">
green contextmenu - not working (succeed: true)
</div>
<div class="piece col-xs-4 bg-danger" data-bind="event:{contextmenu: contextMenuVM.show}">
red contextmenu - not working (succeed: true)
</div>
</div>
<div class="row">
<textarea name="_hiddenCopyText_" id="_hiddenCopyText_" cols="30" rows="1"></textarea>
</div>
<div class="row">
<div class="col-xs-12" style="padding-top:5px;">
<div class="row">
<div class="col-xs-12">testing (scroll down)</div>
</div>
<div class="row">
<div class="expected col-xs-3 bg-success">(expected: working)</div>
<div class="result col-xs-3 bg-danger">(result: broken)</div>
<div class="piece col-xs-6 bg-warning" data-bind="event: {contextmenu: contextMenuVM.show}">
context menu (same as demo)
</div>
</div>
<div class="row">
<div class="expected col-xs-3 bg-success">(expected: working)</div>
<div class="result col-xs-3 bg-danger">(result: broken)</div>
<div class="piece col-xs-6 bg-warning" data-bind="click: contextMenuVM.show">
left click menu
</div>
</div>
<div class="row">
<div class="expected col-xs-3 bg-success">(expected: working)</div>
<div class="result col-xs-3 bg-success">(result: working)</div>
<div class="piece col-xs-6 bg-primary" data-bind="click: function(){copyToClipboard('click direct')}">
click direct copy
</div>
</div>
<div class="row">
<div class="expected col-xs-3 bg-danger">(expected: broken)</div>
<div class="result col-xs-3 bg-danger">(result: broken)</div>
<div class="piece col-xs-6 bg-warning" data-bind="event: {contextmenu: copyToClipboard('context direct')}">
context direct copy
</div>
</div>
<div class="row">
<div class="expected col-xs-3 bg-success">(expected: working)</div>
<div class="result col-xs-3 bg-success">(result: working)</div>
<div class="piece col-xs-6 bg-primary" data-bind="click: contextMenuVM.clickHandler(function(){copyToClipboard('click indirect')})">
click indirect
</div>
</div>
<div class="row">
<div class="expected col-xs-3 bg-danger">(expected: broken)</div>
<div class="result col-xs-3 bg-danger">(result: broken)</div>
<div class="piece col-xs-6 bg-warning" data-bind="event: {contextmenu: contextMenuVM.clickHandler(function(){copyToClipboard('context indirect')})}">
context indirect
</div>
</div>
</div>
</div>
</div>

<div id="contextMenu" class="contextMenu ui-content" data-role="popup" data-theme="c" data-dismissible="true">
<div title="Copy" data-bind="click: clickHandler(toolbox.copy)"><i style="cursor: pointer;" class="fa fa-copy"></i><span class="contextMenuItemText">Copy</span></div>
<div title="Copy"><a data-bind="click: clickHandler(toolbox.copy)"><i style="cursor: pointer;" class="fa fa-copy"></i><span class="contextMenuItemText">Copy</span></a></div>
<div title="Copy" data-bind="event: {click: clickHandler(toolbox.copy)}"><i style="cursor: pointer;" class="fa fa-copy"></i><span class="contextMenuItemText">Copy</span></div>
<div title="Copy"><a data-bind="event: {click: clickHandler(toolbox.copy)}"><i style="cursor: pointer;" class="fa fa-copy"></i><span class="contextMenuItemText">Copy</span></a></div>
<a data-bind="event: {click: clickHandler(toolbox.copy)}" class="ui-btn">Copy</a>
<div title="Copy" data-bind="click: clickHandler(function(){copyToClipboard('click indirect')})">click indirect</div>
</div>
</div>
</div>

</body>

</html>

最佳答案

它停止工作,因为 JQuery Mobile 弹出窗口阻止焦点转到弹出窗口之外的元素。

您正在使用的代码(已在一些地方流行,包括堆栈溢出复制)依赖于获得焦点的隐藏元素。

在你的情况下,你可能有点运气不好,因为你有一个硬编码的实用函数,假设焦点可能会丢失。

如果您可以编辑该实用程序,我建议您在每个弹出窗口中包含多个这些字段,并使用最接近的字段,或者在调用复制函数时在弹出窗口中提供元素的 ID。

幸运的是,您的问题不是要求解决方案,而是要求为什么会发生。否则我无法帮助你:P。花了 6 个小时...我们真是太糟糕了。

关于javascript - 为什么从上下文菜单中复制停止工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44303217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com