单击contenteditable div stills会使其更有重点吗?

时间:2021-07-21 04:31:26

For some reason I need to use contenteditable div instead of normal text input for inputting text. (for some javascript library) It works fine until I found that when I set the contenteditable div using display: inline-block, it gives focus to the div even if I click outside the div!

出于某种原因,我需要使用contenteditable div而不是常规的文本输入来输入文本。(对于一些javascript库)它工作得很好,直到我发现当我使用display: inline-block设置contenteditable div时,即使我在div之外单击它,它也会关注div!

I need it to be giving focus to the div only when the user clicks right onto the div but not around it. Currently, I found that when the user clicks elsewhere and then click at position that is the same row as the div, it gives focus to it.

我需要它只在用户点击div时关注div而不是在它周围。目前,我发现,当用户单击其他地方,然后单击与div相同的位置时,它会对其进行关注。

A simple example to show the problem:

一个简单的例子来说明这个问题:

HTML:

HTML:

<div class="outside">
    <div class="text-input" contenteditable="true">
        Input 1
    </div>
    <div class="text-input" contenteditable="true">
        Input 2
    </div>
    <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
    </div>
</div>

CSS:

CSS:

div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
}

The JSFiddle for displaying the problem

用于显示问题的JSFiddle

Is there a way (CSS or javascript are both acceptable) to make the browser only give focus to div when it is clicked instead of clicking the same row?

是否有一种方法(CSS或javascript都可以接受)让浏览器只在单击时关注div,而不是单击同一行?

P.S. I noticed that there are similar problem (link to other related post), but the situation is a bit different and the solution provided is not working for me.

附注:我注意到也有类似的问题(链接到其他相关岗位),但是情况有点不同,提供的解决方案对我来说并不适用。

5 个解决方案

#1


18  

Explanation (if you don't care, skip to the Workarounds section below)

解释(如果您不介意,请跳到下面的工作区部分)

When you click in an editable element, the browser places a cursor (a.k.a. insertion point) in the nearest text node that is within the clicked element, on the same line as your click. The text node may be either directly within the clicked element, or in one of its child elements. You can verify this by running the code snippet below and clicking around in the output.

当您单击可编辑元素时,浏览器将光标(即插入点)放置在单击元素中最近的文本节点中,与单击位于同一行。文本节点可以直接位于单击的元素中,也可以位于其子元素之一中。您可以通过运行下面的代码片段并在输出中单击来验证这一点。

.container {width: auto; padding: 30px; background: tan;}
.container * {margin: 4px; padding: 4px;}
div {width: 50%; background: lightgreen;}
span {background: orange;}
span > span {background: gold;}
span > span > span {background: yellow;}
<div class="container" contenteditable>
  text
  <div>
    text in a div
  </div>
  <span><span><span>text in spans</span></span></span></div>
Notice that you can get an insertion point by clicking above the first line or below the last. Some of the other answers don't account for this!

The large tan box is a <div> with the contenteditable attribute, and the inner colored boxes are nested child elements. Notice that if you click near (but not in) one of the child elements, the cursor ends up inside it, even though you clicked outside. This is not a bug. Since the element you clicked on (the tan box) is editable and the child element is part of its content, it makes sense to place the cursor in the child element if that's where the nearest text node happens to be.

大的tan box是一个

,带有contenteditable属性,而内色框是嵌套的子元素。请注意,如果单击子元素之一的near(而不是in),那么光标将在其中结束,即使您在外部单击。这不是一个bug。由于您单击的元素(tan框)是可编辑的,子元素是其内容的一部分,所以如果最近的文本节点在子元素中,那么将光标放在子元素中是有意义的。

What doesn't make sense is the way Webkit browsers (Chrome, Safari, Opera) behave when you click on an element that is not editable. You wouldn't expect them to even bother looking at the nearest text node in this case, but they do, and if it's editable, they add an insertion point. I'd consider that a bug. Webkit browsers are doing this:

当你点击一个不可编辑的元素时,Webkit浏览器(Chrome, Safari, Opera)的运行方式是不合理的。在这种情况下,您甚至不会期望他们去查看最近的文本节点,但是他们做了,如果它是可编辑的,他们会添加一个插入点。我认为那是个错误。Webkit浏览器正在这样做:

on click:
  find nearest text node within clicked element;
  if text node is editable:
    add insertion point;

...when they should be doing this:

…当他们应该这样做的时候:

on click:
  if clicked element is editable:
    find nearest text node within clicked element;
    add insertion point;

Block elements (such as divs) don't seem to be affected by the bug, which makes me think @GOTO 0's answer is correct in implicating text selection-- at least insofar as it seems to be governed by the same logic that controls insertion point placement. Normally, you can select the text within an element by multi-clicking outside the element, but it doesn't work if the element happens to be a block. It's probably no coincidence that external clicks also don't trigger insertion point placement in a block. The first workaround below makes use of this behavior.

块元素(比如div)似乎不受这个bug的影响,这让我认为@GOTO 0的答案在暗示文本选择方面是正确的——至少在控制插入点位置的逻辑上是正确的。通常,您可以通过在元素外面多单击来选择元素中的文本,但是如果元素恰好是块,那么它将不起作用。外部点击也不会在一个块中触发插入点,这可能不是巧合。下面的第一个解决方案利用了这种行为。


Workaround 1

解决方案1

Since blocks aren't affected by the bug, I think the best solution is to nest a div in the inline-block and make it editable instead. Inline-blocks already behave like blocks internally, so the div should have no effect on its behavior.

由于块不受bug的影响,我认为最好的解决方案是将div嵌套到内联块中,并使其可编辑。内联块在内部已经表现为块,所以div不应该影响它的行为。

div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
}
<div class="outside">
    <div class="text-input">
      <div contenteditable>
        Input 1
      </div>
    </div>
    <div class="text-input">
      <div contenteditable>
        Input 2
      </div>
    </div>
    <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
    </div>
