safari - contenteditable, after making it empty, c

2019-07-20 21:08发布

问题:

In safari,

i had a simple edtable div with a input button, on deletion of the element (backspace or delete), caret moves to center of edtiable div with some inline styled p tag with text-align:center and inline style "color"

<div class="editable" contenteditable="true"> <input type="button" value="inputBtn" /> </div> http://jsfiddle.net/VqCvt/

its a strange behavior observed only in safari.

回答1:

Over a year after this post, this issue is still a problem. This issue is directly tied to the input tag. Once an input tag has been in a contenteditable element, Safari will attempt to make the style of the text similar to the input (I confirmed this by observing that the resulting style was different for type="text" vs type="button"). It's a very strange bug. I have found a workaround that works, but it's pretty absurd. My fix is basically to test when my main input no longer has content, and then removing the element, and re-adding it

<div id="content-wrapper">
  <div contenteditable="true" id="content" role="textbox"></div>
</div>

and in my "keyup" listener, I put the following code

// Grab main editable content div
var element = document.getElementById("content");

// Check empty state conditions.  These work for me, but you may have your own conditions.
if (element.getElementsByTagName("input").length == 0 &&
        element.innerText.trim().length == 0) {
    // Grab parent container
    var elementContainer = document.getElementById("content-wrapper");

    // Add a copy of your element to the same specifications.  If you have custom style attributes that you set through javascript, don't forget to copy them over
    elementContainer.innerHTML = '<div contenteditable="true" id="content" role="textbox"></div>';

    // Re-focus the element so the user doesn't have to click again to keep typing
    element = document.getElementById("content");
    element.focus();
}

What this code does works for my case because input is the only elements which are allowed in my code other than text nodes and <br>, so I first check to make sure there are no input elements, and then make sure the innerText is empty (this indicates no content in my case, you may have to customize your conditions for the "empty" state). Once the empty state is confirmed, I replace the old div with a new one to the same specification, and the user never notices. A very strange issue with a hacky workaround, but I think contenteditables.

You could probably also strip out the HTML that Safari is generating, but for my case this solution is much simpler. I hope this helps someone in the future.