如果为true,则if语句的计算结果为false

时间:2018-12-25 21:22:42

标签: javascript html substring

更新

问题不在于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(空格)。难道我做错了什么?请帮忙。

4 个答案:

答案 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并阻止用户连续添加多个空格字符。