Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在contenteditable div外部单击仍会使其成为焦点?_Javascript_Html_Css - Fatal编程技术网

Javascript 在contenteditable div外部单击仍会使其成为焦点?

Javascript 在contenteditable div外部单击仍会使其成为焦点?,javascript,html,css,Javascript,Html,Css,出于某种原因,我需要使用contenteditable div而不是普通的文本输入来输入文本。(对于某些javascript库)它工作得很好,直到我发现当我使用display:inline block设置contenteditable div时,即使在div外部单击,它也会将焦点放在div上 我需要它只在用户右键点击div时才关注div,而不是在div周围。目前,我发现当用户在别处单击,然后在与div相同的行的位置单击时,它会将焦点放在div上 下面是一个简单的示例来说明问题: HTML: 有

出于某种原因,我需要使用contenteditable div而不是普通的文本输入来输入文本。(对于某些javascript库)它工作得很好,直到我发现当我使用
display:inline block
设置contenteditable div时,即使在div外部单击,它也会将焦点放在div上

我需要它只在用户右键点击div时才关注div,而不是在div周围。目前,我发现当用户在别处单击,然后在与div相同的行的位置单击时,它会将焦点放在div上

下面是一个简单的示例来说明问题:

HTML:

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


另外,我注意到有类似的问题(),但情况有点不同,提供的解决方案对我不起作用。

如果不需要使用
display:inline block
,我建议使用float

根据您的示例,新的CSS将是:

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

我只能在Chrome和Safari中重现这种行为,这表明这可能是一个与Webkit相关的问题

在不检查代码的情况下很难判断发生了什么,但我们至少可以怀疑问题在于触发浏览器中文本选择的某些错误机制。 类似地,如果
div
s不可编辑,则单击最后一个字符后的同一行文本将触发从该行末尾开始的文本选择

解决方法是将contenteditable
div
s包装到容器元素中,并使用
-webkit user select:none
设置容器样式,使其不可选择

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

  • 为什么非空?:因为在选择文本时忽略空元素
  • 为什么是零宽度?:因为我们不想看到它
  • 为什么不可见?:因为我们不希望内容被复制到剪贴板,比如说Ctrl+A,Ctrl+C
div.out{
利润率:30像素;
}
div.text-input{
显示:内联块;
背景色:黑色;
颜色:白色;
宽度:300px;
}
div.text-input-container{
-webkit用户选择:无;
}
.无形的{
可见性:隐藏;
}

​
输入1
输入2
这是一些不相关的内容
这是一些更不相关的内容 这只是一些空间,表明单击此处不会弄乱contenteditable div 但是点击侧面会弄乱它。
禁用容器中的文本选择。。。应该解决这个问题

例如:

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

解释(如果您不在意,请跳到下面的解决方法

在图元中单击时,浏览器会将光标(又称光标)放置在所单击图元内最近的位置,与单击位置在同一行。文本节点可以直接位于单击的元素中,也可以位于其子元素之一中。您可以通过运行下面的代码段并在蓝色大框中单击来验证这一点

.container{宽度:自动;填充:20px;背景:矢车菊蓝;}
.container*{margin:4px;padding:4px;}
div{宽度:50%;背景:金色;}
span{背景:橙色;}
span>span{背景:金色;}
span>span>span{背景:黄色;}

可编辑元素中的文本
嵌套div中的文本
深度嵌套跨度中的文本

请注意,可以通过单击第一行上方或最后一行下方来获取插入点。这是因为这些行的“hitbox”分别延伸到容器的顶部和底部。其他一些答案不能解释这一点来一点jQuery怎么样

$(".outside").click(function(e){
    $(e.target).siblings(".text-input").blur();
    window.getSelection().removeAllRanges();
});
如果IRL需要说明单击兄弟姐妹的孩子的原因:

$(".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()

不确定问题出在哪里,但这起作用了……嗯。。。它是有效的,但我不知道为什么。@yjs你想回答这个问题吗?如果你想回答这个问题,请也弄清楚它为什么有效。我想它会聚焦于单击的div。。。在Chrome上仍然不起作用。当你点击这些div的上方(边距区域)时进行检查。@AlexChar谢谢你看到这一点。更新了我的答案。仍然有Alex指出的相同问题。真正奇怪的是,如果你点击中间的左边,第一个div会被选中,但中间右边的第二个div会被选中,即使在这两种情况下,您都在第一个div上方单击。这在Safari for Windows中似乎有效的原因是,当存在
-webkit user select:none
属性时,它错误地使内联块完全不可编辑。我猜不然就不行了。总之,我有一个想法:如果使用
:before
伪元素插入
&zwnj也许你可以去掉匿名跨度。伪元素会添加一个不需要的空格,除非你将所有代码放在一行:/。所以我想这并不完美。无论如何,我还有一个想法,然后我就不打扰你了:零宽度空间(
​;
\200B
)可能比零宽度非连接者更好,因为后者用于控制。只是一个技术性的问题,但没什么坏处。为什么你甚至需要包括
$(".outside").click(function(e){
    $(e.target).siblings(".text-input").blur();
    window.getSelection().removeAllRanges();
});
$(".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();
    }
});