Javascript CSS::contenteditable中元素的焦点

Javascript CSS::contenteditable中元素的焦点,javascript,html,css,focus,contenteditable,Javascript,Html,Css,Focus,Contenteditable,如果您有以下HTML: <div contenteditable="true"> <p>The first paragraph</p> <p>The second paragraph</p> </div> 不会应用于正在编辑的段落 这是一个你可以玩的游戏 我如何以不同的方式编辑-标记中的段落 我更喜欢只使用CSS的解决方案,但也许我必须使用JavaScript 编辑: 因为我们找不到一个纯CSS解决方案,而使用:h

如果您有以下HTML:

<div contenteditable="true">
  <p>The first paragraph</p>
  <p>The second paragraph</p>
</div>
不会应用于正在编辑的段落

这是一个你可以玩的游戏

我如何以不同的方式编辑-标记中的段落

我更喜欢只使用CSS的解决方案,但也许我必须使用JavaScript

编辑:


因为我们找不到一个纯CSS解决方案,而使用:hover对我来说不是一个真正的解决方案,所以我现在正在寻找一些JavaScript行,它们将属性class=focus设置在正在编辑的节点上。

有趣的问题。如果可行,我建议将contenteditable属性移动到ps本身:

编辑:这是另一个版本,它使para返回生成para而不是DIV:

以下是不完美的,因为您的鼠标需要与所选段落位于同一区域才能保持:hover参数为true,但由于通常情况下都是这样,所以这应该是好的-如果您希望保持标记的原样,这将是最好的选择:

CSS:

HTML:

HTML:


我想我找到了解决办法

使用以下代码段,您可以在选择更改时在当前插入符号位置获取父元素

var selectedElement = null;
function setFocus(e) {
  if (selectedElement)
    selectedElement.style.outline = 'none';

  selectedElement = window.getSelection().focusNode.parentNode;
  // walk up the DOM tree until the parent node is contentEditable
  while (selectedElement.parentNode.contentEditable != 'true') {
    selectedElement = selectedElement.parentNode;
  }
  selectedElement.style.outline = '1px solid #f00';
};
document.onkeyup = setFocus;
document.onmouseup = setFocus;
在这里,我手动更改outline属性,但是您当然可以添加一个class属性,并通过CSS设置样式

您仍然需要手动检查selectedElement是否是contenteditable属性的子元素。但我认为你可以得到基本的想法

这是我的建议


编辑:我更新了代码和JSFIDLE,使其在Firefox和InternetExplorer9+中也能工作。不幸的是,这些浏览器没有onselectionchange事件处理程序,因此我不得不使用onkeyup和onmouseup。

请给我一个提示,说明如果你否决我的问题,我可以如何改进它。唉,我差点让它工作了-,只是在未选中边框时似乎无法删除它。@Zenith nice Approach您只需要在每个p@optim请看下面的答案。这通常是我想要的,但它会带来一些副作用:比如说我在最后一段末尾点击了return。在我的版本中,添加了一个新段落。在您的版本中,它将在其中插入一个。奇怪的行为…:天哪,真奇怪。好吧,我添加了另一个似乎有效的例子。唯一的问题是,我还必须添加悬停样式,以便集中精力处理段落。很抱歉,悬停状态对我来说不是一个选项,因为我想指出哪一段你正在编辑,即使你不使用鼠标。也许我必须解决插入问题,或者我可以通过JavaScript找到当前光标位置周围的元素。我更新了问题,所以JavaScript解决方案通常是受欢迎的。嗯,最好不要在段落周围有内联跨距,虽然至少从验证的角度来看是这样。第二个是我在第一次回复中发布的,但它有一个问题,即当您按Enter/Return时,它会创建一个新的而不是一个新的,因此我进行了第二次尝试。@Zenith嗯,至少在Chrome中是这样。在Firefox中,它创建了一个很好的应用程序。这在Firefox或IE10中不起作用,可能所有旧的IE都不起作用。谢谢你的提示。我来看看。这正是我的建议。一件事是,如果用户将某些文本设置为粗体,然后将插入符号放在粗体文本中,则此操作将失败,因为window.getSelection.focusNode.parentNode现在将是粗体元素,而不是段落。我建议迭代parentNodes,直到找到元素为止;看见还有一件小事:选择可以在不触发键或鼠标事件的情况下通过浏览器菜单中的“选择所有选项”进行更改,例如,因此您可能需要一个轮询解决方案作为后备方案。@TimDown是的,没错。如果中的标记不同,则将失败。在DOM树上行走是我希望一个人可以自己想象的事情。轮询解决方案总是有点粗糙,但为了完整性,我可能不得不添加它。虽然我想不出有哪一种情况可以让人在不启动鼠标或按键的情况下选择一个段落。干得好,伙计们。我要做的一个改变是使用大纲而不是边框,因为这样在添加和删除边框时,段落不会跳跃。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">

div > p:focus {outline: 1px solid red; }

</style>

</head>
<body>

<div>
    <p contenteditable="true">The first paragraph</p>
    <p contenteditable="true">The second paragraph</p>
</div>

</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">

div:focus {outline: none;}
div > p:focus, div > p:hover {outline: 1px solid red; }

</style>

</head>
<body>

<div contenteditable="true">
    <p contenteditable="true">The first paragraph</p>
    <p contenteditable="true">The second paragraph</p>
</div>

</body>
</html>
div[contenteditable="true"]:focus > p:hover {
   border: 2px solid red;
}
<div contenteditable="true">
   <p>The first paragraph</p>
   <p>The second paragraph</p>
</div>
p[contenteditable="true"]:focus {
   border: 2px solid red;
}
<div>
   <p contenteditable="true">The first paragraph</p>
   <p contenteditable="true">The second paragraph</p>
</div>
var selectedElement = null;
function setFocus(e) {
  if (selectedElement)
    selectedElement.style.outline = 'none';

  selectedElement = window.getSelection().focusNode.parentNode;
  // walk up the DOM tree until the parent node is contentEditable
  while (selectedElement.parentNode.contentEditable != 'true') {
    selectedElement = selectedElement.parentNode;
  }
  selectedElement.style.outline = '1px solid #f00';
};
document.onkeyup = setFocus;
document.onmouseup = setFocus;