插入符号在元素中的时候是否有CSS选择器?

时间:2018-04-19 14:07:44

标签: javascript css caret

我有一个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上空盘旋了:

example of the problem

有没有办法应用这样的样式,但是当插入符号位于元素内部时?那么红线周围的span中的文字是粗体吗?

解决方案如下所示:

style following caret

CSS解决方案将是理想的,但如果不可能,我会考虑JS解决方案。

2 个答案:

答案 0 :(得分:2)

使用CSS?

不,没有css选择器。

使用JavaScript?

是的,您可以使用.getSelection()功能JavaScriptelement执行此操作。

使用.getSelection(),您可以获取插入符号的当前位置,并且插入符号已启用window.getSelection().focusNode.parentElement // Returns DOM node

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       
    Array.prototype.forEach.call(selection.focusNode.parentElement.parentElement.getElementsByTagName( "span" ), 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
function reset() {
  Array.prototype.forEach.call(ctl.getElementsByTagName( "span" ), child => {
      child.style.fontWeight = "normal";
  });
}

ctl.addEventListener("keyup", styleNode);
ctl.addEventListener("click", styleNode);
ctl.addEventListener("focusout", reset);
  

<强> window.getSelection()

     

返回一个Selection对象,表示用户选择的文本范围    或者插入符号的当前位置。

     

https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection

因此,使用此信息,您可以创建一个函数,对插入符号所在的元素进行样式设置

&#13;
&#13;
<div contenteditable id="contenteditable">
  <span>This is</span> some editable <span>content</span>
</div>
&#13;
mongo
use admin
db.auth("devx","xxxxxx")
show dbs
use db1
> db.getUser("devx")
{
    "_id" : "db1.dbuser",
    "user" : "devx",
    "db" : "db1",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "db1"
        },
        {
            "role" : "dbAdmin",
            "db" : "db1"
        },
        {
            "role" : "dbOwner",
            "db" : "db1"
        }
    ]
}
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我认为需要采用不同的方法。由于编辑需要单击元素,我只需在子元素上设置一个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>