80

新しいposition: sticky( info ) を使用して、iOS のようなコンテンツのリストを作成しています。

以前の JavaScript の代替手段 ( example ) よりもうまく機能しており、はるかに優れています。解決。

stuckの要素がposition: stickyページの上部にヒットしたときに、クラス (例: ) を追加したいと考えています。JavaScript でこれをリッスンする方法はありますか? jQueryの使用は問題ありません。

4

11 に答える 11

2

Chrome が追加された後、十分な準備ができていないposition: stickyことが判明し、 --enable-experimental-webkit-features フラグに追いやられました。ポール アイリッシュは 2 月に「この機能はおかしな辺境状態にある」と述べました。

頭が痛くなるまでポリフィルを使用していました。うまく機能しますが、CORS の問題などのまれなケースがあり、すべての CSS リンクに対して XHR 要求を実行し、ブラウザーが無視した「position: sticky」宣言を再解析することで、ページの読み込みが遅くなります。

今はScrollToFixedを使用しています。これは、ラッパーでレイアウトを台無しにしないため、 StickyJSよりも気に入っています。

于 2013-05-01T14:59:22.020 に答える
2

現在、ネイティブ ソリューションはありません。現在「スタック」状態にある位置:スティッキー要素をターゲティングするを参照してください。position: stickyただし、スティッキー動作を実装するネイティブとポリフィルの両方で動作する CoffeeScript ソリューションがあります。

スティッキーにしたい要素に「スティッキー」クラスを追加します。

.sticky {
  position: -webkit-sticky;
  position: -moz-sticky;
  position: -ms-sticky;
  position: -o-sticky;
  position: sticky;
  top: 0px;
  z-index: 1;
}

「スティッキー」要素の位置を監視し、「スティッキー」状態のときに「スタック」クラスを追加する CoffeeScript:

$ -> new StickyMonitor

class StickyMonitor

  SCROLL_ACTION_DELAY: 50

  constructor: ->
    $(window).scroll @scroll_handler if $('.sticky').length > 0

  scroll_handler: =>
    @scroll_timer ||= setTimeout(@scroll_handler_throttled, @SCROLL_ACTION_DELAY)

  scroll_handler_throttled: =>
    @scroll_timer = null
    @toggle_stuck_state_for_sticky_elements()

  toggle_stuck_state_for_sticky_elements: =>
    $('.sticky').each ->
      $(this).toggleClass('stuck', this.getBoundingClientRect().top - parseInt($(this).css('top')) <= 1)

注: このコードは、垂直スティッキー位置でのみ機能します。

于 2014-10-03T19:22:01.360 に答える
0

私は自分のテーマでこのスニペットを使用して、スタックした位置にあるときに.is-stuckクラスを追加しています:.site-header

// noinspection JSUnusedLocalSymbols
(function (document, window, undefined) {

    let windowScroll;

    /**
     *
     * @param element {HTMLElement|Window|Document}
     * @param event {string}
     * @param listener {function}
     * @returns {HTMLElement|Window|Document}
     */
    function addListener(element, event, listener) {
        if (element.addEventListener) {
            element.addEventListener(event, listener);
        } else {
            // noinspection JSUnresolvedVariable
            if (element.attachEvent) {
                element.attachEvent('on' + event, listener);
            } else {
                console.log('Failed to attach event.');
            }
        }
        return element;
    }

    /**
     * Checks if the element is in a sticky position.
     *
     * @param element {HTMLElement}
     * @returns {boolean}
     */
    function isSticky(element) {
        if ('sticky' !== getComputedStyle(element).position) {
            return false;
        }
        return (1 >= (element.getBoundingClientRect().top - parseInt(getComputedStyle(element).top)));
    }

    /**
     * Toggles is-stuck class if the element is in sticky position.
     *
     * @param element {HTMLElement}
     * @returns {HTMLElement}
     */
    function toggleSticky(element) {
        if (isSticky(element)) {
            element.classList.add('is-stuck');
        } else {
            element.classList.remove('is-stuck');
        }
        return element;
    }

    /**
     * Toggles stuck state for sticky header.
     */
    function toggleStickyHeader() {
        toggleSticky(document.querySelector('.site-header'));
    }

    /**
     * Listen to window scroll.
     */
    addListener(window, 'scroll', function () {
        clearTimeout(windowScroll);
        windowScroll = setTimeout(toggleStickyHeader, 50);
    });

    /**
     * Check if the header is not stuck already.
     */
    toggleStickyHeader();


})(document, window);

于 2021-09-13T15:16:56.873 に答える