jQuery scrollTop() 在 Safari 或 Chrome (Windows) 中似乎不起作用

IT技术 javascript jquery safari
2021-01-28 10:17:28

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

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

滚动的目标和软糖值由页面上的几个提示决定,我对这个机制的任何地方都没有问题。在 Firefox 和 IE8 中,上面的代码与我想要的完全一样:滚动框(在这种情况下,页面正文)在被告知这样做时正确地将包含的内容滚动到窗口中的正确点。

然而,在 Chrome 和 Safari 中,对 scrollTop() 的调用显然什么都不做。所有数字都正常,目标指向正确的事物(并且 offsetParent() 确实是 body 元素),但什么也没有发生。据我通过谷歌搜索可以看出,这应该有效。Safari 和 Chrome 下的渲染器有什么有趣的地方吗?

如果这很重要,这是 jQuery 1.3.2。

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

6个回答

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

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

bodyelem.scrollTop(100)

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

希望这可以帮助某人。

刚刚在 FF 3.6、Safari 5、Chrome 6、Opera 10 和 IE7 中进行了测试。太棒了!
2021-03-18 10:17:28
我只是得到“未定义 safari”……任何可能发生这种情况的情况,即使您加载了 jquery?
2021-03-23 10:17:28
这不再是事实;在最新版本的 jQuery Chrome 中有它自己的浏览器值:$.browser.chrome
2021-04-01 10:17:28

是啊,有似乎是在浏览器的错误,当涉及到修改body,努力使其成为一个offsetParent作为一个变通办法,我建议你只需添加另一个div来包裹#contentDIV,并使滚动:

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 中测试

现场演示:

谢谢,是的,这就是我最终解决的问题(主要是作为“oop,我想知道这是否有帮助”测试)。我将容器设置为“位置:相对”,但除此之外,它几乎完全符合您的建议。
2021-03-18 10:17:28
Thaaaaanks 很多!尝试了大量解决方案,您的解决方案是唯一一种适用于所有浏览器的解决方案!我不明白为什么这个错误还没有修复!
2021-03-22 10:17:28
我在尝试使用 animate 移动滚动条时遇到了另一个问题。就我而言,事实证明您必须将 document.documentElement.scrollTop 添加到 document.body.scrollTop。两者都不会在所有浏览器中都有值,因此它们一起等于您的目标。以为我会把它放在那里给发现这个问题的其他人。
2021-04-06 10:17:28
 $("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);
这就是传统上所说的“shotgun 调试”,en.wikipedia.org/wiki/Shotgun_debugging顺便说一下,它确实使页面在 Opera 中无法使用。
2021-03-21 10:17:28
是的,有效,原因是: .offset() 获取相对于文档的偏移量, .position() 获取相对于“偏移父级”的偏移量:例如,位置最近的父元素:相对。api.jquery.com/offset
2021-04-01 10:17:28
没有document元素这样的东西$("document")永远不会匹配有效 HTML 文档中的任何内容。坚持 $("body,html")`
2021-04-07 10:17:28
我知道但一些旧的浏览器需要它,不知道为什么
2021-04-08 10:17:28

浏览器支持状态是这样的:

IE8、火狐、Opera: $("html")

铬、Safari: $("body")

所以这有效:

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

对于滚动:setter 的“html”或“body”(取决于浏览器)... getter 的“window” ...

用于测试的 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');