我有一个文本区域,用户可以在其中粘贴剪贴板中的文本。
粘贴的文本
clipboarddata.getData('text')
被修改。
但是,我需要一个开关,如果按 CTRL SHIFT V 而不是 CTRL V,粘贴的文本不会被修改。
我尝试用 keydown/keyup 来捕捉 Shift 键:
$('textarea').on('keyup', function(e)
{
shiftkey_down = e.shiftKey;
});
然后尝试读取粘贴事件处理程序中的布尔变量:
$('textarea').on('paste', function(e)
{
if (shiftkey_down)
{
// ...
}
});
但是
paste
事件发生在 keydown 和 keyup 之后。所以我无法读取按下了什么键。并且 shiftkey_down
始终位于粘贴处理程序内 false
。
处理这个问题的正确方法是什么?
我得到的唯一想法是保存在 keydown 事件中按下的最后一个组合键,然后检查粘贴处理程序中按下的最后一个组合键。但似乎也不起作用。
更新:
我尝试使用一个很小的超时,这样 keydown 布尔变量就不会立即被覆盖:
var shiftkey_paste = false;
$('textarea').on('keydown', function(e)
{
if (!shiftkey_paste)
{
shiftkey_paste = e.shiftKey && e.ctrlKey;
console.log('> '+shiftkey_paste);
setTimeout( function()
{
// set false again after timeout so paste event has chance to pick up a true value
shiftkey_paste = false;
}, 10);
}
console.log('>> ' + shiftkey_paste);
});
在粘贴处理程序中,我使用
console.log('>>> ' + shiftkey_paste);
打印该值。
结果:
> false
>> false
> true
>> true
> false
>> false
>>> false
此外
false
即使超时应该有所帮助。
更新2:
✔️ 哇,它的超时时间为
100ms
而不是 10ms
(!)
更新3:
我发现,当用户按住 CTRL SHIFT 时,setTimeout 会被多次触发,从而将布尔值设置为 false,即使按住按键也是如此。解决办法是清除settimeout,如下:
var shiftkey_paste = false;
var shiftkey_timeout = null;
$('textarea').on('keydown', function(e)
{
if (!shiftkey_paste)
{
clearTimeout(shiftkey_timeout);
shiftkey_paste = e.shiftKey && e.ctrlKey;
console.log('> ' + shiftkey_paste);
shiftkey_timeout = setTimeout( function()
{
// set false again after timeout so paste event has chance to pick up a true value
shiftkey_paste = false;
shiftkey_timeout = null;
},
500); // 500 ms for timeout to set back boolean to false
}
console.log('>> ' + shiftkey_paste);
});
这个解决方案效果很好。
使用
keydown
和 keyup
来存储 ctrlKey
和 shiftKey
的状态。如果是特殊组合键,我们会取消该事件并以不完整的方式将文本插入到文本区域。
var ctrl = false
var shift = false
textarea.addEventListener('paste', function(ev) {
var clipboardData = (event.clipboardData || window.clipboardData);
var pastedText = clipboardData.getData('text');
if (ctrl && shift) {
pastedText = "*" + pastedText + "*"
ev.preventDefault()
// this code - i don't like it - because you can't ctrl+z
var cursorPosition = textarea.selectionStart;
var currentValue = textarea.value;
var newValue = currentValue.substring(0, cursorPosition) + pastedText + currentValue.substring(textarea.selectionEnd);
textarea.value = newValue;
textarea.selectionStart = textarea.selectionEnd = cursorPosition + pastedText.length;
}
})
textarea.addEventListener('keydown', function(ev) {
ctrl = ev.ctrlKey
shift = ev.shiftKey
})
textarea.addEventListener('keyup', function(ev) {
ctrl = ev.ctrlKey
shift = ev.shiftKey
})
<textarea id="textarea" style="width:100%" rows="8"></textarea>