jQuery scrollTop() doesn't seem to work in Saf

2019-01-03 02:09发布

I've got a simple setup to allow a "help"-style window to be loaded and scrolled to a particular point on the page. More or less the code looks like this:

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

The target of the scroll and the fudge value are determined by a couple of hints dropped on the page, and I'm having no problems with that part of this mechanism anywhere. In Firefox and IE8, the above code works exactly like I want: the scrolled box (in this case, the page body) correctly scrolls the contained stuff to the right point in the window when it's told to do so.

In Chrome and Safari, however, the call to scrollTop() apparently does nothing at all. All the numbers are OK, and the target refers to the right thing (and the offsetParent() is indeed the body element), but nothing at all happens. As far as I can tell from googling around, this is supposed to work. Is there something funny about the renderer under Safari and Chrome?

This is jQuery 1.3.2 if that matters.

Test page: http://gutfullofbeer.net/scrolltop.html

19条回答
Bombasti
2楼-- · 2019-01-03 02:46
 $("body,html,document").scrollTop($("#map_canvas").position().top);

This works for Chrome 7, IE6, IE7, IE8, IE9, FF 3.6 and Safari 5.

2012 UPDATE
This is still good but I had to use it again. Sometimes position doesn't work so this is an alternative:

$("body,html,document").scrollTop($("#map_canvas").offset().top);
查看更多
家丑人穷心不美
3楼-- · 2019-01-03 02:46

There is not a big choice of elements that might get auto-assigned with a scrollTop value as we scroll a webpage.

So I wrote this little function to iterate through the probable elements and return the one we seek.

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

In Google chrome it would get us the body, in IE - HTML.

(Note, we don't need to set overflow:auto explicitly on our html or body that way.)

查看更多
趁早两清
4楼-- · 2019-01-03 02:47

It's not really a bug, just a difference in implantation by the browser vendors.

As a rule avoid browser sniffing. There is a nifty jQuery fix which is hinted at in the answers.

This is what works for me: $('html:not(:animated),body:not(:animated)').scrollTop()

查看更多
闹够了就滚
5楼-- · 2019-01-03 02:49

For the scroll : 'html' or 'body' for setter (depend on browser)... 'window' for getter...

A jsFiddle for testing is here : 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');
查看更多
Ridiculous、
6楼-- · 2019-01-03 02:49

This appears to be working in FF and WebKit; IE not tested so far.

$(document).scrollTop();
查看更多
Lonely孤独者°
7楼-- · 2019-01-03 02:50

The browser support status is this:

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

Chrome, Safari: $("body")

So this works:

bodyelem = $.browser.safari ? $("body") : $("html") ;
bodyelem.animate( {scrollTop: 0}, 500 );
查看更多
登录 后发表回答