CSS: :focus of elements within contenteditable

后端 未结 3 1626
南旧
南旧 2020-12-03 03:49

If you have the following HTML:

The first paragraph

The second paragraph

相关标签:
3条回答
  • 2020-12-03 04:04

    I think I found a solution.

    With the following code snippet you can get the parent element at the current caret position when the selection changes.

    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;
    

    Here I change the outline property manually but you could of course add a class attribute and set the style via CSS.

    You still have to manually check if selectedElement is a child of our <div> with the contenteditable attribute. But I think you can get the basic idea.

    Here's the updated JSFiddle.

    EDIT: I updated the code as well as the JSFiddle to make it work in Firefox and Internet Explorer 9+, too. Unfortunately these Browsers do not have a onselectionchange event handler, so I had to use onkeyup and onmouseup.

    0 讨论(0)
  • 2020-12-03 04:07

    Interesting question. If it's viable, I'd suggest moving the contenteditable attribute to the ps themselves: 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>
    

    EDIT: Here is another version, that causes para returns to generate paras instead of divs: 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>
    
    0 讨论(0)
  • 2020-12-03 04:12

    jsFiddle here.

    The following is imperfect in the sense that your mouse will need to be in the same area as the selected paragraph (to keep the :hover argument true), but as this will usually be the case anyway this should be fine - it's the best you're going to get if you want to keep your markup as it is anyway:

    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.

    If you're able to change the markup, you can use the following simplified selector:

    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>
    
    0 讨论(0)
提交回复
热议问题