jQuery scrollTop()似乎不适用于Safari或Chrome(Windows)

时间:2009-12-02 01:14:50

标签: javascript jquery safari

我有一个简单的设置,允许加载“帮助”式窗口并滚动到页面上的特定点。或多或少的代码看起来像这样:

var target = /* code */;
target.offsetParent().scrollTop(target.offset().top - fudgeValue);

滚动的目标和软糖价值是由页面上的一些提示确定的,我对这个机制的任何部分都没有任何问题。在Firefox和IE8中,上面的代码与我想要的完全一样:滚动框(在这种情况下,页面正文)正确地将包含的东西滚动到窗口中的正确位置,当它被告知这样做时。

然而,在Chrome和Safari中,对scrollTop()的调用显然什么都不做。所有数字都没问题,目标指的是正确的东西(而offsetParent()确实是正文元素),但什么都没发生。据我所知,谷歌搜索,这应该是有效的。 Safari和Chrome下的渲染器有什么有趣的东西吗?

如果重要的话,这是jQuery 1.3.2。

测试页面:http://gutfullofbeer.net/scrolltop.html

19 个答案:

答案 0 :(得分:45)

我在Safari和Chrome(Mac)中遇到此问题,并发现.scrollTop可以在$("body")上工作,但不能在$("html, body")上工作,但FF和IE可以反过来工作。一个简单的浏览器检测可以解决问题:

if($.browser.safari)
    bodyelem = $("body")
else
    bodyelem = $("html,body")

bodyelem.scrollTop(100)

Chrome的jQuery浏览器值是Safari,因此您只需要对其进行检测。

希望这有助于某人。

答案 1 :(得分:23)

是的,在修改body时,Chrome中似乎存在一个错误,试图将其变为offsetParent。作为解决方法,我建议您只需添加另一个div来包装#content div,并使 滚动:

