【问题标题】:CSS on :focus within child of contenteditableCSS on :focus 在 contenteditable 的子项内
【发布时间】:2015-04-30 09:08:17
【问题描述】:

出于纯 CSS 样式的目的,我正在尝试在 contenteditable 元素的子元素上检测 focus。 (我知道我可以用 JS 检测到这一点,添加一个额外的类并这样做,但这太啰嗦了。)

基本上,我有以下几点:

<div contenteditable="true">
  Some text <span class="edit">that</span> goes here.
</div>

我尝试了 CSS:

.edit:focus {
  color: #FF0000;
}

我希望span 在插入符号进入时改变颜色,但显然焦点仅应用于设置为contenteditablediv,而不应用于其中的任何子项。我尝试将第二个contenteditable 应用到span,但除了是一种非常草率的方法之外,它无论如何也不起作用。

有解决办法吗?

【问题讨论】:

  • 基于提供的解决方案的说明 - 我有 div[contenteditable=true] 样式,所以 focus 状态需要保持在 div

标签: css contenteditable


【解决方案1】:

由于contenteditable 元素中的元素通常无法获得焦点的限制,我建议通过在&lt;span&gt; 元素中包含选择时添加一个类来伪造它,您可以通过监视来做到这一点更改选择(您必须使用鼠标和键盘事件并在 Firefox until the selectionchange event is implemented in that browser 中轮询彻底性)。

var selectionContainer = null;

function updateSelectionContainer() {
  var newSelectionContainer = null;
  var sel;
  if (window.getSelection && (sel = window.getSelection()).rangeCount) {
    newSelectionContainer = sel.getRangeAt(0).commonAncestorContainer;

    // Ensure we have an element rather than a text node
    if (newSelectionContainer.nodeType != 1) {
      newSelectionContainer = newSelectionContainer.parentNode;
    }
  }
  if (newSelectionContainer != selectionContainer) {
    if (selectionContainer) {
      selectionContainer.className = selectionContainer.className.replace(/ ?containsSelection/, "");
    }
    if (newSelectionContainer) {
      newSelectionContainer.className +=
        (newSelectionContainer.className ? " containsSelection" : "containsSelection");
    }
    selectionContainer = newSelectionContainer;
  }
}

if ("onselectionchange" in document) {
  document.onselectionchange = updateSelectionContainer;
} else {
  var el = document.getElementById("editor");
  el.onmousedown = el.onmouseup = el.onkeydown = el.onkeyup = el.oninput = updateSelectionContainer;
  window.setInterval(updateSelectionContainer, 100);
}
div {
  font-size: 200%;
}

.edit.containsSelection {
  color: red;
  font-weight: bold;
}
<div contenteditable="true" id="editor">
  Some text <span class="edit">that</span> goes here.
</div>

【讨论】:

  • 谢谢@Tim。监控显然是唯一的出路——尤其是我的实际用例非常复杂,CSS 的单向性无法应对。
【解决方案2】:

我的理解是可以(自动)获得焦点的元素类型是有限的。

SO Question

一种选择是将tabindex 添加到跨度中。

body {
  font-size: 3rem;
}
div[contenteditable=true] .edit:focus {
  color: #FF0000;
}
&lt;div contenteditable="true"&gt;Some text &lt;span class="edit" tabindex="0"&gt;that&lt;/span&gt; goes here.&lt;/div&gt;

【讨论】:

  • 真的很有趣,我在 FF 和 chrome 中对此进行了测试,但完全没有结果。这在某些情况下对您有用吗?
  • 谢谢@Paulie_D。在我问这个问题的有限范围内,这实际上是有效的。问题是我在contenteditable 的焦点状态下还有很多其他的东西……对于初学者来说,它是自己的样式。
  • @Rick 和 Paulie,我很抱歉,你是对的。一定是在测试时犯了一个愚蠢的错误。确认这在 FF 中有效。我的道歉
  • 一个有趣的转折:如果你点击span,它可以工作(在页面中运行代码sn-p),但如果你使用光标键移动插入符号,它就不行!
【解决方案3】:
:focus > .edit { color: #cc0000; }

<div contenteditable="true">Some text <span class="edit">that</span> goes here.</div>
<div contenteditable="true">Some text that goes here.</div>

【讨论】:

  • 考虑添加一些解释:)
  • 好主意。这个解决方案的唯一问题是,只要父 contentEditable 元素被聚焦,.edit 将始终具有#cc0000 的颜色。最初的问题是当插入符号位于此特定范围内时,突出显示.edit。无论如何都要起床。
【解决方案4】:

只需添加这个而不是 :focus。 Fiddle.

.edit {
  color: #f00;
}

【讨论】:

  • 希望在插入符号移入 .edit 时应用样式,而不是一直应用。
猜你喜欢
  • 2014-07-20
  • 2020-09-12
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多