</div>


Workaround 2

解决方案2

If you must put the contenteditable attribute on the inline-blocks, this solution will allow it. It works by surrounding each editable block with invisible characters (specifically, zero-width spaces) which shield it from external clicks. (GOTO 0's answer uses the same principle, but it still had some problems last I checked).

如果您必须将contenteditable属性放在行块上,这个解决方案将允许这样做。它的工作原理是围绕每个可编辑的块(特别是,零宽度的空间),屏蔽外部的点击。(GOTO 0的答案使用了相同的原则,但它仍然有一些问题,我上次检查过)。

div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
  white-space: normal;
}
.input-container {white-space: nowrap;}
<div class="outside">
  <span class="input-container">&#8203;<div class="text-input" contenteditable>
    Input 1
  </div>&#8203;</span>
  <span class="input-container">&#8203;<div class="text-input" contenteditable>
    Input 2
  </div>&#8203;</span>
  <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
  </div>
</div>


Workaround 3

解决方案3

If you absolutely can't change your markup, then this JavaScript-based solution could work as a last resort (inspired by this answer). It sets contentEditable to true when the inline-blocks are clicked, and false when they lose focus.

如果您绝对不能更改标记,那么这个基于javascript的解决方案可以作为最后的解决方案(受这个答案的启发)。它将contentEditable设置为true,当inline-block被单击时,当它们失去焦点时就会出错。

(function() {
  var inputs = document.querySelectorAll('.text-input');
  for(var i = inputs.length; i--;) {
    inputs[i].addEventListener('click', function(e) {
      e.target.contentEditable = true;
      e.target.focus();
    });
    inputs[i].addEventListener('blur', function(e) {
      e.target.contentEditable = false;
    });
  }
})();
div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
}
<div class="outside">
    <div class="text-input">
      Input 1
    </div>
    <div class="text-input">
      Input 2
    </div>
    <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
    </div>
</div>

