refreshless-8.x-1.x-dev/modules/refreshless_turbo/js/browser_fixes/scroll_reset.js

modules/refreshless_turbo/js/browser_fixes/scroll_reset.js
/**
 * @file
 * Fixes scroll sometimes not resetting to the top on forward navigation.
 *
 * This works around a Firefox issue where the browser will sometimes not
 * scroll to the top as expected on an advance visit (i.e. clicking a link,
 * not a back or forward history navigation) if scroll-behavior: smooth; is
 * set on the <html> element. The solution is to temporarily force
 * scroll-behavior: auto; (instant scrolling) right before the render and remove
 * it once the render has finished.
 *
 * Also note that Turbo at the time of writing seems to add aria-busy to
 * <html> on clicking an in-page anchor (such as a table of contents) and not
 * remove it until navigated to a different page. Because of this, we can't
 * use a CSS-only solution.
 *
 * @see https://github.com/hotwired/turbo/issues/190#issuecomment-1525135845
 *   CSS-only solution for future reference.
 *
 * @see https://github.com/hotwired/turbo/issues/426
 *
 * @see https://github.com/hotwired/turbo/issues/698
 */
(function(html, $, once) {

  'use strict';

  /**
   * Our event namespace.
   *
   * @type {String}
   *
   * @see https://learn.jquery.com/events/event-basics/#namespacing-events
   */
  const eventNamespace = 'refreshless-turbo-disable-smooth-scroll';

  /**
   * The once() identifier for our behaviour.
   *
   * @type {String}
   */
  const onceName = eventNamespace;

  /**
   * Class added to the <html> element during a load to prevent smooth scroll.
   *
   * @type {String}
   */
  const smoothScrollDisableClass = 'refreshless-disable-smooth-scroll';

  $(once(onceName, html))
  .on(`refreshless:before-render.${eventNamespace}`, async (event) => {

    // Don't do anything if this a refresh copy being rendered replacing a
    // preview as the page is already interactive.
    if (event.detail.isFreshReplacingPreview === true) {
      return;
    }

    await event.detail.delay(async (resolve, reject) => {

      $(event.target).addClass(smoothScrollDisableClass);

      // Wait for a frame to be rendered before resolving so that instant
      // scrolling is applied by the browser before page content is swapped.
      await new Promise(requestAnimationFrame);
      await new Promise(requestAnimationFrame);

      resolve();

    });

  }).on(`refreshless:render.${eventNamespace}`, async (event) => {

    // Don't do anything if this a refresh copy being rendered replacing a
    // preview as the page is already interactive.
    if (event.detail.isFreshReplacingPreview === true) {
      return;
    }

    // Wait for at least a frame to be rendered to reduce the chance we might
    // remove the class too early and the browser ends up smooth scrolling.
    await new Promise(requestAnimationFrame);
    await new Promise(requestAnimationFrame);

    $(event.target).removeClass(smoothScrollDisableClass);

  });

})(document.documentElement, jQuery, once);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc