IE 11平滑滚动不会触发中间滚动事件

dan*_*ndi 21 javascript jquery internet-explorer underscore.js

如果我们做一个简单的测试用例,例如:

document.documentElement.addEventListener('scroll', function() {
    console.log(document.documentElement.scrollTop);
});
Run Code Online (Sandbox Code Playgroud)

然后通过单击轨道或使用PageDown/PageUp使用滚动条滚动,然后我们可以看到在滚动动画结束时我们只获得一个事件.

现在理论上我可以通过模拟滚动事件来修复一些行为.使用jQuery和Underscore的示例代码:

$(function () {
    var $document = $(document), until = 0;

    var throttleScroll = _.throttle(function () {
        $document.scroll();
        if (+new Date < until) {
            setTimeout(throttleScroll, 50);
        }
    }, 50);

    $document.keydown(function (evt) {
        if (evt.which === 33 || evt.which === 34) {
            until = +new Date + 300;
            throttleScroll();
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

但它仍然无效.我们只获得原始scrollTop目的地和目的地的滚动事件scrollTop,两者之间没有值.

如果然后console.log(document.documentElement.scrollTop)每10分钟一次,那么我们可以看到IE在scrollTop滚动时不会更新.

如果我们想要将某些内容"固定"到滚动位置,这将非常令人沮丧.IE变得生涩.

我没有在任何其他浏览器上观察到此行为,并且没有使用以前的IE版本进行测试.

如果有人找到一种方法来修复IE的行为(也许有一个神奇的CSS来关闭IE 11中的平滑滚动?)那么我非常想听听它!

谢谢 :-)

M H*_*M H 9

你说: "如果有人找到了一种方法来修复IE的行为(也许有一个神奇的CSS来关闭IE 11中的平滑滚动?)那么我非常想听听它的消息!"

这不会关闭它,但这是我用来解决平滑滚动问题,即使用固定元素.

if(navigator.userAgent.match(/Trident\/7\./)) {
    $('body').on("mousewheel", function ( event ) {
        event.preventDefault();
        var wd = event.wheelDelta;
        var csp = window.pageYOffset;
        window.scrollTo(0, csp - wd);
    });
}
Run Code Online (Sandbox Code Playgroud)


Sam*_*son 6

您所描述的问题仅限于在Windows 7上运行的Internet Explorer 11的实例.此问题不会影响IE 11诞生的平台,Windows 8.1.似乎Windows 7上的IE 11与上面提到的其他滚动实现属于类似的类别.它并不理想,但它是我们暂时需要与之合作的东西.

我要继续研究这个; 实际上,只是将一台Windows 7机器从机柜中取出来安装第一件事,以便进一步调查.虽然我们无法正面解决这个问题,但也许,我们可以通过某种方式来规避问题本身.

未完待续.

  • @Jonathan Sampson据我所知,问题是关于IE11在平滑滚动动画期间没有触发滚动事件.因此,我们看到页面滚动动画,但是在此动画期间我们没有得到滚动事件,所以需要在滚动事件上更新的所有内容实际上都没有更新,只有在动画结束时才会立即更新,当滚动事件被触发时.当页面已经动画化时,这给了我们那种不稳定的行为,而且需要更新的东西只是在动画后跳转到位. (2认同)

小智 -1

看起来有一篇关于 IE 的帖子,强制屏幕“绘制”以帮助拖放。看起来与大多数性能努力相反,但可能有效吗?/sf/answers/867685451/ (代码来自/sf/users/22055841/

function cleanDisplay() {
    var c = document.createElement('div');
    c.innerHTML = 'x';
    c.style.visibility = 'hidden';
    c.style.height = '1px';
    document.body.insertBefore(c, document.body.firstChild);
    window.setTimeout(function() {document.body.removeChild(c)}, 1);
}
Run Code Online (Sandbox Code Playgroud)

您可以尝试 CSS 动画,以便浏览器处理动画/过渡。例如,在滚动和 CSS 动画上应用显示/隐藏类。

.hide-remove {
    -webkit-animation: bounceIn 2.5s;
    animation: bounceIn 2.5s;
}

.hide-add {
    -webkit-animation: flipOutX 2.5s;
    animation: flipOutX 2.5s;
    display: block !important;
}
Run Code Online (Sandbox Code Playgroud)

如果没有浏览器处理动画(带有创意 CSS),关键帧和 JS 性能可能会提供线索。另外,我见过几个网站的导航栏在滚动结束后“重新出现”。