html, body { height: 100%; padding: 0; } 
html { width: 100%; background-color: #222; overflow: hidden; margin: 0; } 
body 
{ 
   width: 40em; margin: 0px auto; /* narrow center column layout */
   background-color: white; 
   position: relative; /* allow positioning children relative to this element */
} 
#scrollContainer /* wraps #content, scrolls */
{ 
  overflow: auto; /* scroll! */
  position:absolute; /* make offsetParent */
  top: 0; height: 100%; width: 100%; /* fill parent */
} 
#header 
{ 
  position: absolute; 
  top: 0px; height: 50px; width: 38.5em; 
  background-color: white; 
  z-index: 1; /* sit above #content in final layout */
} 
#content { padding: 5px 14px 50px 5px;  } 

在FF 3.5.5,Chrome 3.0.195.33,IE8

中测试

现场演示:

$(function() {
        $('#header').find('button').click(function(ev) {
          var button = $(this), target = $('div.' + button.attr('class'));
          var scroll = target.offsetParent().scrollTop(); 
          target.offsetParent().scrollTop(target.offset().top + scroll - 50);
        });
      });
html, body { height: 100%; padding: 0; }
      html { width: 100%; background-color: #222; overflow: hidden; margin: 0; }
      body { width: 40em; margin: 0px auto; background-color: white; position: relative; }
      #scrollContainer { overflow: auto; position:absolute; top: 0; height: 100%; width: 100%; }
      #header { position: absolute; top: 0px; height: 50px; width: 38.5em; background-color: white; z-index: 1; }
      #content { padding: 5px 14px 50px 5px;  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <div id='header'> 
      Header Box
      <button class='A'>A</button> 
      <button class='B'>B</button> 
      <button class='C'>C</button> 
    </div> 
    <div id='scrollContainer'>
    <div id='content'> 
      <div style='height: 50px'> </div> 
      <div class='A'> 
        <h1>A</h1> 
        <p>My name is Boffer Bings. I was born of honest parents in one of the humbler walks of life, my father being a manufacturer of dog-oil and my mother having a small studio in the shadow of the village church, where she disposed of unwelcome babes. In my boyhood I was trained to habits of industry; I not only assisted my father in procuring dogs for his vats, but was frequently employed by my mother to carry away the debris of her work in the studio. In performance of this duty I sometimes had need of all my natural intelligence for all the law officers of the vicinity were opposed to my mother's business. They were not elected on an opposition ticket, and the matter had never been made a political issue; it just happened so. My father's business of making dog-oil was, naturally, less unpopular, though the owners of missing dogs sometimes regarded him with suspicion, which was reflected, to some extent, upon me. My father had, as silent partners, all the physicians of the town, who seldom wrote a prescription which did not contain what they were pleased to designate as _Ol. can._ It is really the most valuable medicine ever discovered. But most persons are unwilling to make personal sacrifices for the afflicted, and it was evident that many of the fattest dogs in town had been forbidden to play with me--a fact which pained my young sensibilities, and at one time came near driving me to become a pirate.
      </div> 
      <div class='B'> 
        <h1>B</h1> 
        <p> 
        Looking back upon those days, I cannot but regret, at times, that by indirectly bringing my beloved parents to their death I was the author of misfortunes profoundly affecting my future.
        <p> 
        One evening while passing my father's oil factory with the body of a foundling from my mother's studio I saw a constable who seemed to be closely watching my movements. Young as I was, I had learned that a constable's acts, of whatever apparent character, are prompted by the most reprehensible motives, and I avoided him by dodging into the oilery by a side door which happened to stand ajar. I locked it at once and was alone with my dead. My father had retired for the night. The only light in the place came from the furnace, which glowed a deep, rich crimson under one of the vats, casting ruddy reflections on the walls. Within the cauldron the oil still rolled in indolent ebullition, occasionally pushing to the surface a piece of dog. Seating myself to wait for the constable to go away, I held the naked body of the foundling in my lap and tenderly stroked its short, silken hair. Ah, how beautiful it was! Even at that early age I was passionately fond of children, and as I looked upon this cherub I could almost find it in my heart to wish that the small, red wound upon its breast--the work of my dear mother--had not been mortal.
      </div> 
      <div class='C'> 
        <h1>C</h1> 
        <p>It had been my custom to throw the babes into the river which nature had thoughtfully provided for the purpose, but that night I did not dare to leave the oilery for fear of the constable. "After all," I said to myself, "it cannot greatly matter if I put it into this cauldron. My father will never know the bones from those of a puppy, and the few deaths which may result from administering another kind of oil for the incomparable _ol. can._ are not important in a population which increases so rapidly." In short, I took the first step in crime and brought myself untold sorrow by casting the babe into the cauldron.
      </div> 
      <div style='height: 75em;'> </div> 
    </div> 
    </div>

答案 2 :(得分:17)

 $("body,html,document").scrollTop($("#map_canvas").position().top);

适用于Chrome 7,IE6,IE7,IE8,IE9,FF 3.6和Safari 5.

2012年更新
这仍然很好,但我不得不再次使用它。有时position不起作用,所以这是另一种选择:

$("body,html,document").scrollTop($("#map_canvas").offset().top);

答案 3 :(得分:9)

浏览器支持状态为:

IE8,Firefox,Opera:$("html")

Chrome,Safari:$("body")

这样可行:

bodyelem = $.browser.safari ? $("body") : $("html") ;
bodyelem.animate( {scrollTop: 0}, 500 );

答案 4 :(得分:7)

对于滚动:'html'或'body'用于setter (取决于浏览器)... 'window'用于getter ...

用于测试的jsFiddle在这里:http://jsfiddle.net/molokoloco/uCrLa/

var $window = $(window), // Set in cache, intensive use !
    $document = $(document),
    $body = $('body'),
    scrollElement = 'html, body',
    $scrollElement = $();

var isAnimated = false;

// Find scrollElement
// Inspired by http://www.zachstronaut.com/posts/2009/01/18/jquery-smooth-scroll-bugs.html
$(scrollElement).each(function(i) {
    // 'html, body' for setter... window for getter... 
    var initScrollTop = parseInt($(this).scrollTop(), 10);
    $(this).scrollTop(initScrollTop + 1);
    if ($window.scrollTop() == initScrollTop + 1) {
        scrollElement = this.nodeName.toLowerCase(); // html OR body
        return false; // Break
    }
});
$scrollElement = $(scrollElement);

// UTILITIES...
var getHash = function() {
        return window.location.hash || '';
    },
    setHash = function(hash) {
        if (hash && getHash() != hash) window.location.hash = hash;
    },
    getWinWidth = function() {
        return $window.width();
    },
    // iphone ? ((window.innerWidth && window.innerWidth > 0) ? window.innerWidth : $window.width());
    getWinHeight = function() {
        return $window.height();
    },
    // iphone ? ((window.innerHeight && window.innerHeight > 0) ? window.innerHeight : $window.height());
    getPageWidth = function() {
        return $document.width();
    },
    getPageHeight = function() {
        return $document.height();
    },
    getScrollTop = function() {
        return parseInt($scrollElement.scrollTop() || $window.scrollTop(), 10);
    },
    setScrollTop = function(y) {
        $scrollElement.stop(true, false).scrollTop(y);
    },
    myScrollTo = function(y, newAnchror) { // Call page scrolling to a value (like native window.scrollBy(x, y)) // Can be flooded
        isAnimated = true; // kill waypoint AUTO hash
        var duration = 360 + (Math.abs(y - getScrollTop()) * 0.42); // Duration depend on distance...
        if (duration > 2222) duration = 0; // Instant go !! ^^
        $scrollElement.stop(true, false).animate({
            scrollTop: y
        }, {
            duration: duration,
            complete: function() { // Listenner of scroll finish...
                if (newAnchror) setHash(newAnchror); // If new anchor
                isAnimated = false;
            }
        });
    },
    goToScreen = function(dir) { // Scroll viewport page by paginette // 1, -1 or factor
        var winH = parseInt((getWinHeight() * 0.75) * dir); // 75% de la hauteur visible comme unite
        myScrollTo(getScrollTop() + winH);
    };


myScrollTo((getPageHeight() / 2), 'iamAMiddleAnchor');

答案 5 :(得分:2)

在我们检查时,Chrome中存在一个错误(在我们检查时不在Safari中),在后台打开标签(bug details here)时会在Javascript的各种宽度和高度测量中产生意外结果 - 我们在6月份记录了错误从那时起它一直没有得到解决。

你可能遇到过你正在尝试做的事情的错误。

答案 6 :(得分:2)

setTimeout(function() { 
   $("body,html,document").scrollTop( $('body').height() ); 
}, 100);

即使时间是10毫秒,这也许应该有效。

答案 7 :(得分:2)

适用于Safari,Firefox和IE7(尚未尝试过IE8)。简单测试:

<button onclick='$("body,html").scrollTop(0);'>  Top </button>

<button onclick='$("body,html").scrollTop(100);'> Middle </button>

<button onclick='$("body,html").scrollTop(250);'> Bottom </button>

大多数示例使用其中一个或两个,但顺序相反(即“html,body”)。

干杯。

(语义纯粹主义者,不要破坏我的印章 - 我一直在寻找这个,这是一个简单的示例,它验证XHTML严格。随意创建27层的抽象和事件绑定膨胀让你的OCD安心。只是请给予应有的信任,因为jQuery论坛中的人们,SO和G不能咳出货物。和平了。)

答案 8 :(得分:1)

这似乎适用于FF和WebKit;目前尚未对IE进行测试。

$(document).scrollTop();

答案 9 :(得分:1)

哪个元素是另一个元素的offsetParent未明确指定,并且可能因浏览器而异。不能保证您正在寻找可滚动的父级。

主体本身也不应该是页面的主要可滚动元素。它只是在Quirks模式下,一般你想要避免。

offsetTop / offsetLeft / offsetParent测量本身并不十分有用,只有当你在循环中使用它们时它们才真正可靠总页面相对坐标(在jQuery中为position())。您应该知道要滚动的元素是哪一个,并找出它与后代target之间的页面坐标的差异,以找出滚动它的数量。

或者,如果它始终是页面本身,您正在谈论滚动,请改为使用location.href= '#'+target.id导航。

答案 10 :(得分:1)

怎么样

var top = $('html').scrollTop() || $('body').scrollTop();

答案 11 :(得分:1)

它对我有用,只需将它留给jQuery。

$("html,body").animate({ scrollTop: 0 }, 1);

基本上你应该知道浏览器并考虑浏览器差异来编写代码。由于jQuery是跨浏览器,因此它应该处理第一步。最后,你通过在1毫秒内设置滚动动画来伪造浏览器的js-engine。

答案 12 :(得分:0)

这不是一个真正的错误,只是浏览器供应商植入的差异。

通常避免浏览器嗅探。有一个漂亮的jQuery修复,在答案中暗示。

这对我有用:$('html:not(:animated),body:not(:animated)').scrollTop()

答案 13 :(得分:0)

在我们滚动网页时,可能会自动分配带有scrollTop值的元素选项不多。

所以我编写了这个小函数来遍历可能的元素并返回我们寻找的元素。

var grab=function (){
    var el=$();
        $('body#my_body, html, document').each(function(){
            if ($(this).scrollTop()>0) {
                el= ($(this));
                return false;
            }
        })
    return el;
}
//alert(grab().scrollTop());

在谷歌浏览器中,它会让我们身体,在IE - HTML中。

(注意,我们不需要在我们的html或body上明确设置overflow:auto。)

答案 14 :(得分:0)

我遇到了这个问题,我在底部创建了这个链接并实现了jQuery scrollTop代码,它在Firefox,IE,Opera中完美运行但在Chrome和Safari中无效。我正在学习jQuery,所以我不知道这个解决方案在技术上是否完美,但这对我有用。我刚刚实现了2个ScrollTop代码,第一个使用$('html'),适用于Firefox等。第二个使用$('html body'),这适用于Chrome和Safari。

$('a#top').click(function() {

    $('html').animate({scrollTop: 0}, 'slow');
    return false;

    $('html body').animate({scrollTop: 0}, 'slow');
    return false;
});

答案 15 :(得分:0)

事实上,似乎需要动画才能使其在Safari中运行。我最终得到了:

if($.browser.safari) 
    bodyelem = $("body");
else 
    bodyelem = $("html,body");

bodyelem.animate({scrollTop:0},{queue:false, duration:100, easing:"linear", complete:callbackFunc});

答案 16 :(得分:0)

我不确定是不是这样:

我正在使用Google的CDN for jQuery,即

"https:"之前加//ajax.google....... 工作,似乎Safari认为它是一个本地路径(检查它 - 检查元素)

抱歉,仅在Safari 7.0.3中测试过:(

答案 17 :(得分:0)

我是我的情况,该按钮适用于8个链接中的两个。我的解决方案是

$("body,html,document").animate({scrollTop:$("#myLocation").offset().top},2500);

这也创造了一个很好的滚动效果

答案 18 :(得分:0)

To summarise solutions from a couple of questions/answers:

If you want to get the current scroll offset use:

$(document).scrollTop()

To set the scroll offset use:

$('html,body').scrollTop(x)

To animate the scroll use use:

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