IE11+ => 聚焦 child div 导致 parent 滚动到顶部

IE11+ => Focusing child div causes parent to scroll to top

我 运行 在 Internet Explorer 11+ 中遇到了一个小问题。我有一个可滚动的容器 div(带有 "overflow-y:auto")和一个 child div 即 "contenteditable=true".

我 运行 遇到的问题是,每当我尝试以编程方式关注 child div(使用 element.focus())时,Internet Explorer自动滚动到 parent div 的顶部。我一直在尝试为 IE 找到一种解决方法,以防止它自动滚动到顶部,但一直找不到。

这里有一个fiddle说明了问题:

http://jsfiddle.net/grese/dvxh74fr/9/

HTML:

    <div id="container">
         <div id="editor" contenteditable="true">
             <!-- sample text/html here -->
         </div>
    </div>
    <button id="bold">bold</button>

CSS:

    #container {
      height: 250px;
      overflow-y: auto;
      border: 1px solid black;
    }
    #editor {
      padding: 10px;
    }

JS:

    var container = document.getElementById('container');
    var editor = document.getElementById('editor');
    var bold = document.getElementById('bold');

    // initially, scroll to bottom...
    container.scrollTop = 200;

    bold.addEventListener('click', function(e) {
        e.preventDefault();
        document.execCommand('bold');

        // bring focus back to the editor...
        // this is causing IE to scroll to the top of the container :(
        editor.focus();
    });

重现问题的步骤:

  1. 在IE11(或IE Edge)中打开fiddle,然后点击"Run"
  2. Select(突出显示)fiddle
  3. 底部的一些文本
  4. 单击 "bold" 按钮
  5. 观察容器已经自动滚动到顶部

如果您在任何其他浏览器(Safari、Firefox、Chrome)中执行相同的步骤,您会注意到容器不会滚动。它只是停留在与之前相同的滚动位置(这是正确的行为)。

有什么想法吗?

我找到了解决方法。我可以使用“.setActive”(仅在 IE/Edge 中可用),而不是使用“.focus”来聚焦编辑器。 "setActive" 方法不会导致滚动,但仍然 "focuses" 元素。我只是在 "setActive" 函数上进行特征检测,以确定我们是否在 IE/Edge.

这是 "setActive" 方法的文档:

https://msdn.microsoft.com/en-us/library/ms536738(v=vs.85).aspx

这里有一个 fiddle 说明解决方案:

http://jsfiddle.net/grese/dvxh74fr/11/

JS解决方案:

var container = document.getElementById('container');
var editor = document.getElementById('editor');
var bold = document.getElementById('bold');

// initially, scroll to bottom...
container.scrollTop = 200;

bold.addEventListener('click', function(e) {
    e.preventDefault();
    document.execCommand('bold');

    // bring focus back to the editor...
    // use 'setActive' in IE/Edge so container does not scroll...
    if (editor.setActive) {
        editor.setActive(); // IE/Edge
    } else {
        editor.focus(); // All other browsers
    }
});