Animate scrollTop无法在firefox中运行

Ton*_*bet 164 firefox jquery scrolltop

这个功能很好.它将主体滚动到所需容器的偏移量

function scrolear(destino){
    var stop = $(destino).offset().top;
    var delay = 1000;
    $('body').animate({scrollTop: stop}, delay);
    return false;
}
Run Code Online (Sandbox Code Playgroud)

但不是在Firefox中.为什么?

-编辑-

要在接受的答案中处理de double触发器,我建议在动画之前停止元素:

$('body,html').stop(true,true).animate({scrollTop: stop}, delay);
Run Code Online (Sandbox Code Playgroud)

Dav*_*und 330

Firefox将溢出放在html关卡中,除非特别设计为表现不同.

要使其在Firefox中运行,请使用

$('body,html').animate( ... );
Run Code Online (Sandbox Code Playgroud)

工作实例

CSS解决方案是设置以下样式:

html { overflow: hidden; height: 100%; }
body { overflow: auto; height: 100%; }
Run Code Online (Sandbox Code Playgroud)

我认为JS解决方案的侵入性最小.


更新

下面的很多讨论都集中在这样一个事实上,即动画scrollTop两个元素会导致回调被调用两次.浏览器检测功能已被建议并随后弃用,有些可能相当牵强.

如果回调是幂等的并且不需要大量的计算能力,那么两次触发可能是完全没有问题的.如果回调的多次调用确实是一个问题,并且如果您想避免特征检测,则可能更直接地强制回调仅在回调中运行一次:

function runOnce(fn) { 
    var count = 0; 
    return function() { 
        if(++count == 1)
            fn.apply(this, arguments);
    };
};

$('body, html').animate({ scrollTop: stop }, delay, runOnce(function() {
   console.log('scroll complete');
}));
Run Code Online (Sandbox Code Playgroud)

  • JS解决方案有一个缺陷!_animate_函数分别执行两次,分别用于_html_元素和_body_元素.看起来Webkit浏览器使用_body_,其余使用_html_.这个修复应该做的工作`$(jQuery.browser.webkit?"body":"html").animate(...);` (51认同)
  • 注意,`jQuery.browser`在最新的jQuery版本中已弃用且缺失 (23认同)
  • js解决方案工作得很好,固定在ff和ie (3认同)
  • 我发现Andreyco的解决方案在我使用的jQuery <1.4中不起作用.我能够像这样解决它:`$(jQuery.browser.mozilla?"html":"body").animate(...);`.不使用浏览嗅探,但功能检测会很棒.不知道如何在CSS上进行特征检测 (2认同)
  • 4年了,这个答案仍然被证明是有用的。非常感谢! (2认同)

Ste*_*hen 19

在单个受支持的对象上进行特征检测和动画制作会很不错,但是没有单线解决方案.与此同时,这是一种使用promise来执行单个回调的方法.

$('html, body')
    .animate({ scrollTop: 100 })
    .promise()
    .then(function(){
        // callback code here
    })
});
Run Code Online (Sandbox Code Playgroud)

更新:以下是您可以使用特征检测的方法.在动画调用之前,需要对这块代码进行评估:

// Note that the DOM needs to be loaded first, 
// or else document.body will be undefined
function getScrollTopElement() {

    // if missing doctype (quirks mode) then will always use 'body'
    if ( document.compatMode !== 'CSS1Compat' ) return 'body';

    // if there's a doctype (and your page should)
    // most browsers will support the scrollTop property on EITHER html OR body
    // we'll have to do a quick test to detect which one...

    var html = document.documentElement;
    var body = document.body;

    // get our starting position. 
    // pageYOffset works for all browsers except IE8 and below
    var startingY = window.pageYOffset || body.scrollTop || html.scrollTop;

    // scroll the window down by 1px (scrollTo works in all browsers)
    var newY = startingY + 1;
    window.scrollTo(0, newY);

    // And check which property changed
    // FF and IE use only html. Safari uses only body.
    // Chrome has values for both, but says 
    // body.scrollTop is deprecated when in Strict mode.,
    // so let's check for html first.
    var element = ( html.scrollTop === newY ) ? 'html' : 'body';

    // now reset back to the starting position
    window.scrollTo(0, startingY);

    return element;
}

// store the element selector name in a global var -
// we'll use this as the selector for our page scrolling animation.
scrollTopElement = getScrollTopElement();
Run Code Online (Sandbox Code Playgroud)

现在使用我们刚刚定义的var作为页面滚动动画的选择器,并使用常规语法:

$(scrollTopElement).animate({ scrollTop: 100 }, 500, function() {
    // normal callback
});
Run Code Online (Sandbox Code Playgroud)


Aid*_*wen 6

我花了很多年时间试图弄清楚为什么我的代码不起作用 -

$('body,html').animate({scrollTop: 50}, 500);
Run Code Online (Sandbox Code Playgroud)

问题出在我的CSS中 -

body { height: 100%};
Run Code Online (Sandbox Code Playgroud)

我把它设置为auto(并且担心为什么它首先被设置100%).这为我解决了这个问题.