#2


9  

I was able to reproduce this behavior only in Chrome and Safari, suggesting that this may be a Webkit related issue.

我只能在Chrome和Safari中复制这种行为,这表明这可能是与Webkit相关的问题。

It's hard to tell what's going on without inspecting the code but we can at least suspect that the problem lies in some faulty mechanism that triggers text selection in the browser. For analogy, if the divs were not contenteditable, clicking in the same line of text after the last character would trigger a text selection starting at the end of the line.

如果不检查代码,就很难知道发生了什么,但我们至少可以怀疑,问题出在触发浏览器中的文本选择的某种错误机制上。打个比方,如果div不是contenteditable,那么在最后一个字符之后单击同一行文本将触发从行尾开始的文本选择。

The workaround is to wrap the contenteditable divs into a container element and style the container with -webkit-user-select: none to make it unselectable.

解决方案是将contenteditable div包装到容器元素中,并使用-webkit-user-select: none对容器进行样式化,以使其不可选。

As Alex Char points out in a comment, this will not prevent a mouse click outside the container to trigger a selection at the start of the text inside it, since there is no static text between the first contenteditable div and the (selectable) ancestor container around it. There are likely more elegant solutions, but a way to overcome this problem is to insert an invisible, nonempty span of text of zero width just before the first contenteditable div to capture the unwanted text selection.

正如Alex Char在评论中指出的,这不会阻止鼠标在容器外单击,在容器内部的文本开始时触发一个选择,因为在第一个contenteditable div和(可选的)祖先容器之间没有静态文本。可能有更优雅的解决方案,但是解决这个问题的方法是在第一个contenteditable div之前插入一个不可见的、非空的、零宽度的文本跨度,以捕获不需要的文本选择。

  • Why non empty?: Because empty elements are ignored upon text selection.
  • 为什么非空的吗?:因为在文本选择时忽略了空元素。
  • Why zero width?: Because we don't want to see it...
  • 为什么零宽度?因为我们不想看到它……
  • Why invisible?: Because we don't want the content to be copied to the clipboard with, say Ctrl+A, Ctrl+C.
  • 为什么看不见呢?:因为我们不希望内容被复制到剪贴板上,按Ctrl+A, Ctrl+C。

div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
}
div.text-input-container {
  -webkit-user-select: none;
}
.invisible {
  visibility: hidden;
}
<div class="outside">
    <div class="text-input-container">
        <span class="invisible">&#8203;</span><div class="text-input" contenteditable="true">
            Input 1
        </div>
        <div class="text-input" contenteditable="true">
            Input 2
        </div>
    </div>
    <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
    </div>
</div>

Even in normal circumstances it is generally a good idea to keep adjacent inline-block elements in a separate container rather than next to a block element (like the unrelated div) to prevent unexpected layout effects in case the order of the sibling elements changes.

即使在正常情况下,最好将相邻的内联块元素保存在单独的容器中,而不是放在块元素(如不相关的div)旁边,以防止在兄弟元素的顺序发生变化时出现意外的布局效果。

#3


1  

If it's not needed to use display: inline-block, I would recommend using float. Here is the example.

如果不需要使用display: inline-block,我建议使用float。这是例子。

Based on your example, the new CSS would be:

基于您的示例,新的CSS将是:

div.text-input {
  display: block;
  background-color: black;
  color: white;
  width: 300px;
  float: left;
  margin-right: 10px;
}
div.unrelated {
  clear: both;
}

#4


0  

Disable text selection in container... should fix that.

禁用容器中的文本选择…应该解决这个问题。

For example:

例如:

* {
   -ms-user-select: none; /* IE 10+ */
   -moz-user-select: -moz-none;
   -khtml-user-select: none;
   -webkit-user-select: none;
   user-select: none;
}

#5


0  

How about a little jQuery?

来点jQuery怎么样?

$(".outside").click(function(e){
    $(e.target).siblings(".text-input").blur();
    window.getSelection().removeAllRanges();
});

