当插入符号在元素中时,是否有 CSS 选择器?
Is there a CSS selector for when the caret is in the element?
我有一个 contenteditable
元素,我希望其中的元素在插入符号位于其中时应用样式。
在此示例中,样式更改 :hover
:
div{
caret-color: red;
}
span:hover {
font-weight:bold;
}
<div contenteditable="true">
<span>Sub element one</span>
text node
<span>sub element two</span>
</div>
在这里您可以看到插入符号,因为我将其设置为红色,但我将鼠标悬停在另一个符号上 span
:
有什么方法可以应用这样的样式,但当插入符在元素内部时?以便红线周围span
中的文字是粗体?
解决方案如下所示:
CSS 解决方案是理想的,但如果不可能,我会考虑 JS 解决方案。
我认为需要一种不同的方法。由于编辑需要单击元素,我只需要在子元素上设置一个 click
事件处理程序来设置它们的样式。
// Get reference to the contenteditable element
var container = document.querySelector("[contenteditable='true']");
// Set up a click event handler for the container
container.addEventListener("click", function(evt){
// Loop over child elements and remove the active class
Array.prototype.slice.call(container.querySelectorAll("*")).forEach(function(el){
el.classList.remove("active");
});
// Apply the active class to the clicked element
evt.target.classList.add("active");
});
.active {
font-weight:bold;
}
<div contenteditable="true">
<span>Sub element one</span>
text node
<span>sub element two</span>
</div>
和CSS?
不,没有 css
选择器。
和JavaScript?
是的,您可以通过 JavaScript
使用 .getSelection()
函数来做到这一点。
使用 .getSelection()
你可以获得 caret 和 element
caret 的当前位置已开启。
window.getSelection().focusNode.parentElement // Returns DOM node
window.getSelection()
Returns a Selection object representing the range of text selected by the user
or the current position of the caret.
https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection
因此,使用此信息,您可以创建一个函数,为插入符所在的元素设置样式
var ctl = document.getElementById('contenteditable');
var selection;
function styleNode() {
// Get selection / caret position
selection = window.getSelection();
// Check if type is Caret and not Range (selection)
if(selection.type === 'Caret') {
// Remove styles
[...selection.focusNode.parentElement.parentElement.getElementsByTagName( "span" )].forEach( child => child.style.fontWeight = "normal" );
// Only style <span> elements
if(selection.focusNode.parentElement.tagName === 'SPAN') {
// Set style on element where caret is
selection.focusNode.parentElement.style.fontWeight = "bold";
}
}
}
// Removes styles on focusout
const reset = () => [...ctl.getElementsByTagName( "span" )].forEach( child => child.style.fontWeight = "normal" );
ctl.addEventListener("keyup", styleNode);
ctl.addEventListener("click", styleNode);
ctl.addEventListener("focusout", reset);
<div contenteditable id="contenteditable">
<span>This is</span> some editable <span>content</span>
</div>
事件侦听器 selectionchange
对于检测插入符位置的变化(由于鼠标或键盘)非常有用。当在空格键上滑动以移动插入符时,它检测到也应该适用于手机。
sel = window.getSelection()
document.addEventListener("selectionchange", e => {
(x=document.querySelector('.caretover')) && x.classList.remove('caretover')
if (sel.focusNode.parentNode.tagName == 'SPAN')
sel.focusNode.parentNode.classList.add('caretover')
})
.caretover {
font-weight: bold;
}
<div contenteditable>
<span>Sub element one</span>
text node
<span>sub element two</span>
</div>
我有一个 contenteditable
元素,我希望其中的元素在插入符号位于其中时应用样式。
在此示例中,样式更改 :hover
:
div{
caret-color: red;
}
span:hover {
font-weight:bold;
}
<div contenteditable="true">
<span>Sub element one</span>
text node
<span>sub element two</span>
</div>
在这里您可以看到插入符号,因为我将其设置为红色,但我将鼠标悬停在另一个符号上 span
:
有什么方法可以应用这样的样式,但当插入符在元素内部时?以便红线周围span
中的文字是粗体?
解决方案如下所示:
CSS 解决方案是理想的,但如果不可能,我会考虑 JS 解决方案。
我认为需要一种不同的方法。由于编辑需要单击元素,我只需要在子元素上设置一个 click
事件处理程序来设置它们的样式。
// Get reference to the contenteditable element
var container = document.querySelector("[contenteditable='true']");
// Set up a click event handler for the container
container.addEventListener("click", function(evt){
// Loop over child elements and remove the active class
Array.prototype.slice.call(container.querySelectorAll("*")).forEach(function(el){
el.classList.remove("active");
});
// Apply the active class to the clicked element
evt.target.classList.add("active");
});
.active {
font-weight:bold;
}
<div contenteditable="true">
<span>Sub element one</span>
text node
<span>sub element two</span>
</div>
和CSS?
不,没有 css
选择器。
和JavaScript?
是的,您可以通过 JavaScript
使用 .getSelection()
函数来做到这一点。
使用 .getSelection()
你可以获得 caret 和 element
caret 的当前位置已开启。
window.getSelection().focusNode.parentElement // Returns DOM node
window.getSelection()
Returns a Selection object representing the range of text selected by the user or the current position of the caret.
https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection
因此,使用此信息,您可以创建一个函数,为插入符所在的元素设置样式
var ctl = document.getElementById('contenteditable');
var selection;
function styleNode() {
// Get selection / caret position
selection = window.getSelection();
// Check if type is Caret and not Range (selection)
if(selection.type === 'Caret') {
// Remove styles
[...selection.focusNode.parentElement.parentElement.getElementsByTagName( "span" )].forEach( child => child.style.fontWeight = "normal" );
// Only style <span> elements
if(selection.focusNode.parentElement.tagName === 'SPAN') {
// Set style on element where caret is
selection.focusNode.parentElement.style.fontWeight = "bold";
}
}
}
// Removes styles on focusout
const reset = () => [...ctl.getElementsByTagName( "span" )].forEach( child => child.style.fontWeight = "normal" );
ctl.addEventListener("keyup", styleNode);
ctl.addEventListener("click", styleNode);
ctl.addEventListener("focusout", reset);
<div contenteditable id="contenteditable">
<span>This is</span> some editable <span>content</span>
</div>
事件侦听器 selectionchange
对于检测插入符位置的变化(由于鼠标或键盘)非常有用。当在空格键上滑动以移动插入符时,它检测到也应该适用于手机。
sel = window.getSelection()
document.addEventListener("selectionchange", e => {
(x=document.querySelector('.caretover')) && x.classList.remove('caretover')
if (sel.focusNode.parentNode.tagName == 'SPAN')
sel.focusNode.parentNode.classList.add('caretover')
})
.caretover {
font-weight: bold;
}
<div contenteditable>
<span>Sub element one</span>
text node
<span>sub element two</span>
</div>