facebookarchive / draft-js

A React framework for building text editors.
https://draftjs.org/
MIT License
22.56k stars 2.64k forks source link

Jumping on focus iOS #1075

Open Nikcrysis opened 7 years ago

Nikcrysis commented 7 years ago

I've got a strange jump when triggers an "onFocus" event and show keyboard on iOS devices. Are there any solutions to avoid this behavior?

gangstertim commented 6 years ago

@Nikcrysis did you ever get around this? We're experiencing something similar.

joelzimmer commented 6 years ago

+1 - this is definitely something we are seeing in iOS as well

MohsinPHP commented 6 years ago

Hi, I am facing the same issue on iOS. It's working perfect in all other devices but in iOS have jumping issue. I tried html, body { position: absolute; } as suggested in an article but not helpful

ksmth commented 6 years ago

I've just encountered this issue as well. You can find it reproduced here: https://codesandbox.io/s/5wq9pv1w7x https://5wq9pv1w7x.codesandbox.io/

Clicking on the buttons should focus any of the editors / inputs at the bottom of the page, scrolling the viewport so they're visible. It seems like calling .focus() on a contentEditable element is the main cause for the jankyness. You can also see that Slate doesn't exhibit this behaviour, although it too is based on a contentEditable element.

Looking at what Slate does, I've found the following comments in their source:

      // COMPAT: In Firefox, it's not enough to create a range, you also need to
      // focus the contenteditable element too. (2016/11/16)

Which lead me to investigate further ... and it seems like in all environments except Firefox it's enough to set the selection range and the element gains focus.

Here's our workaround based on these findings:

    let contentNode;
    let originalFocusFn;
    if (this.isIOS()) {
      const rootEditorNode = findDOMNode(this.editor);
      if (!rootEditorNode) {
        return;
      }

      contentNode = rootEditorNode.querySelector('.public-DraftEditor-content');
      if (contentNode) {
        originalFocusFn = node.focus;
        contentNode.focus = () => {};
      }
    }

    this.editor.focus();

    if (contentNode && originalFocusFn) {
      contentNode.focus = originalFocusFn;
    }

By replacing the focus function with a noop temporarily, we're preventing https://github.com/facebook/draft-js/blob/master/src/component/base/DraftEditor.react.js#L488 this line from having any effect, solely relying on the following lines setting the selection to trigger the focus and it appears to be working nicely.

Gleb-Selikhov commented 3 years ago

Is this bug is still reproducing? If not can someone please close this issue?