新しいposition: sticky
( info ) を使用して、iOS のようなコンテンツのリストを作成しています。
以前の JavaScript の代替手段 ( example ) よりもうまく機能しており、はるかに優れています。解決。
stuck
の要素がposition: sticky
ページの上部にヒットしたときに、クラス (例: ) を追加したいと考えています。JavaScript でこれをリッスンする方法はありますか? jQueryの使用は問題ありません。
Chrome が追加された後、十分な準備ができていないposition: sticky
ことが判明し、 --enable-experimental-webkit-features フラグに追いやられました。ポール アイリッシュは 2 月に「この機能はおかしな辺境状態にある」と述べました。
頭が痛くなるまでポリフィルを使用していました。うまく機能しますが、CORS の問題などのまれなケースがあり、すべての CSS リンクに対して XHR 要求を実行し、ブラウザーが無視した「position: sticky」宣言を再解析することで、ページの読み込みが遅くなります。
今はScrollToFixedを使用しています。これは、ラッパーでレイアウトを台無しにしないため、 StickyJSよりも気に入っています。
現在、ネイティブ ソリューションはありません。現在「スタック」状態にある位置:スティッキー要素をターゲティングするを参照してください。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)
注: このコードは、垂直スティッキー位置でのみ機能します。
私は自分のテーマでこのスニペットを使用して、スタックした位置にあるときに.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);