And if IRL you need to account for clicks on contenteditable=true siblings' children:

如果IRL,你需要对contenteditable=真正的兄弟姐妹的孩子进行说明:

$(".outside").click(function(e){
    if ($(e.target).siblings(".text-input").length != 0){
        $(e.target).siblings(".text-input").blur();
        window.getSelection().removeAllRanges();
    } 
    else {
        $(e.target).parentsUntil(".outside").last().siblings(".text-input").blur();
        window.getSelection().removeAllRanges();
    }
});

window.getSelection().removeAllRanges();"The trick is to remove all ranges after calling blur"

.removeAllRanges window.getSelection()();“诀窍是在调用blur(模糊)后删除所有范围”

#1


18  

Explanation (if you don't care, skip to the Workarounds section below)

解释(如果您不介意,请跳到下面的工作区部分)

When you click in an editable element, the browser places a cursor (a.k.a. insertion point) in the nearest text node that is within the clicked element, on the same line as your click. The text node may be either directly within the clicked element, or in one of its child elements. You can verify this by running the code snippet below and clicking around in the output.

当您单击可编辑元素时,浏览器将光标(即插入点)放置在单击元素中最近的文本节点中,与单击位于同一行。文本节点可以直接位于单击的元素中,也可以位于其子元素之一中。您可以通过运行下面的代码片段并在输出中单击来验证这一点。

.container {width: auto; padding: 30px; background: tan;}
.container * {margin: 4px; padding: 4px;}
div {width: 50%; background: lightgreen;}
span {background: orange;}
span > span {background: gold;}
span > span > span {background: yellow;}
<div class="container" contenteditable>
  text
  <div>
    text in a div
  </div>
  <span><span><span>text in spans</span></span></span></div>
Notice that you can get an insertion point by clicking above the first line or below the last. Some of the other answers don't account for this!

The large tan box is a <div> with the contenteditable attribute, and the inner colored boxes are nested child elements. Notice that if you click near (but not in) one of the child elements, the cursor ends up inside it, even though you clicked outside. This is not a bug. Since the element you clicked on (the tan box) is editable and the child element is part of its content, it makes sense to place the cursor in the child element if that's where the nearest text node happens to be.

大的tan box是一个

,带有contenteditable属性,而内色框是嵌套的子元素。请注意,如果单击子元素之一的near(而不是in),那么光标将在其中结束,即使您在外部单击。这不是一个bug。由于您单击的元素(tan框)是可编辑的,子元素是其内容的一部分,所以如果最近的文本节点在子元素中,那么将光标放在子元素中是有意义的。

What doesn't make sense is the way Webkit browsers (Chrome, Safari, Opera) behave when you click on an element that is not editable. You wouldn't expect them to even bother looking at the nearest text node in this case, but they do, and if it's editable, they add an insertion point. I'd consider that a bug. Webkit browsers are doing this:

当你点击一个不可编辑的元素时,Webkit浏览器(Chrome, Safari, Opera)的运行方式是不合理的。在这种情况下,您甚至不会期望他们去查看最近的文本节点,但是他们做了,如果它是可编辑的,他们会添加一个插入点。我认为那是个错误。Webkit浏览器正在这样做:

on click:
  find nearest text node within clicked element;
  if text node is editable:
    add insertion point;

...when they should be doing this:

…当他们应该这样做的时候:

on click:
  if clicked element is editable:
    find nearest text node within clicked element;
    add insertion point;

Block elements (such as divs) don't seem to be affected by the bug, which makes me think @GOTO 0's answer is correct in implicating text selection-- at least insofar as it seems to be governed by the same logic that controls insertion point placement. Normally, you can select the text within an element by multi-clicking outside the element, but it doesn't work if the element happens to be a block. It's probably no coincidence that external clicks also don't trigger insertion point placement in a block. The first workaround below makes use of this behavior.

块元素(比如div)似乎不受这个bug的影响,这让我认为@GOTO 0的答案在暗示文本选择方面是正确的——至少在控制插入点位置的逻辑上是正确的。通常,您可以通过在元素外面多单击来选择元素中的文本,但是如果元素恰好是块,那么它将不起作用。外部点击也不会在一个块中触发插入点,这可能不是巧合。下面的第一个解决方案利用了这种行为。


Workaround 1

解决方案1

Since blocks aren't affected by the bug, I think the best solution is to nest a div in the inline-block and make it editable instead. Inline-blocks already behave like blocks internally, so the div should have no effect on its behavior.

由于块不受bug的影响,我认为最好的解决方案是将div嵌套到内联块中,并使其可编辑。内联块在内部已经表现为块,所以div不应该影响它的行为。

div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
}
<div class="outside">
    <div class="text-input">
      <div contenteditable>
        Input 1
      </div>
    </div>
    <div class="text-input">
      <div contenteditable>
        Input 2
      </div>
    </div>
    <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
    </div>
