应取消哪个事件以停止可编辑的键盘快捷键?
Which event should be cancelled to stop a contenteditable keyboard shortcut?
我试图通过首先从键盘快捷键禁用它的文本样式行为来围绕 contenteditable 构建,例如 ctrl+b
或 ctrl+i
。
当在 keyup
和 keydown
事件中检测到这些快捷方式时,我正在使用 event.preventDefault()
-- 但有时 很少 ,我注意到contenteditable 仍然忽略 event.preventDefault()
并且键盘快捷键受到尊重。
除了取消 keyup
和 keydown
之外,还有什么方法可以完全禁用这些键盘快捷键吗?
我的快捷方式检测器有问题,它在某些情况下让事件通过。似乎取消 keydown
上的事件实际上也取消了快捷方式。
我为任何想尝试的人创建了一个 jsfiddle:https://jsfiddle.net/mohj19bs/28/
明天我将关闭此线程,以防万一其他人可能会分享一些有趣的东西,因为 contenteditable
一直给我带来惊喜。
这是另一种可能适合您的策略。不要试图阻止插入 b
和 i
元素,只需在 keyup
或 paste
.
上立即删除它们
处理的案例有:
- [CTRL] + [b] 和 [CTRL] + [i]
- 粘贴 HTML 包含内联样式属性
它以递归方式处理嵌套元素。
let forbiddenTags = ["B", "I", "STRONG"]
let clean = function(e){
// Loop through all child nodes
e.target.childNodes.forEach(function(item){
// recursion if there are childnodes
if(item.childNodes){
clean({target:item})
}
// Remove forbidden tags
if(item.tagName && forbiddenTags.indexOf(item.tagName) > -1){
item.insertAdjacentHTML("afterEnd", item.innerHTML)
item.remove()
return
}
// Reset inline style
if(item.style){
item.style.fontWeight = "normal"
item.style.fontStyle = "normal"
}
})
}
document.querySelector("#test").addEventListener("keyup", clean)
document.querySelector("#test").addEventListener("paste", clean)
div{
border: 1px solid grey;
padding: 0.5em;
}
table{
border-collapse: collapse;
}
td{
border: 1px solid grey;
}
<div id="test" contentEditable=true>Enter text here</div>
<br>
Paste me in!:
<div id="pasteit">
<b>bold</b> <i>italic</i> <strong>strong</strong> <span style="font-weight:bold;">inline</span>
<table>
<tr>
<td style="font-style:italic;">Italic</td>
<td style="font-weight:bold;">Bold</td>
</tr>
</table>
</div>
不确定您正在处理什么问题,但这很有效...
document.getElementById("test").addEventListener("keydown", e => {
if(!e.ctrlKey) return;
if(e.keyCode === 66 || e.keyCode === 73) {
e.preventDefault();
}
});
<div id="test" contenteditable>This div is editable</div>
还有一个 one-liner 供您欣赏:
document.getElementById("test").onkeydown = e => !(e.ctrlKey && (e.keyCode === 66 || e.keyCode === 73));
<div id="test" contenteditable>This div is editable</div>
我试图通过首先从键盘快捷键禁用它的文本样式行为来围绕 contenteditable 构建,例如 ctrl+b
或 ctrl+i
。
当在 keyup
和 keydown
事件中检测到这些快捷方式时,我正在使用 event.preventDefault()
-- 但有时 很少 ,我注意到contenteditable 仍然忽略 event.preventDefault()
并且键盘快捷键受到尊重。
除了取消 keyup
和 keydown
之外,还有什么方法可以完全禁用这些键盘快捷键吗?
我的快捷方式检测器有问题,它在某些情况下让事件通过。似乎取消 keydown
上的事件实际上也取消了快捷方式。
我为任何想尝试的人创建了一个 jsfiddle:https://jsfiddle.net/mohj19bs/28/
明天我将关闭此线程,以防万一其他人可能会分享一些有趣的东西,因为 contenteditable
一直给我带来惊喜。
这是另一种可能适合您的策略。不要试图阻止插入 b
和 i
元素,只需在 keyup
或 paste
.
处理的案例有:
- [CTRL] + [b] 和 [CTRL] + [i]
- 粘贴 HTML 包含内联样式属性
它以递归方式处理嵌套元素。
let forbiddenTags = ["B", "I", "STRONG"]
let clean = function(e){
// Loop through all child nodes
e.target.childNodes.forEach(function(item){
// recursion if there are childnodes
if(item.childNodes){
clean({target:item})
}
// Remove forbidden tags
if(item.tagName && forbiddenTags.indexOf(item.tagName) > -1){
item.insertAdjacentHTML("afterEnd", item.innerHTML)
item.remove()
return
}
// Reset inline style
if(item.style){
item.style.fontWeight = "normal"
item.style.fontStyle = "normal"
}
})
}
document.querySelector("#test").addEventListener("keyup", clean)
document.querySelector("#test").addEventListener("paste", clean)
div{
border: 1px solid grey;
padding: 0.5em;
}
table{
border-collapse: collapse;
}
td{
border: 1px solid grey;
}
<div id="test" contentEditable=true>Enter text here</div>
<br>
Paste me in!:
<div id="pasteit">
<b>bold</b> <i>italic</i> <strong>strong</strong> <span style="font-weight:bold;">inline</span>
<table>
<tr>
<td style="font-style:italic;">Italic</td>
<td style="font-weight:bold;">Bold</td>
</tr>
</table>
</div>
不确定您正在处理什么问题,但这很有效...
document.getElementById("test").addEventListener("keydown", e => {
if(!e.ctrlKey) return;
if(e.keyCode === 66 || e.keyCode === 73) {
e.preventDefault();
}
});
<div id="test" contenteditable>This div is editable</div>
还有一个 one-liner 供您欣赏:
document.getElementById("test").onkeydown = e => !(e.ctrlKey && (e.keyCode === 66 || e.keyCode === 73));
<div id="test" contenteditable>This div is editable</div>