从绝对位置更改为固定位置时发生意外跳跃,为什么? [英] Unexpected jump while changing position from absolute to fixed, why?

查看:56
本文介绍了从绝对位置更改为固定位置时发生意外跳跃,为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我想说的不是内容跳跃!

first of all I want to say that it's not about content jumping!

我有一个导航栏和一个侧栏,它们都位于absolute位置.用户滚动100个像素后,我将它们都更改为fixed.但是会有奇怪的动作发生(并非总是如此!).导航栏和边栏的包装将刷新一秒钟.我使用不同的浏览器对其进行了测试,并且它不依赖于浏览器.我试图重现这种情况:

I have a navbar and a sidebar which both have absolute position. after user scrolls 100 pixels I change both of them to fixed. but an odd action happens (not always!). wrappers of navbar and sidebar flush for a second. I tested it with different browsers and it does not depend on browser. I tried to reproduce the situation in this fiddle:

https://jsfiddle.net/addxmkgj/

(将屏幕调整为尽可能大的尺寸) - 编辑 - https://codepen.io/anon/pen/dJKBPe 也添加了codepen链接.

(resize the screen as large as possible it happens in large screens) -- Edit -- https://codepen.io/anon/pen/dJKBPe codepen link added too.

推荐答案

原因

滚动可以快速生成滚动事件,处理程序可能需要在某种程度上限制滚动事件(例如,在滚动停止后执行代码操作)或相当轻巧的功能,可以快速执行.

Causes

Scrolling can generate scroll events quickly and handlers may need to either throttle scroll events to some extent (e.g. perform code action after scrolling has stopped) or be fairly lightweight functions that can execute quickly.

此外,滚动事件处理与页面更新不同步:如果鼠标滚轮启动向下滚动,则在释放滚轮后可以继续滚动(类似触摸事件滚动).在滚动事件处理有机会赶上并更改位置之前,浏览器可以滚动到低于100px的顶部位置.

In addition scroll event handling is not synchronized with page update: if the mouse wheel initiates downward scrolling, scrolling can continue after the wheel is released (and similarly with touch event scrolling). The browser can scroll below a top position of 100px before scroll event handling has had a chance to catch up and change the positioning.

结果是标题从部分脱离屏幕的位置跳到占据屏幕顶部的固定位置.滚动动作越快(浏览器越忙),跳跃的可能性就越大.

The result is the header jumps down from being partially off-screen to occupy a fixed position at top of screen. The faster the scroll action (or the busier the browser is) the more likely it is that jumping will be noticeable.

桌面浏览的第二个效果是,当侧栏面板向上滚动超过屏幕顶部并再次向下移动时,可见的白屏补丁会在侧栏下方瞬间闪烁",直到固定定位生效.

A secondary effect in desktop browsing is that when the side bar panel scrolls upwards past top of screen and moves down again, a visible patch of white screen "flashes" momentarily below the side bar before fixed positioning takes effect.

通过增加容器的高度,可以减少但不必完全消除侧杆的溢料.将高度更改为150%并有可见的溢出效果很成功:

Flashing of the side bar can be reduced but not necessarily fully eliminated, by increasing the height of the container. Changing the height to 150% with visible overflow met with some success:

.side-bar {
position: absolute;
height: 150%;
... /* more declarations */

这可能会或可能不会与应用程序要求冲突.

通过使用requestAnimationFrame回调来监视scrollTop值并根据需要更改位置,可以实现导航栏跳跃的某种缓解.这不会像这样使用滚动事件处理:

Some mitigation of navbar jumping can be achieved by using requestAnimationFrame call backs to monitor scrollTop values and change positioning as necessary. This does not use scroll event handling as such:

$(document).ready(function() {
    $(window).resize(function() {
        if( $(window).width() > 850) {
            $('.navbar').css('display', 'block');   
        } else {
            $('.navbar').css('display', 'none');
        }
    });
    scrollTo(0, 0);
    var num = 100;
    var bAbsolute = true;
    function checkScroll() {
        var newTop = $(window).scrollTop();
        if( bAbsolute && newTop >= num) {
             $('.navbar').css('position', 'fixed');
            $('.navbar').css('top', '0');
            $('.side-bar').css('position', 'fixed');            
            $('.side-bar').css('top', '0');
            bAbsolute = false;
        }
        if( !bAbsolute && newTop < num) {
            $('.navbar').css('position', 'absolute');
             $('.side-bar').css('position', 'absolute');
             $('.navbar').css('top', '100px');
             $('.side-bar').css('top', '100px');
            bAbsolute = true;
        }
        requestAnimationFrame( checkScroll);

    } 
    requestAnimationFrame( checkScroll)
});

此代码显示出跳跃减少方面的改进,但并不完美.它不是特别的JQuery解决方案,而是直接调用requestAnimationFrame.

This code showed an improvement in jump reduction but was not perfect. It is not particularly a JQuery solution and calls requestAnimationFrame directly.

当然,一种选择是在给定浏览器时间限制的情况下不执行任何操作.


One option, of course, is to do nothing given browser timing constraints.


滚动链接效果的MDN指南比我能更好地解释根本原因问题:

This MDN guide for Scroll linked effects explains the root cause problem better than I was able to:

现在大多数浏览器都支持某种异步滚动....可视滚动位置在合成器线程中更新,并且在DOM中更新滚动事件并在主线程上触发之前对用户可见.这可能会导致效果过大,过时或抖动-简而言之,我们要避免这种情况.

most browsers now support some sort of asynchronous scrolling .... the visual scroll position is updated in the compositor thread and is visible to the user before the scroll event is updated in the DOM and fired on the main thread ... This can cause the effect to be laggy, janky, or jittery — in short, something we want to avoid.

因此,在将新的滚动位置通知滚动处理程序之前,绝对定位的元素可以在一定程度上滚动到屏幕之外.

So the absolutely positioned elements can scroll off screen (to some extent) before scroll handlers are notified of a new scroll position.

未来的解决方案是使用sticky定位(请参见上方的滚动效果指南或,但是position:sticky在相对位置和固定位置之间进行了交换,因此HTML需要重新设计以适应这种情况.

The solution going forward is to use sticky positioning (see the scroll effects guide above or the CSS position guide. However position:sticky swaps between relative and fixed position so the HTML would need redesigning to accommodate this.

Sticky定位也是2018年1月的领先技术,尚不建议在MDN上用于生产.在网络上搜索"JQuery支持粘性位置"显示了对JQuery插件支持的选择.

Sticky positioning is also leading edge technology at January 2018, and not yet recommended for production use on MDN. A web search for "JQuery support sticky position" revealed a choice of JQuery plugin support.

最好的折衷办法可能是重新设计HTML以使用粘性定位,并包括一个JQuery插件,该插件在可用时使用本机支持,在不可用时使用polyfill-使用支持浏览器的网站访问者将获得最佳体验,而使用较旧版本的浏览器浏览器将获得功能支持.

Potentially the best-case compromise may be to redesign the HTML to use sticky positioning and include a JQuery plugin that uses native support when available or a polyfill when not - site visitors with supporting browsers will get the best experience, those with older browsers will get functional support.

这篇关于从绝对位置更改为固定位置时发生意外跳跃,为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