</div>


Workaround 2

解决方案2

If you must put the contenteditable attribute on the inline-blocks, this solution will allow it. It works by surrounding each editable block with invisible characters (specifically, zero-width spaces) which shield it from external clicks. (GOTO 0's answer uses the same principle, but it still had some problems last I checked).

如果您必须将contenteditable属性放在行块上,这个解决方案将允许这样做。它的工作原理是围绕每个可编辑的块(特别是,零宽度的空间),屏蔽外部的点击。(GOTO 0的答案使用了相同的原则,但它仍然有一些问题,我上次检查过)。

div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
  white-space: normal;
}
.input-container {white-space: nowrap;}
<div class="outside">
  <span class="input-container">&#8203;<div class="text-input" contenteditable>
    Input 1
  </div>&#8203;</span>
  <span class="input-container">&#8203;<div class="text-input" contenteditable>
    Input 2
  </div>&#8203;</span>
  <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
  </div>
</div>


Workaround 3

解决方案3

If you absolutely can't change your markup, then this JavaScript-based solution could work as a last resort (inspired by this answer). It sets contentEditable to true when the inline-blocks are clicked, and false when they lose focus.

如果您绝对不能更改标记,那么这个基于javascript的解决方案可以作为最后的解决方案(受这个答案的启发)。它将contentEditable设置为true,当inline-block被单击时,当它们失去焦点时就会出错。

(function() {
  var inputs = document.querySelectorAll('.text-input');
  for(var i = inputs.length; i--;) {
    inputs[i].addEventListener('click', function(e) {
      e.target.contentEditable = true;
      e.target.focus();
    });
    inputs[i].addEventListener('blur', function(e) {
      e.target.contentEditable = false;
    });
  }
})();
div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
}
<div class="outside">
    <div class="text-input">
      Input 1
    </div>
    <div class="text-input">
      Input 2
    </div>
    <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
    </div>
</div>

#2


9  

I was able to reproduce this behavior only in Chrome and Safari, suggesting that this may be a Webkit related issue.

我只能在Chrome和Safari中复制这种行为,这表明这可能是与Webkit相关的问题。

It's hard to tell what's going on without inspecting the code but we can at least suspect that the problem lies in some faulty mechanism that triggers text selection in the browser. For analogy, if the divs were not contenteditable, clicking in the same line of text after the last character would trigger a text selection starting at the end of the line.

如果不检查代码,就很难知道发生了什么,但我们至少可以怀疑,问题出在触发浏览器中的文本选择的某种错误机制上。打个比方,如果div不是contenteditable,那么在最后一个字符之后单击同一行文本将触发从行尾开始的文本选择。

The workaround is to wrap the contenteditable divs into a container element and style the container with -webkit-user-select: none to make it unselectable.

解决方案是将contenteditable div包装到容器元素中,并使用-webkit-user-select: none对容器进行样式化,以使其不可选。

