簡體   English   中英

IntersectionObserver 在 Safari 或 iOS 中不起作用

[英]IntersectionObserver not working in Safari or iOS

我有一段代碼根據元素是從頂部還是底部滾動進入或退出視口,將不同的 css class 添加到元素中。

它使用Intersection Observer因為它應該比scroll事件更好地處理大量元素。

但是,這段代碼我面臨兩個問題:

  1. 它在 Safari(最新版本)中不起作用
  2. 它不適用於移動 Apple 設備

這很奇怪,因為 IntersectionObserver 應該可以在 Safari 甚至是 iOS 上的移動瀏覽器上正常工作。

您可以在 jsFiddle 上找到代碼或在此處查看代碼片段:

 const config = { // Add root here so rootBounds in entry object is not null root: document, // Margin to when element should take action rootMargin: '-50px 0px', // Callback will be fired 30 times during intersection threshold: [...Array(30).keys()].map(x => x / 29) }; let observer = new IntersectionObserver(function(entries, observer) { entries.forEach((entry, index) => { const element = entry.target; // Get root element (document) coords const rootTop = entry.rootBounds.top; const rootBottom = entry.rootBounds.height; // Get div coords const topBound = entry.boundingClientRect.top - 50; // margin in config const bottomBound = entry.boundingClientRect.bottom; let className; // Do calculations to get class names if (topBound < rootTop && bottomBound < rootTop) { className = "outview-top"; } else if (topBound > rootBottom) { className = "outview-bottom"; } else if (topBound < rootBottom && bottomBound > rootBottom) { className = "inview-bottom"; } else if (topBound < rootTop && bottomBound > rootTop) { className = "inview-top"; } element.setAttribute('data-view', className); }); }, config); const viewbox = document.querySelectorAll('.viewme'); viewbox.forEach(image => { observer.observe(image); });
 body { text-align: center; }.margins { position: fixed; top: 50px; bottom: 50px; border-top: 2px dashed; border-bottom: 2px dashed; z-index: 1; left: 0; width: 100%; pointer-events: none; }.hi { padding: 40vh 0; background: lightgray; }.box { width: 23%; min-width: 100px; height: 40vh; margin-bottom: 10px; background: lightblue; display: inline-block; }.viewme { transition: all.3s ease; }.viewme[data-view='inview-top'], .viewme[data-view='inview-bottom'] { opacity: 1; transform: translateY(0); }.viewme[data-view='outview-top'] { opacity: 0; transform: translateY(-20px); }.viewme[data-view='outview-bottom'] { opacity: 0; transform: translateY(20px); }
 <p class="hi">Scroll down and back up</p> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class="box viewme"></div> <div class='margins'> </div>

到目前為止,對於可能導致這些問題的原因,我有兩個提示:

  1. 在 Safari 開發人員控制台中,它說我的 JS 代碼中的第 10 行和第 38 行之間存在Type error
  2. 我注意到其他定義root: document的腳本在 iOS 上不起作用。 相反,它們在定義root: null 但是,我不能使用root: null因為rootBounds 我試圖將我的 html 包裝在一個 div 中,並將 div 的 id 設置為根元素,但這不起作用(請參閱此處)。

非常感謝解決這兩個問題的任何幫助。 但是,請務必考慮到我沒有編寫上面的代碼並且不太了解它。

雖然我無法確定錯誤的確切原因,但我確實有一個解決方案:

嘗試使用document.body作為root並定義htmlbody的大小和滾動行為。

我認為這與document不僅僅是一個簡單的 html 節點(我也嘗試使用document.documentElement沒有成功)以及 Safari 如何為它初始化框 model 相關。

無論如何,這是更新的工作小提琴https://jsfiddle.net/gion_13/okrcgejt/8/和 iOS 和 Mac Z50DE9BC68C93DC312D760C7C90593Z 上的測試的截屏視頻:

在此處輸入圖像描述 在此處輸入圖像描述

我找不到您的問題的解決方案,但是當我將閾值從 1 降低到 0.9 時,我的問題得到了解決。 當它設置為 1 時,交叉點觀察器在 Safari 中不起作用。 但它在 Firefox 和 Chrome 中完美運行。

const options={
    root:null,
    rootMargin:'0px',
    threshold:0.9
 };

無論根設置為 null 還是 document.body,它都有效。 出於某種原因,當我請求 Safari 中的交叉點觀察器僅在 object 100% 完全可見時觸發時它不起作用,但它適用於 90%。 我希望這可以幫助那里的人。

我最近遇到了同樣的問題,為了解決這個問題,我只需要

設置根目錄:null

對我來說工作document.body和任何不同的閾值然后[] || 0 [] || 0 .

const options = {
    root: document.body,
    threshold: 0.000001
}

我想我找到了問題所在。 如果您的項目對於視口(屏幕)來說太高(高度),則元素將永遠不會符合閾值,至少它足夠小。 這就是為什么我相信@donquixote 的答案很奇怪但正確。

 const options = {
      root: null,
      rootMargin: "0px",
      threshold: 0.1,
    };

這對我有用。

僅供參考,如果您查看 MDN - https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#browser_compatibility

root can't be the document in Safari, IE, Safari IOS and Firefox Android. 至於為什么會這樣,我不知道,只是分享這已經是一個已知問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM