CSS on :focus within child of contenteditable
CSS on :focus within child of contenteditable
我正在尝试检测 contenteditable
元素的子元素上的 focus
,以实现纯粹的 CSS 样式。 (我知道我可以用 JS 检测到这个,添加一个额外的 class 然后那样做,但那太啰嗦了。)
基本上,我有一些类似的东西:
<div contenteditable="true">
Some text <span class="edit">that</span> goes here.
</div>
我尝试了 CSS 的思路:
.edit:focus {
color: #FF0000;
}
我希望 span
在插入符号进入时改变颜色,但显然焦点仅应用于设置为 contenteditable
的 div
,而不是其任何子项。我已经尝试将第二个 contenteditable
应用于 span
,但除了是一种非常草率的方法之外,它无论如何都不起作用。
有解决办法吗?
只需添加这个而不是 :focus。 Fiddle.
.edit {
color: #f00;
}
我的理解是可以(自动)获得焦点的元素类型是有限的。
见SO Question
一个选项是将 tabindex
添加到跨度。
body {
font-size: 3rem;
}
div[contenteditable=true] .edit:focus {
color: #FF0000;
}
<div contenteditable="true">Some text <span class="edit" tabindex="0">that</span> goes here.</div>
: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
元素中的元素通常无法获得焦点的限制,我建议在选择时通过向 <span>
元素添加 class 来伪装它包含在其中,您可以通过监视选择的更改来做到这一点(您必须使用鼠标和键盘事件并轮询 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>
我正在尝试检测 contenteditable
元素的子元素上的 focus
,以实现纯粹的 CSS 样式。 (我知道我可以用 JS 检测到这个,添加一个额外的 class 然后那样做,但那太啰嗦了。)
基本上,我有一些类似的东西:
<div contenteditable="true">
Some text <span class="edit">that</span> goes here.
</div>
我尝试了 CSS 的思路:
.edit:focus {
color: #FF0000;
}
我希望 span
在插入符号进入时改变颜色,但显然焦点仅应用于设置为 contenteditable
的 div
,而不是其任何子项。我已经尝试将第二个 contenteditable
应用于 span
,但除了是一种非常草率的方法之外,它无论如何都不起作用。
有解决办法吗?
只需添加这个而不是 :focus。 Fiddle.
.edit {
color: #f00;
}
我的理解是可以(自动)获得焦点的元素类型是有限的。
见SO Question
一个选项是将 tabindex
添加到跨度。
body {
font-size: 3rem;
}
div[contenteditable=true] .edit:focus {
color: #FF0000;
}
<div contenteditable="true">Some text <span class="edit" tabindex="0">that</span> goes here.</div>
: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
元素中的元素通常无法获得焦点的限制,我建议在选择时通过向 <span>
元素添加 class 来伪装它包含在其中,您可以通过监视选择的更改来做到这一点(您必须使用鼠标和键盘事件并轮询 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>