我有一个contenteditable
p
元素。我想将可能的编辑操作限制为插入和删除逗号。我也想将更新的内容复制到另一个div
。这两个目标似乎很难结合在一起:
如果按下了除退格键或逗号以外的任何其他键,似乎我必须监听keydown
事件以防止使用event.preventDefault()
更改文本。当我收听keyup
时,event.preventDefault()
执行得太迟了,无论按下哪个键,内容都会更新。
但是我可能需要等待keyup
更新段落的内容,以便我可以复制文本。如果我使用keydown
,则会得到原始文本。
我正在使用Vue。在HTML代码中,@keydown='evaluate($event)'
只是附加了一个侦听器,并允许使用来访问事件变量。
编辑:这是我的原始代码,另请参见下面的代码段(无Vue)。
HTML
<p @keydown='evaluate($event)' id='text' contenteditable>
Some text
</p>
JS
evaluate: function(storeResponse = true, event) {
// Stop if any key except comma or backspace was pressed. Only works well with keydown.
if (! [',', 'Backspace'].includes (event.key)) {
event.preventDefault();
return;
}
// Otherwise, copy the updated content. Only works well with keyup.
let textContent = document.getElementById('text').textContent;
// Paste updated content to another p
document.getElementById('original-text').innerText = textContent;
}
document.getElementById('text').addEventListener('keydown', evaluate);
function evaluate() {
// Stop if any key except comma or backspace was pressed.
// Only works well with keydown.
if (![',', 'Backspace'].includes(event.key)) {
event.preventDefault();
return;
}
// Otherwise, copy the updated content. Only works well with keyup.
let textContent = document.getElementById('text').textContent;
// I need to paste the updated content to another div, but just log it for this snippet
console.log(textContent);
}
<p @keydown='evaluate' id='text' contenteditable>
Some text
</p>
是否有一种优雅的方法来限制可能的编辑操作,并获取更新的文本?
答案 0 :(得分:0)
这是在单个事件中执行此操作的一种方法:
new Vue({
el: '#app',
data: () => ({
content: ''
}),
methods: {
evaluate(event) {
// Stop if any key except comma or backspace was pressed. Only works well with keydown.
if (![',', 'Backspace'].includes(event.key)) {
event.preventDefault();
return;
}
// Otherwise, copy the updated content.
const el = event.target;
// Paste updated content to another p
this.content = el.textContent;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p @keydown='evaluate' contenteditable>
Start typing...
</p>
<br />
<p v-text="content">
Updated text goes here.
</p>
</div>
传递不带任何参数的方法名称并括住括号将自动将关联的Event
数据对象传递给幕后方法,如果执行了键盘事件,则KeyboardEvent
数据对象将传递给方法。
因此,以下几行实际上是等效的:
<p @keydown='evaluate($event)'></p>
<!-- Or -->
<p @keydown='evaluate'></p>
答案 1 :(得分:0)
这是根据Yom S.的答案编写的摘要。
new Vue({
el: '#app',
data: () => ({
content: ''
}),
methods: {
/**
* Checks whether the keypress should be processed.
*/
checkKey: function() {
// Users may only navigate or enter/delete commas
let permittedKeys = [
',',
'Backspace',
'ArrowLeft',
'ArrowRight',
'ArrowDown',
'ArrowUp'
];
if (! permittedKeys.includes (event.key)) {
event.preventDefault();
}
},
evaluate(event) {
// Stop if any key except comma or backspace was pressed. Only works well with keydown.
if (![',', 'Backspace'].includes(event.key)) {
event.preventDefault();
return;
}
// Otherwise, copy the updated content.
const el = event.target;
// Paste updated content to another p
this.content = el.textContent;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p @keydown='checkKey' @keyup='evaluate' contenteditable>
Start typing...
</p>
<br />
<p v-text="content">
Updated text goes here.
</p>
</div>
运行该代码段时,您会看到仍然可以删除除逗号以外的其他字符。 AFAIK,不可能从关键事件中获取已删除的字符,因此唯一的机会似乎是撤消此类删除。为此,我从编辑后的文本和以前的版本中都删除了所有逗号。如果这些字符串不同,则将先前版本复制到contenteditable
元素。