animationscrollTop不工作在Firefox

这个function工作正常。 它将主体滚动到所需容器的偏移量

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

但不是在Firefox。 为什么?

-编辑-

为了在接受的答案中处理双重触发,我build议在animation之前停止元素:

 $('body,html').stop(true,true).animate({scrollTop: stop}, delay); 

Firefox将溢出置于html级别,除非专门devise为performance不同。

要在Firefox中使用它,请使用

 $('body,html').animate( ... ); 

工作示例

CSS解决scheme将设置以下样式:

 html { overflow: hidden; height: 100%; } body { overflow: auto; height: 100%; } 

我会假设JS解决scheme将是最不具侵略性的。


更新

下面的很多讨论着重于两个元素的scrollTopanimation会导致callback被调用两次的事实。 浏览器检测function已被build议,随后被弃用,有些可能是相当牵强的。

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

 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'); })); 

特征检测,然后animation在一个单一的支持的对象将是很好的,但没有一个线路的解决scheme。 同时,这里有一个使用承诺来执行每个执行单个callback的方法。

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

更新:这是如何使用function检测来代替。 这部分代码需要在animation调用之前进行评估:

 // 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(); 

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

 $(scrollTopElement).animate({ scrollTop: 100 }, 500, function() { // normal callback }); 

我花了很多年试图解决为什么我的代码不起作用 –

 $('body,html').animate({scrollTop: 50}, 500); 

问题出在我的CSS –

 body { height: 100%}; 

我把它设置为auto (而不是担心它为什么设置为100% )。 这为我修好了。

你可能想通过使用一个插件来避免这个问题 – 更具体地说, 我的插件 🙂

严重的是,尽pipe基本问题早已被解决(不同的浏览器使用不同的窗口滚动元素),但是下面还有很多非常重要的问题,

  • 简单地animationbodyhtml 都有问题 ,
  • functiontesting的实际浏览器的行为是很难得到正确的(请参阅我对@ Stephen的答案的评论 ),
  • 但最重要的是,有一大堆的可用性问题 ,你想要处理一个体面的用户体验。

我显然有偏见,但jQuery.scrollable实际上是一个很好的select来解决这些问题。 (事实上​​,我不知道其他任何处理它们的插件。)

另外,你可以用这个要点的getScrollTargetPosition()函数以防弹的方式计算目标位置 – 你滚动到的位置。

所有这一切都将离开你

 function scrolear ( destino ) { var $window = $( window ), targetPosition = getScrollTargetPosition ( $( destino ), $window ); $window.scrollTo( targetPosition, { duration: 1000 } ); return false; } 

小心这个。 我有同样的问题,Firefox或资源pipe理器都不滚动

 $('body').animate({scrollTop:pos_},1500,function(){do X}); 

所以我像大卫说的说

 $('body, html').animate({scrollTop:pos_},1500,function(){do X}); 

伟大的工作,但新的问题,因为有两个元素,身体和HTML,function执行两次,这是,X运行两次。

只用'html',Firefox和Explorer工作,但现在Chrome不支持这一点。

所以需要Chrome的正文,HTML和Firefox的浏览器。 这是一个jQuery的错误? 不知道。

只要小心你的function,因为它会运行两次。

我会build议不要依靠bodyhtml作为一个更便携的解决scheme。 只需在主体中添加一个div,旨在包含滚动的元素和样式,以启用全尺寸滚动:

 #my-scroll { position: absolute; width: 100%; height: 100%; overflow: auto; } 

(假设display:block; top:0;left:0;是与你的目标相匹配的默认值),然后使用$('#my-scroll')作为animation。

这是实打实的。 它完美地运行在Chrome和Firefox上。 有些无知的人投票给我,甚至感到难过。 这个代码在所有浏览器上的字面上都是完美的。 你只需要添加一个链接,把你想要滚动的元素的ID在HREF,它没有指定任何东西。 纯可重用和可靠的代码。

 $(document).ready(function() { function filterPath(string) { return string .replace(/^\//,'') .replace(/(index|default).[a-zA-Z]{3,4}$/,'') .replace(/\/$/,''); } var locationPath = filterPath(location.pathname); var scrollElem = scrollableElement('html', 'body'); $('a[href*=#]').each(function() { var thisPath = filterPath(this.pathname) || locationPath; if (locationPath == thisPath && (location.hostname == this.hostname || !this.hostname) && this.hash.replace(/#/,'') ) { var $target = $(this.hash), target = this.hash; if (target) { var targetOffset = $target.offset().top; $(this).click(function(event) { event.preventDefault(); $(scrollElem).animate({scrollTop: targetOffset}, 400, function() { location.hash = target; }); }); } } }); // use the first element that is "scrollable" function scrollableElement(els) { for (var i = 0, argLength = arguments.length; i <argLength; i++) { var el = arguments[i], $scrollElement = $(el); if ($scrollElement.scrollTop()> 0) { return el; } else { $scrollElement.scrollTop(1); var isScrollable = $scrollElement.scrollTop()> 0; $scrollElement.scrollTop(0); if (isScrollable) { return el; } } } return []; } }); 

对我来说,问题是firefox自动跳转到名称属性与我放入url的散列名称相同的锚点。 即使我把.preventDefault(),以防止这一点。 所以更改名称属性后,firefox并没有自动跳转到锚点,而是执行animation的权利。

@Toni对不起,如果这是不可理解的。 问题是我改变了像www.someurl.com/#hashname这样的URL中的哈希值。 然后,我有一个像<a name="hashname" ...></a>这样的jQuery应该自动滚动到的锚点。 但是这并不是因为它跳跃到Firefox中没有任何滚动animation的匹配名称属性的锚点。 一旦我将name属性更改为与hash名称不同的名称,例如name="hashname-anchor" ,则滚动工作。

对我而言,避免在animation的位置附加ID:

避免:

  scrollTop: $('#' + id).offset().top 

事先准备好id,然后做这个:

  scrollTop: $(id).offset().top 

固定在FF。 (这些CSS添加对我来说没有什么不同)

 setTimeout(function(){ $('html,body').animate({ scrollTop: top }, 400); },0); 

希望这个作品。