JQuery scrollTop(), похоже, не работает в Safari или Chrome (Windows)

У меня есть простая настройка, позволяющая загружать окно справки "help" и прокручиваться до определенной точки на странице. Более или менее код выглядит следующим образом:

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

Цель прокрутки и значение fudge определяется несколькими подсказками, выпавшими на странице, и у меня нет проблем с этой частью этого механизма в любом месте. В Firefox и IE8 приведенный выше код работает точно так же, как я хочу: прокрученный блок (в данном случае, тело страницы) корректно прокручивает содержимое в нужную точку в окне, когда он сказал это сделать.

Однако в Chrome и Safari вызов scrollTop(), по-видимому, ничего не делает. Все цифры в порядке, и цель относится к правильной вещи (и offsetParent() действительно является элементом тела), но ничего не происходит. Насколько я могу судить по всему миру, это должно работать. Есть что-то смешное в рендерере в Safari и Chrome?

Это jQuery 1.3.2, если это имеет значение.

Страница тестирования: http://gutfullofbeer.net/scrolltop.html

Ответ 1

Да, в Chrome появляется ошибка, когда нужно изменить body, пытаясь превратить ее в offsetParent. Как обход, я предлагаю вам просто добавить еще один div, чтобы обернуть div #content и сделать эту прокрутку:

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 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 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 oil factory with the body of a foundling from my mother studio I saw a constable who seemed to be closely watching my movements. Young as I was, I had learned that a constable 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

У меня была эта проблема в Safari и Chrome (Mac), и я обнаружил, что .scrollTop будет работать на $("body"), но не $("html, body"), FF и IE, однако, работают наоборот. Простое обнаружение браузера устраняет проблему:

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

bodyelem.scrollTop(100)

Значение браузера jQuery для Chrome - это Safari, поэтому вам нужно только сделать это.

Надеюсь, это поможет кому-то.

Ответ 3

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

Ответ 4

Статус поддержки браузера:

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

Chrome, Safari: $("body")

Итак, это работает:

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

Ответ 5

Для прокрутки: 'html' или 'body' для setter (зависит от браузера)... 'window' для getter...

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

Ответ 6

В Chrome (ошибка Safari в момент проверки) есть ошибка, которая дает неожиданные результаты в различных измерениях ширины и высоты Javascript при открытии вкладок в фоновом режиме (здесь]) - мы записали ошибку в июне, и она осталась нерешенной с тех пор.

Возможно, вы столкнулись с ошибкой в ​​том, что вы пытаетесь сделать.

Ответ 7

Работает для 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

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

Это, вероятно, должно работать, даже если время составляет 10 мс.

Ответ 9

Какой элемент является offsetParent другого, не является корректным и может меняться в разных браузерах. Не гарантируется, что вы прокручивающийся родитель, которого ищете.

Само тело также не должно быть основным прокручиваемым элементом страницы. Это только в режиме Quirks Mode, который в общем вы бы хотели избежать.

Измерения offsetTop/offsetLeft/offsetParent сами по себе не очень полезны, они только очень надежны, когда вы используете их в цикле, чтобы получить общее сопоставление страниц, ординат (как position() в jQuery). Вы должны знать, какой элемент вы хотите прокрутить, и узнать разницу между координатами страницы между этим и потоком target, чтобы узнать, сколько прокрутить его.

Или, если это всегда сама страница, о которой вы говорите, прокрутка, используйте вместо нее location.href= '#'+target.id.

Ответ 10

Это, похоже, работает в FF и WebKit; IE не тестировался до сих пор.

$(document).scrollTop();

Ответ 11

как насчет

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

Ответ 12

Это сработало для меня, просто оставьте его в jQuery.

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

В основном вы должны знать браузер и писать код с учетом различий браузера. Поскольку jQuery является кросс-браузером, он должен обрабатывать первый шаг. И, наконец, вы подделываете js-engine браузера, оживляя прокрутку за 1 миллисекунду.

Ответ 13

Это не ошибка, а просто разница в имплантации поставщиков браузеров.

Как правило, избегайте обхода браузером. В ответах есть замечательное исправление jQuery, которое намечено в нем.

Это то, что работает для меня: $('html:not(:animated),body:not(:animated)').scrollTop()

Ответ 14

Нет большого выбора элементов, которые могут быть автоматически назначены с помощью значения 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());

В Google хром он получит тело, в IE - HTML.

(Обратите внимание: нам не нужно явно устанавливать overflow:auto на наш html или тело таким образом.)

Ответ 15

Я столкнулся с этой проблемой, я создал эту ссылку внизу и реализовал код scrollTop jQuery, и он отлично работал в 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;
});

Ответ 16

Действительно, кажется, что анимация необходима, чтобы заставить ее работать в Safari. Я закончил с:

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

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

Ответ 17

Я не уверен, что это так:

Я использовал Google CDN для jQuery i.e.

Ввод "https:" до //ajax.google....... работал, кажется, Safari распознал его как локальный путь (проверил его - Inspect Element)

Извините, проверено только в Safari 7.0.3: (

Ответ 18

В моем случае кнопка работала для двух из 8 ссылок. Мое решение было

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

Это создало хороший эффект прокрутки, а также

Ответ 19

Подводя итог решениям из нескольких вопросов/ответов:

Если вы хотите получить текущее смещение прокрутки, используйте:

$(document).scrollTop()

Чтобы установить смещение прокрутки, используйте:

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

Чтобы анимировать использование прокрутки, используйте:

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