简体   繁体   中英

Fix caret position on contenteditable div

I have a div with contenteditable="true" and resize: both attributes which has centered text via flexbox

.edit-area {      
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: rgba(206, 206, 206, 0.5);
      border: 0.1rem solid gray;
      resize: both;
      overflow: hidden;
}

the problem is that when you focus the div and it is empty the caret position is on left top corner
在此处输入图片说明

and only when you type 1 character the caret jumps to the center
在此处输入图片说明

i've done some research and found answers like these:
Caret position when centering with flexbox in contenteditable
Centering the placeholder caret in contentEditable element

text-align:center on :empty selector works for horizontal centering, but for the vertical align the problem remains, fixes with line-height = initial height on :empty selector wont work in my case because this div can be resized, is there any ways to set caret on the center programmatically with onFocus event, or with some other css tricks?

with help of @Spectric answer here is the solution that i end up with:

const FILLCHARACTER = String.fromCharCode(8203);

node
  .on("input", textInputHandler)
  .on("keydown", textKeyDownHandler);

  const textInputHandler = () => {
    const nodeDOM = d3.select(textNode.current).node();
    if (nodeDOM.innerText.toString().length == 0) {
      nodeDOM.innerHTML = FILLCHARACTER;
    }
  };

  const textKeyDownHandler = (event) => {
    if (event.key == "Backspace") {
      const selectionText = window.getSelection().toString();
      const selectionLength = selectionText.length;
      const currentTextLength = textValue.current.length;
      if (
        selectionLength === currentTextLength ||
        (selectionLength === 1 &&
          (/\u200B/g.test(selectionText) ||
            selectionText.indexOf(FILLCHARACTER) !== -1))
      ) {
        d3.select(textNode.current).node().innerHTML = FILLCHARACTER;
      }
    }
  };

With JavaScript you can insert a space ('   ') when you detect the contenteditable is empty. This pushes the caret position to the center.

 document.querySelector('.edit-area').addEventListener("input", function() { if (this.innerText.toString().length == 0) { this.innerHTML= ' '; } })
 .edit-area { display: flex; justify-content: center; align-items: center; background-color: rgba(206, 206, 206, 0.5); border: 0.1rem solid gray; resize: both; overflow: hidden; }
 <div class="edit-area" contenteditable> &nbsp; </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM