【问题标题】:CSS: :focus of elements within contenteditableCSS: :contenteditable 中元素的焦点
【发布时间】:2013-05-25 19:50:28
【问题描述】:

如果您有以下 HTML:

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

有没有办法让正在编辑的段落与div 中的所有其他段落(即contenteditable)中的所有其他段落不同?

div > p:focus { border: 1px solid red }

不会应用于正在编辑的段落。

这是一个JSFiddle,你可以玩。

如何以不同的方式设置正在编辑的段落&lt;p&gt;-tag)?

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

编辑:

由于我们找不到纯 CSS 解决方案(并且使用 :hover 对我来说不是真正的解决方案),我现在正在寻找一些 JavaScript 行,它们在正在编辑的节点上设置属性 class="focus"

【问题讨论】:

  • 如果您投反对票,请给我一个提示,告诉我如何改进我的问题。
  • 呸,我几乎让它工作了 - jsfiddle.net/PPNE2/7,只是在未选中时似乎无法删除边框。
  • @Zenith 不错的方法
  • 您只需将contenteditable="true" 与每个p 放在一起
  • @optim 请看下面的答案。

标签: javascript html css focus contenteditable


【解决方案1】:

我想我找到了解决办法。

使用下面的代码sn-p可以在选择改变时获取当前插入位置的父元素。

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 属性,但您当然可以添加一个类属性并通过 CSS 设置样式。

您仍然需要手动检查 selectedElement 是否是具有 contenteditable 属性的 &lt;div&gt; 的子代。但我认为您可以了解基本概念。

这是updated JSFiddle

编辑:我更新了代码以及 JSFiddle,使其也可以在 Firefox 和 Internet Explorer 9+ 中运行。不幸的是,这些浏览器没有onselectionchange 事件处理程序,所以我不得不使用onkeyuponmouseup

【讨论】:

  • 这在 Firefox 或 IE10 中不起作用(可能所有较旧的 IE 也一样)。
  • 感谢您的提示。我去看看。
  • +1。这几乎就是我所建议的。一件事是,如果用户将某些文本加粗,然后将插入符号放在粗体文本中,这将失败,因为window.getSelection().focusNode.parentNode 现在将是粗体元素而不是段落。我建议您遍历parentNodes,直到您找到&lt;p&gt; 元素;见stackoverflow.com/a/4642894/96100。另一件小事:选择可以在不触发键或鼠标事件的情况下更改(例如,通过浏览器菜单中的全选选项),因此您可能需要轮询解决方案作为后备。
  • @TimDown 是的,没错。如果&lt;div contenteditable="true"&gt; 中的标记不同,它将失败。走上 DOM 树是我希望一个人可以自己解决的问题。轮询解决方案总是有点 hacky,但可能我必须添加它以确保完整性。 (虽然我想不出在&lt;div&gt; 中选择single 段落而不触发鼠标或按键事件的情况。)
  • firefox 52 现在支持onselectionchange
【解决方案2】:

有趣的问题。如果可行,我建议将 contenteditable 属性移至ps 本身:http://codepen.io/pageaffairs/pen/FHKAC

<!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>

编辑:这是另一个版本,它导致 para 返回生成 paras 而不是 div:http://codepen.io/pageaffairs/pen/dbyIa

<!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>

【讨论】:

  • 这通常是我想要的,但它带有一些副作用:假设我在最后一段的末尾点击了返回。在我的版本中,添加了一个新段落。在您的版本中,它将在该&lt;p&gt; 中插入一个&lt;div&gt;。奇怪的行为... :(
  • 天哪,这很奇怪。好吧,我添加了另一个似乎可行的示例。唯一的问题是,我还必须添加悬停样式才能将重点放在段落上。去图吧。
  • 很抱歉,我不能选择悬停状态,因为即使您不使用鼠标,我也想指出您正在编辑的段落。也许我必须解决 &lt;div&gt; 插入问题,或者我可以通过 JavaScript 找出当前光标位置周围的元素。
  • 我更新了问题,所以 JavaScript 解决方案普遍受到欢迎。
【解决方案3】:

jsFiddle here.

以下内容是不完美的,因为您的鼠标需要与所选段落位于同一区域(以保持:hover 参数为真),但无论如何通常都是这种情况,这应该没问题 -如果您想保持标记保持原样,这是您将获得的最佳效果:

CSS:

div[contenteditable="true"]:focus > p:hover {
   border: 2px solid red;
}

HTML:

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

jsFiddle here.

如果您能够更改标记,则可以使用以下简化选择器:

CSS:

p[contenteditable="true"]:focus {
   border: 2px solid red;
}

HTML:

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

【讨论】:

  • 嗯,最好不要在段落周围使用内联跨度——至少从验证的角度来看是这样。
  • 第二个是我在第一个回复中发布的,但它的问题是,当您按 Enter/Return 时,它会创建一个新的 &lt;div&gt; 而不是新的 &lt;p&gt;,因此我的第二次尝试。
  • @Zenith 好吧,至少在 Chrome 中是这样。在 Firefox 中,它会创建一个 &lt;br&gt;,这很好。
猜你喜欢
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 2016-06-03
相关资源
最近更新 更多