As Alex Char points out in a comment, this will not prevent a mouse click outside the container to trigger a selection at the start of the text inside it, since there is no static text between the first contenteditable div and the (selectable) ancestor container around it. There are likely more elegant solutions, but a way to overcome this problem is to insert an invisible, nonempty span of text of zero width just before the first contenteditable div to capture the unwanted text selection.

正如Alex Char在评论中指出的,这不会阻止鼠标在容器外单击,在容器内部的文本开始时触发一个选择,因为在第一个contenteditable div和(可选的)祖先容器之间没有静态文本。可能有更优雅的解决方案,但是解决这个问题的方法是在第一个contenteditable div之前插入一个不可见的、非空的、零宽度的文本跨度,以捕获不需要的文本选择。

  • Why non empty?: Because empty elements are ignored upon text selection.
  • 为什么非空的吗?:因为在文本选择时忽略了空元素。
  • Why zero width?: Because we don't want to see it...
  • 为什么零宽度?因为我们不想看到它……
  • Why invisible?: Because we don't want the content to be copied to the clipboard with, say Ctrl+A, Ctrl+C.
  • 为什么看不见呢?:因为我们不希望内容被复制到剪贴板上,按Ctrl+A, Ctrl+C。

div.outside {
  margin: 30px;
}
div.text-input {
  display:inline-block;
  background-color: black;
  color: white;
  width: 300px;
}
div.text-input-container {
  -webkit-user-select: none;
}
.invisible {
  visibility: hidden;
}
<div class="outside">
    <div class="text-input-container">
        <span class="invisible">&#8203;</span><div class="text-input" contenteditable="true">
            Input 1
        </div>
        <div class="text-input" contenteditable="true">
            Input 2
        </div>
    </div>
    <div class="unrelated">This is some unrelated content<br>
      This is some more unrelated content
      This is just some space to shows that clicking here doesn't mess with the contenteditable div
      but clicking the side mess with it.
    </div>
</div>

Even in normal circumstances it is generally a good idea to keep adjacent inline-block elements in a separate container rather than next to a block element (like the unrelated div) to prevent unexpected layout effects in case the order of the sibling elements changes.

即使在正常情况下,最好将相邻的内联块元素保存在单独的容器中,而不是放在块元素(如不相关的div)旁边,以防止在兄弟元素的顺序发生变化时出现意外的布局效果。

#3


1  

If it's not needed to use display: inline-block, I would recommend using float. Here is the example.

如果不需要使用display: inline-block,我建议使用float。这是例子。

Based on your example, the new CSS would be:

基于您的示例,新的CSS将是:

div.text-input {
  display: block;
  background-color: black;
  color: white;
  width: 300px;
  float: left;
  margin-right: 10px;
}
div.unrelated {
  clear: both;
}

#4


0  

Disable text selection in container... should fix that.

禁用容器中的文本选择…应该解决这个问题。

For example:

例如:

* {
   -ms-user-select: none; /* IE 10+ */
   -moz-user-select: -moz-none;
   -khtml-user-select: none;
   -webkit-user-select: none;
   user-select: none;
}

#5


0  

How about a little jQuery?

来点jQuery怎么样?

$(".outside").click(function(e){
    $(e.target).siblings(".text-input").blur();
    window.getSelection().removeAllRanges();
});

And if IRL you need to account for clicks on contenteditable=true siblings' children:

如果IRL,你需要对contenteditable=真正的兄弟姐妹的孩子进行说明:

$(".outside").click(function(e){
    if ($(e.target).siblings(".text-input").length != 0){
        $(e.target).siblings(".text-input").blur();
        window.getSelection().removeAllRanges();
    } 
    else {
        $(e.target).parentsUntil(".outside").last().siblings(".text-input").blur();
        window.getSelection().removeAllRanges();
    }
});

window.getSelection().removeAllRanges();"The trick is to remove all ranges after calling blur"

.removeAllRanges window.getSelection()();“诀窍是在调用blur(模糊)后删除所有范围”