问题不在于e.key === " "
,而是在于内部的if
语句。内部if
始终返回false,无论如何。外面的if
很好。到目前为止,我们认为.innerText
可能是一个问题。最后可能返回一个不同的空格字符。
我想我可能已经发现Java或其他内部错误,因为这不起作用。我试图防止用户使用Javascript在内容可编辑div中的一行中插入多个空格。应该允许用户一次进入一个空间。
This is allowed
This is not
这就是我要尝试的:
document.getElementById("div")
.addEventListener("keydown", function(e) {
if (e.key === " ") {
const text = this.innerText,
i = window.getSelection().anchorOffset;
const chars = text.substring(i - 1, i + 1);
if (chars.includes(" ")) {
e.preventDefault();
return false;
}
}
});
<div contenteditable=true id=div></div>
逻辑对我来说似乎是正确的。问题是它不起作用。我可以插入任意多个空格,而浏览器不在乎。我已经在每个步骤中使用调试器记录了变量,并且变量具有预期的值,但是在评估chars.includes(" ")
时,出于某种原因,即使{{{ 1}}包含一个if
(空格)。难道我做错了什么?请帮忙。
答案 0 :(得分:1)
首先,添加一个keydown
侦听器,以检查最后一次按下的键是这样的:
document.getElementById("div").addEventListener("keydown", function(e) {
});
第二,在该监听器函数中,添加另一个函数,例如stop()
,其中包含要运行的所有代码(例如preventDefault()
,return false
等),如果有人尝试添加两个连续的空格,例如:
document.getElementById("div").addEventListener("keydown", function(e) {
function stop() {
alert("two whitespaces detected");
e.preventDefault();
return false;
}
});
第三,在侦听器内添加if语句,以检查上次按下的键是否为space
,如下所示:
document.getElementById("div").addEventListener("keydown", function(e) {
function stop() {
alert("two whitespaces detected");
e.preventDefault();
return false;
}
if (e.code == "Space" || e.key == " ") {
}
});
第四,将在div上键入的任何值分配给变量,例如将content
用作字符串,还将另一个变量,例如prevVal
分配给变量content
字符串的最后一个字符如下:
document.getElementById("div").addEventListener("keydown", function(e) {
function stop() {
alert("two whitespaces detected");
e.preventDefault();
return false;
}
if (e.code == "Space" || e.key == " ") {
var divContent = e.target;
var content = divContent.innerText;
var prevVal = content.substr(content.length - 1);
}
});
最后,您可以使用另一个if statement
来检查最后按下的键是否为空格,方法是将其与上面分配的变量prevVal
进行比较,然后如果是这样,请运行我们之前编写的stop()函数,如下所示:
document.getElementById("div").addEventListener("keydown", function(e) {
function stop() {
alert("two whitespaces detected");
e.preventDefault();
return false;
}
if (e.code == "Space" || e.key == " ") {
var divContent = e.target;
var content = divContent.innerText;
var prevVal = content.substr(content.length - 1);
if (prevVal.trim() === '') {
stop();
} else {
console.log("nevermind");
}
}
});
查看下面的代码段,或转到此 jsFiddle 以查看上面的代码:
var div = document.getElementById("div");
div.addEventListener("keydown", function(e) {
function stop() {
alert("two whitespaces detected");
e.preventDefault();
return false;
}
if (e.code == "Space" || e.key == " ") {
var divContent = e.target;
var content = divContent.innerText;
var prevVal = content.substr(content.length - 1);
if (prevVal.trim() === '') {
stop();
} else {
console.log("nevermind");
}
}
});
#div {border: 1px solid #000;}
<div contenteditable="true" id="div"></div>
答案 1 :(得分:1)
由于内容可编辑元素的工作方式,因此您键入的空格是不间断空格(ASCII 160)而不是普通空格(ASCII 32)。 HTML默认将多个空格折叠为1,因此在contenteditable中空格必须是不间断的,否则在键入多个空格时不会看到多个空格。
您必须专门检查不间断空格:
function11111
function33333
function22222
document.getElementById("div")
.addEventListener("keydown", function(e) {
if (e.key === " ") {
const text = this.innerText,
i = window.getSelection().anchorOffset;
const chars = text.substring(i - 1, i + 1);
if (chars.includes( String.fromCharCode(160) )) {
e.preventDefault();
return false;
}
}
});
您可能还需要检查正常空格,因为我不确定浏览器之间的行为是否一致。
答案 2 :(得分:1)
好的,你不能在任何地方放置2个空格
编辑:适用于chrome,ff,edge
document.getElementById('div').addEventListener('keydown', function(e) {
if (e.code === 'Space' || e.key === ' ') {
const node = window.getSelection();
const text = node.anchorNode.textContent;
const cur = node.anchorOffset;
const front = text[cur - 1];
const back = text[cur];
const reg = /\s/;
if (reg.test(front) || reg.test(back)) e.preventDefault();
}
});
div {
border: 1px solid tomato;
}
<div contenteditable="true" id="div"></div>
答案 3 :(得分:-1)
更新 此实现会忽略换行符,如果用户添加了换行符,则会导致错误(在我正在实现的应用中,我不允许用户添加任何换行符,因此此实现有效)。有关完整的实现,请查看@WASD的答案。
更新TLDR :当不允许使用“ Enter”键时,可在Firefox,Edge,Safari,Chrome和Opera上实现。
经过一番摸索,我终于找到了解决方案。在firefox中,.innerText
的问题非常严重。因此,我们需要使用.textContent
来代替所有浏览器。如果我们使用.textContent
,则在除Firefox之外的所有浏览器中,当用户按下空格键时,看起来像空格的字符都会添加到内容中,但不是空格。它实际上是一个不同的字符,即ASCII
字符160
。在Firefox中,常规ASCII
字符32
用于空格。现在,有了这些信息,我们就可以开始解决问题了。这是一个跨浏览器的实现方式。
document.getElementById("div")
.addEventListener("keydown", function(e) {
if (e.key === " ") {
const text = this.textContent,
i = window.getSelection().anchorOffset;
const chars = text.substring(i - 1, i + 1);
if (chars.includes(" ") ||
chars.includes(String.fromCharCode(160))) {
e.preventDefault();
return false;
}
}
});
<div style="border: 2px solid black;" contenteditable=true id=div></div>
首先,我们使用.textContent
代替.innerText
。此外,在if
语句中,我们检查内容可编辑div
中的文本是否包含常规的space
字符(ASCII 32
),并且还检查其是否包含{{ 1}},除FF外,每个浏览器都使用。如果文本包含160或32个字符,则我们需要ASCII 160
并阻止用户连续添加多个空格字符。