交差ãªãã¶ã¼ãã¼ API
Baseline
Widely available
*
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since 2019å¹´3æ.
* Some parts of this feature may have varying levels of support.
交差ãªãã¶ã¼ãã¼ API (Intersection Observer API) ã¯ã対象ã¨ãªãè¦ç´ ããç¥å è¦ç´ ã¾ãã¯ææ¸ã®æä¸ä½ã®ãã¥ã¼ãã¼ãã¨äº¤å·®ããå¤åãéåæçã«ç£è¦ããæ¹æ³ãæä¾ãã¾ãã
æ¦è¦
徿¥ãããè¦ç´ ã®å¯è¦ç¶æ ãããã㯠2 ã¤ã®è¦ç´ ã®ç¸å¯¾çãªå¯è¦ç¶æ ãæ¤åºãããã¨ã¯å°é£ã§ããããã®è§£æ±ºçã¯ä¿¡é ¼æ§ãä½ãããã©ã¦ã¶ã¼ãã¢ã¯ã»ã¹ãããµã¤ãã®åä½ãéããªãå¾åãããã¾ãããã¦ã§ããæçãã¦ããã«ã¤ãã¦ããã®ãããªæ å ±ã®å¿ è¦æ§ã¯é«ã¾ã£ã¦ããã¾ãã交差æ å ± (Intersection information) ã«ã¤ãã¦ã®æ å ±ã¯æ¬¡ã®çç±ããå¿ è¦ã¨ããã¦ãã¾ãã
- ãã¼ã¸ãã¹ã¯ãã¼ã«ããéã®ç»åããã®ä»ã®ã³ã³ãã³ãã®é å»¶èªã¿è¾¼ã¿ã
- ãç¡éã¹ã¯ãã¼ã«ããããã¦ã§ããµã¤ããå®è£ ããã¹ã¯ãã¼ã«ã«å¾ã£ã¦æ¬¡ã ã¨ã³ã³ãã³ããèªã¿è¾¼ãã§ãã¦ã¼ã¶ã¼ããã¼ã¸ã®åãæ¿ããããã«æ¸ãããã«ãããã¨ã
- åºåè²»ãè¨ç®ããããã®åºåã表示ããããã©ããã®ã¬ãã¼ãã
- ã¦ã¼ã¶ã¼ãçµæãè¦ããã©ããã§ãã¿ã¹ã¯ãå®è¡ãããã©ãããã¢ãã¡ã¼ã·ã§ã³ãå¦çãããã©ãããæ±ºå®ãããã¨ã
以åã¯ãè¦ç´ å士ã®äº¤å·®ã®æ¤åºãå®è£
ããã«ã¯ãã¤ãã³ããã³ãã©ã¼ãã«ã¼ãã§ Element.getBoundingClientRect() ãªã©ã®ã¡ã½ãããå¼ã³åºããå½±é¿ãåãããã¹ã¦ã®è¦ç´ ã«ã¤ãã¦å¿
è¦ãªæ
å ±ãèç©ãã¦ãã¾ããããã®ã³ã¼ãã¯ãã¹ã¦ã¡ã¤ã³ã¹ã¬ããã§å®è¡ãããããããããã®ãã¡ 1 ã¤ã§ãããã°ããã©ã¼ãã³ã¹ã®åé¡ãå¼ãèµ·ããå¯è½æ§ãããã¾ãããµã¤ãã§ãã®ãããªæ¤åºã大éã«è¡ãããã¨ãã¾ã£ããéããªãå¯è½æ§ãããã¾ãã
ã¦ã§ããã¼ã¸ã§ç¡éã¹ã¯ãã¼ã«ã使ç¨ãããã¨ãèãã¦ã¿ã¦ãã ããããã³ãã¼ããæä¾ãããã©ã¤ãã©ãªã¼ã使ç¨ãã¦ããã¼ã¸å ¨ä½ã«å®æçã«é ç½®ãããåºåã管çããã¢ãã¡ã¼ã·ã§ã³ã°ã©ãã£ãã¯ã¹ã表示ããéç¥ããã¯ã¹ãªã©ãæç»ããã«ã¹ã¿ã ã©ã¤ãã©ãªã¼ã使ç¨ãã¾ããããããã«ã¯ç¬èªã«äº¤å·®ãæ¤åºããããã®ã«ã¼ãã³ãããããã¹ã¦ãã¡ã¤ã³ã¹ã¬ããä¸ã§å®è¡ããã¾ããã¦ã§ããµã¤ãã®ä½è ã¯ããããèµ·ãã£ã¦ãããã¨ãèªèãã¦ããªãããããã¾ãããå é¨ã®åãã«ã¤ãã¦ã»ã¨ãã©ç¥ããã« 2 ã¤ã®ã©ã¤ãã©ãªã¼ã使ç¨ãã¦ããããã§ããã¦ã¼ã¶ã¼ããã¼ã¸ãã¹ã¯ãã¼ã«ããã¨ãã¹ã¯ãã¼ã«å¦çä¸ã«ãããã®äº¤å·®ã®æ¤åºã«ã¼ãã³ãçµ¶ããèµ·åããã¦ã¼ã¶ã¼ã¯ãã©ã¦ã¶ã¼ãã¦ã§ããµã¤ããããã³ã³ã³ãã¥ã¼ã¿ã¼ã«ã¤ã©ã¤ã©ããããããã¨ã«ãªãã¾ãã
交差ãªãã¶ã¼ãã¼ API ã¯ãç¹å®ã®è¦ç´ ãä»ã®è¦ç´ ï¼ã¾ãã¯ãã¥ã¼ãã¼ãï¼ã¨äº¤å·®ã«å ¥ã£ããåºããããã¨ããã¾ã㯠2 ã¤ã®è¦ç´ éã®äº¤å·®éãæå®ãããéã ãå¤åããã¨ãã«å®è¡ãããã³ã¼ã«ããã¯é¢æ°ããã³ã¼ããç»é²ã§ããããã«ãã¾ãããããããã¨ã§ããµã¤ãã¯ãã®ãããªè¦ç´ ã®äº¤å·®ãç£è¦ããããã«ãã¡ã¤ã³ã¹ã¬ããã§ä½ããã®å¦çãããå¿ è¦ããªããªãããã©ã¦ã¶ã¼ã¯é©åã¨æããã交差ã®ç®¡çãèªç±ã«æé©åãããã¨ãã§ãã¾ãã
交差ãªãã¶ã¼ãã¼ API ã¯ãéè¤ãããã¯ã»ã«ã®æ£ç¢ºãªæ°ããå ·ä½çã«ã©ã®ãã¯ã»ã«ãéè¤ãããã«åºã¥ãã¦ãã¸ãã¯ãèµ·åãããã¨ã¯ã§ãã¾ãããããã¯ããN % ç¨åº¦ã®ã©ããã§äº¤å·®ãã¦ããããä½ããããå¿ è¦ããããã¨ãããããä¸è¬çãªç¨éã®ã¿ã解決ãã¾ãã
æ¦å¿µã¨ä½¿ãæ¹
交差ãªãã¶ã¼ãã¼ API ã使ç¨ããã¨ã以ä¸ã®ããããã®ç¶æ³ãçºçããã¨ãã«å¼ã³åºãããã³ã¼ã«ããã¯ãæ§æãããã¨ãã§ãã¾ãã
- 対象è¦ç´ ã端æ«ã®ãã¥ã¼ãã¼ãã¾ãã¯æå®ãããè¦ç´ ã¨äº¤å·®ããã¨ãããã®æå®ãããè¦ç´ ã¯ã交差ãªãã¶ã¼ãã¼ API ã®ç¨éã§ã¯ã«ã¼ãè¦ç´ ã¾ãã¯ã«ã¼ãã¨å¼ã³ã¾ãã
- ãªãã¶ã¼ãã¼ã対象è¦ç´ ãç£è¦ããããæåã«æç¤ºãããã¨ãã
é常ã対象è¦ç´ ã®æãè¿ãã¹ã¯ãã¼ã«å¯è½ãªç¥å
ãã¾ãã¯å¯¾è±¡è¦ç´ ãã¹ã¯ãã¼ã«å¯è½ãªè¦ç´ ã®åå«ã§ãªãå ´åã¯ã端æ«ã®ãã¥ã¼ãã¼ããåºæºã«ãã¦äº¤å·®ã®å¤åãç£è¦ãããã¨æãã§ãããã端æ«ã®ãã¥ã¼ãã¼ããåºæºã«ãã¦äº¤å·®ãç£è¦ããã«ã¯ã root ãªãã·ã§ã³ã« null ãæå®ãã¾ãã交差ãªãã¶ã¼ãã¼ã®ãªãã·ã§ã³ã«ã¤ãã¦ã®ãã詳ãã説æã¯ããã®ã¾ã¾èªã¿é²ãã¦ãã ããã
ãã¥ã¼ãã¼ãã¨ãã®ä»ã®è¦ç´ ã®ã©ã¡ããã«ã¼ãã¨ãã¦ä½¿ç¨ããã¦ãã¦ãã API ã¯åãããã«åä½ãã対象è¦ç´ ã®è¡¨ç¤ºç¶æ ãå¤ãã£ã¦ã«ã¼ãã¨ã®éã§äº¤å·®ã®éã®æå¾ å¤ãéããã³ã«ãæä¾ããã³ã¼ã«ããã¯é¢æ°ãå®è¡ããã¾ãã
対象è¦ç´ ã¨ãã®ã«ã¼ãè¦ç´ ã®äº¤å·®ãã度åãã交差çã§ããããã¯å¯¾è±¡è¦ç´ ã®ãã¼ã»ã³ãå¤ã 0.0 ãã 1.0 ã®éã®å¤ã§è¡¨ç¾ãããã®ã§ãã
交差ãªãã¶ã¼ãã¼ã®ä½æ
交差ãªãã¶ã¼ãã¼ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãã¦ãããå¤ã䏿¹åã¾ãä»ã®æ¹åã«äº¤å·®ãã度ã«å®è¡ãããã³ã¼ã«ããã¯é¢æ°ã渡ããã¨ã§çæãã¾ãã
const options = {
root: document.querySelector("#scrollArea"),
rootMargin: "0px",
scrollMargin: "0px",
threshold: 1.0,
};
const observer = new IntersectionObserver(callback, options);
ãããå¤ (threshold) ã® 1.0 ã¯ã root ãªãã·ã§ã³ã§æå®ãããè¦ç´ å
ã§å¯¾è±¡ã 100% 表示ãããæã«ã³ã¼ã«ããã¯ãå¼ã³åºããããã¨ãæå³ãã¦ãã¾ãã
交差ãªãã¶ã¼ãã¼ã®ãªãã·ã§ã³
options ãªãã¸ã§ã¯ã㯠IntersectionObserver() ã³ã³ã¹ãã©ã¯ã¿ã¼ã«æ¸¡ããããªãã¶ã¼ãã¼ã®ã³ã¼ã«ããã¯ãå¼ã³åºãããç¶æ³ãå¶å¾¡ãã¾ãã以ä¸ã®ãããªãã£ã¼ã«ããããã¾ãã
root-
対象ãè¦ãããã©ããã確èªããããã®ãã¥ã¼ãã¼ãã¨ãã¦ä½¿ç¨ãããè¦ç´ ã§ããæå®ãããªãã£ãå ´åãã¾ãã¯
nullã®å ´åã¯æ¢å®ã§ãã©ã¦ã¶ã¼ã®ãã¥ã¼ãã¼ãã使ç¨ããã¾ãã rootMargin-
ã«ã¼ãè¦ç´ ã®å¨å²ã®ãã¼ã¸ã³ã§ãã CSS ã®
marginããããã£ã¨åæ§ã«ã 1 ï½ 4 ã¤ã®å¤ãããªãæååã§ãããä¾ãã°"10px 20px 30px 40px"ï¼ä¸ãå³ãä¸ãå·¦ï¼ã®ããã«æå®ãã¾ããå¤ã¯ãã¯ã»ã«åä½ (px) ã¾ãã¯ãã¼ã»ã³ãåä½ (%) ã®ã¿æå®å¯è½ã§ãããã®å¤ã®è¨å®ããçµã¿åããã¯ã交差è¨ç®åã«ã«ã¼ãè¦ç´ ã®å¢çããã¯ã¹ã®ããããã®è¾ºã伸é·ã¾ãã¯ç¸®å°ãããå½¹å²ãæããã¾ããè² ã®å¤ã¯å¢çããã¯ã¹ã縮å°ããæ£ã®å¤ã¯æ¡å¼µãã¾ããæªæå®æã®æ¢å®å¤ã¯"0px 0px 0px 0px"ã§ãã scrollMargin-
å ¥ãåã«ãªã£ãã¹ã¯ãã¼ã«ã³ã³ããã¼ã®å¨å²ã«è¨å®ããããã¼ã¸ã³ã§ã
rootMarginã¨åãå¤/æ¢å®å¤ãåãã¾ãã ãããã®ãã¼ã¸ã³ã¯ã交差ãè¨ç®ããåã«ãå ¥ãåã«ãªã£ãã¹ã¯ãã¼ã«å¯è½ãªã³ã³ããã¼ã«é©ç¨ããã¾ãã æ£ã®å¤ãæå®ããã¨ãã³ã³ããã¼ã®ã¯ãªããç©å½¢ãæ¡å¼µãã対象ãå¯è¦ã«ãªãåã«äº¤å·®ãæ¤åºãããã¨ãã§ãã¾ãã䏿¹ãè² ã®å¤ã¯ã¯ãªããç©å½¢ã縮å°ãã¾ãã threshold-
åä¸ã®æ°å¤ã¾ãã¯æ°å¤ã®é åã§ã対象ãã©ã®ãããã®å²åã§è¦ãã¦ããå ´åã«ãªãã¶ã¼ãã¼ã®ã³ã¼ã«ããã¯ãå®è¡ãããã示ãã¾ããè¦ããç¯å²ã 50% ãè¶ ããã¨ãã®ã¿æ¤åºããå ´åã¯å¤ 0.5 ã使ç¨ãã¾ãã 25% ãè¶ ãã度ã«ã³ã¼ã«ããã¯ãå®è¡ããå ´åã¯ã [0, 0.25, 0.5, 0.75, 1] ã¨ããé åãæå®ãã¾ããæ¢å®å¤ã¯ 0 ã§ãï¼ã¤ã¾ãã 1 ãã¯ã»ã«ã§ã表示ãããã¨ã³ã¼ã«ããã¯ãå®è¡ããã¾ãï¼ã 1.0 ã®å¤ã¯å ¨ã¦ã®ãã¯ã»ã«ãè¦ããããã«ãªãã¾ã§ããããå¤ãè¶ ããã¨ã¯ã¿ãªãããªããã¨ãæå³ãã¾ãã
delay-
対象ã®å¯è¦æ§ã追跡ããå ´åï¼trackVisibility ã
trueã®å ´åï¼ããããç¨ãã¦ãã®ãªãã¶ã¼ãã¼ããã®éç¥éã®æå°é å»¶ï¼ããªç§åä½ï¼ãè¨å®ãããã¨ãã§ãã¾ãã éç¥ã¬ã¼ããå¶éãããã¨ãæã¾ããã®ã¯ãå¯è¦æ§ã®è¨ç®ã®è² è·ã大ããããã§ããã å¯è¦æ§ã追跡ããå ´åã 100 æªæºã®å¤ã¯ãã¹ã¦ 100 ã«è¨å®ããã¾ãã許容ã§ããæå¤§å¤ã使ç¨ãã¾ãããã æ¢å®å¤ã¯ 0ã§ãã trackVisibility-
è«çå¤ã§ããã®
IntersectionObserverã対象ã¨ããå¯è¦æ§ã®å¤åã追跡ãããå¦ãã示ãã¾ããfalseã®å ´åã対象è¦ç´ ãã«ã¼ãè¦ç´ ã®ãã¥ã¼ãã¼ãå ã«ã¹ã¯ãã¼ã«ã¤ã³ããéã«ããã©ã¦ã¶ã¼ã¯äº¤å·®ãå ±åãã¾ããtrueã®å ´åããã©ã¦ã¶ã¼ã¯å¯¾è±¡ã¨ãããå®éã«è¡¨ç¤ºããã¦ããããä»ã®è¦ç´ ã«è¦ããã¦ããªããããã£ã«ã¿ã¼ãä¸éæåº¦ã®ç¸®å°ã座æ¨å¤æã«ãã£ã¦æªãã ãé ãããããã¦ããªããã追å ã§èª¿ã¹ã¾ãã æ¢å®ã§ã¯å¤ã¯falseã§ããå¯è¦æ§ã®è¿½è·¡ã¯è¨ç®è² è·ãé«ãããã§ãã ãããè¨å®ãããå ´åãdelayãè¨å®ããã®ãæã¾ããã§ãã
交差å¤åã³ã¼ã«ããã¯
IntersectionObserver() ã³ã³ã¹ãã©ã¯ã¿ã¼ã«æ¸¡ãã³ã¼ã«ããã¯ã¯ãIntersectionObserverEntry ãªãã¸ã§ã¯ãã®ãªã¹ãã¨ãªãã¶ã¼ãã¼èªä½ãåãåãã¾ãã
const callback = (entries, observer) => {
entries.forEach((entry) => {
// ããããã®é
ç®ã¯ã観測ããã 1 ã¤ã®å¯¾è±¡è¦ç´ ã®äº¤å·®ç¶æ
ã®å¤åã示ãã¦ãã
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
ã³ã¼ã«ããã¯ãåä¿¡ããé
ç®ã®ãªã¹ãã«ã¯ããããå¤ã®è¶
éã®çºçããããã«ã¤ã㦠1 ã¤ã® IntersectionObserverEntry ãªãã¸ã§ã¯ããè¨è¼ããã¾ããè¤æ°ã®å¯¾è±¡ããããããã¯åä¸ã®å¯¾è±¡ãçæéã§è¤æ°ã®ãããå¤ãè¶
éããå ´åã«ãä¸åº¦ã«è¤æ°ã®é
ç®ãåä¿¡ãããå¯è½æ§ãããã¾ããé
ç®ã¯ãã¥ã¼ã使ç¨ãã¦é
ä¿¡ããããããçæãããæå»é ã«ä¸¦ã¹ãããã¯ãã§ãããæ£ç¢ºãªé åºä»ãã«ã¯ã§ããã° IntersectionObserverEntry.time ã使ç¨ãã¾ããããåé
ç®ã¯ãæå®ãããè¦ç´ ã®ã©ã®é¨åãã«ã¼ãè¦ç´ ã¨äº¤å·®ãã¦ãããããã®è¦ç´ ã交差ãã¦ããã¨ã¿ãªããããã©ãããªã©ã説æãã¾ããé
ç®ã«ã¯ãã®å
·ä½çãªç¬éã®æ
å ±ã®ã¿ãå«ã¾ãã¾ããã¹ã¯ãã¼ã«æ¹åãé度ãªã©ãæéçµéã«ä¼´ãæ
å ±ãæ±ããããå ´åã¯ãåååä¿¡ããé
ç®ã®å
容ãè¨æ¶ãã¦ãèªèº«ã§è¨ç®ããå¿
è¦ãããããããã¾ããã
ã³ã¼ã«ããã¯ã¯ã¡ã¤ã³ã¹ã¬ããã§å®è¡ãããç¹ã«æ³¨æãã¦ãã ãããå¯è½ãªéãæ©ãåä½ããå¿
è¦ãããã¾ããããæéãè¦ããå¦çã§ãããªãã Window.requestIdleCallback() ã使ã£ãã»ããããã§ãããã
ä¸è¨ã®ã³ã¼ãã¹ããããã¯ãè¦ç´ ãã«ã¼ãã¨äº¤å·®ãã¦ããªãç¶æ
ããã 75% 以ä¸äº¤å·®ãã¦ããç¶æ
ã«é·ç§»ããåæ°ããã«ã¦ã³ã¿ã¼ã§è¨é²ããã³ã¼ã«ããã¯ã示ãã¦ãã¾ãããããå¤ã 0.0 ï¼æ¢å®ï¼ã®å ´åãã³ã¼ã«ããã¯ã¯ isIntersecting ã®è«çå¤ãå¤åãããã³ã«å¼ã³åºããã¾ãããããã£ã¦ããã®ã¹ããããã¯ã¾ãå¤åãæ£ã®æ¹åã§ããã調ã¹ã次㫠intersectionRatio ã 75% 以ä¸ãã©ãããå¤å®ãã¾ããããã§ããã°ãã«ã¦ã³ã¿ã¼ãå¢å ããã¾ãã
const intersectionCallback = (entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let elem = entry.target;
if (entry.intersectionRatio >= 0.75) {
intersectionCounter++;
}
}
});
};
ç£è¦å¯¾è±¡ã¨ãªãè¦ç´ ã®æå®
ãªãã¶ã¼ãã¼ã使ããããç£è¦ãã対象è¦ç´ ãæå®ããå¿ è¦ãããã¾ãã
const target = document.querySelector("#listItem");
observer.observe(target);
// ãªãã¶ã¼ãã¼ç¨ã«è¨å®ãããã³ã¼ã«ããã¯ããããã§åãã¦å®è¡ããã
// ãªãã¶ã¼ãã¼ã«å¯¾è±¡ãå²ãå½ã¦ãããã¾ã§å¾
ã¤ï¼å¯¾è±¡ãç¾å¨è¡¨ç¤ºããã¦ããªãã¦ãï¼
対象ã IntersectionObserver ã§æå®ãããããå¤ã«éãããã³ã«ãã³ã¼ã«ããã¯ãå¼ã³åºããã¾ãã
ã¾ãã root ãªãã·ã§ã³ãæå®ããå ´åã対象ã¯ã«ã¼ãè¦ç´ ã®åå«è¦ç´ ã§ ãªããã°ãªããªããã¨ã«æ³¨æã㦠ãã ããã
交差ã®è¨ç®æ¹æ³
交差ãªãã¶ã¼ãã¼ API ã«ãã£ã¦èæ ®ãããé åã¯ãã¹ã¦ç©å½¢ã§ããç°å½¢ã®è¦ç´ ã¯ãè¦ç´ å ¨ä½ãå²ãæå°ã®ç©å½¢ã§å æãã¦ããã¨ã¿ãªããã¾ããåæ§ã«ãè¦ç´ ã®å¯è¦é¨åãç©å½¢ã§ã¯ãªãå ´åãè¦ç´ ã交差ããç©å½¢ã¯è¦ç´ ã®å¯è¦é¨åå ¨ä½ãå«ãæå°ã®ç©å½¢ã§ããã¨è¦ãªããã¾ãã
IntersectionObserverEntry ãªãã¸ã§ã¯ãã«ãã£ã¦æä¾ãããæ§ã
ãªããããã£ããã©ã®ããã«äº¤å·®ã表ç¾ããããçè§£ããã¨æçã§ãããã
交差ã«ã¼ãã¨ã«ã¼ããã¼ã¸ã³
ããè¦ç´ ã¨ãã®ã³ã³ããã¼ã¨ã®äº¤å·®ãç£è¦ããã¾ãã«ãã¾ãã¯ã³ã³ããã¼ãç¥ãå¿
è¦ãããã¾ããããã§ã®ã³ã³ããã¼ã¨ã¯äº¤å·®ã«ã¼ãã¾ãã¯ã«ã¼ãè¦ç´ ã§ããããã¯ç£è¦ãããè¦ç´ ã®è¦ªè¦ç´ ã¨ãªãææ¸å
ã®ç¹å®ã®è¦ç´ ã«ãªãããææ¸ã®ãã¥ã¼ãã¼ããã³ã³ããã¼ã¨ãã¦ä½¿ç¨ããé㯠null ã«ãªããããããã«ãªãã¾ãã
ã«ã¼ã交差ç©å½¢ã¯å¯¾è±¡ããã§ãã¯ããããã«ä½¿ç¨ãããç©å½¢ã§ãããã®ç©å½¢ã¯æ¬¡ã®ããã«æ±ºã¾ãã¾ãã
- 交差ã«ã¼ããæé»ã®ã«ã¼ãï¼ããªãã¡æä¸ä½ã®
Documentï¼ã§ããå ´åãã«ã¼ã交差ç©å½¢ã¯ãã¥ã¼ãã¼ãã®ç©å½¢ã«ãªãã¾ãã - 交差ã«ã¼ãã®ããµããé¨åãåãåããã¦ããå ´åãã«ã¼ã交差ç©å½¢ã¯ã«ã¼ãè¦ç´ ã®ã³ã³ãã³ãé åã«ãªãã¾ãã
- ãã以å¤ã®å ´åã¯ãã«ã¼ã交差ç©å½¢ã¯äº¤å·®ã«ã¼ãã®ã¯ã©ã¤ã¢ã³ãç©å½¢ï¼
getBoundingClientRect()ãå¼ã³åºãã¦è¿ããããã®ï¼ã§ãã
交差ããã«ã¼ãã¨ãã¦ä½¿ç¨ãããç©å½¢ã¯ãã«ã¼ããã¼ã¸ã³ rootMargin ã IntersectionObserver ã®ä½ææã«è¨å®ãããã¨ã§èª¿æ´ãããã¨ãå¯è½ã§ãã rootMargin ã®å¤ã¯äº¤å·®ã«ã¼ãã®å¤æ¥ããã¯ã¹ã®å辺ã«è¿½å ããããªãã»ãããå®ç¾©ãã¦ãæçµçãªäº¤å·®ã«ã¼ãã®å¢çã使ãã¾ãï¼ã³ã¼ã«ããã¯ãå®è¡ãããéã«ã¯ IntersectionObserverEntry.rootBounds ã§åå¾ã§ãããã®ã§ãï¼ãæ£ã®å¤ã¯ããã¯ã¹ãæ¡å¼µããè² ã®å¤ã¯ç¸®å°ãã¾ããããããã®ãªãã»ããå¤ã¯ãã¯ã»ã«åä½ (px) ã¾ãã¯ãã¼ã»ã³ãå¤ (%) ã§ã®ã¿è¡¨ããã¨ãã§ãã¾ãã
ã«ã¼ããã¼ã¸ã³ã使ç¨ãã¦ããã¯ã¹ãæ¡å¼µãããã¨ã®å¹æã¯ããªã¼ãã¼ããã¼å¯¾è±¡ãå¯è¦åãããåã«ã«ã¼ãã¨äº¤å·®ãããã¨ãå¯è½ã«ãããã¨ã§ãã ããã¯ãä¾ãã°ãç»åãå¯è¦åãããæç¹ã§ã¯ãªãã表示é åã«å ¥ãç´åã«èªã¿è¾¼ã¿ãéå§ããããã«ä½¿ç¨ãããã¨ãã§ãã¾ãã
ä¸è¨ã®ä¾ã§ã¯ãã¹ã¯ãã¼ã«å¯è½ãªããã¯ã¹ã¨ãåæç¶æ ã§ã¯ç»é¢å¤ã«ããè¦ç´ ãããã¾ãã ã«ã¼ãè¦ç´ ã®å³ãã¼ã¸ã³ã調æ´ããã¨ã次ã®ãã¨ã確èªã§ãã¾ãã
- ãã¼ã¸ã³ãæ£ã®å¤ã®å ´åã赤ãè¦ç´ ã¯è¡¨ç¤ºããã¦ããªãã¦ãã«ã¼ãã¨äº¤å·®ãã¦ããã¨ã¿ãªãã¾ããããã¯ããã®è¦ç´ ãã«ã¼ãã®ãã¼ã¸ã³é åã¨äº¤å·®ãã¦ããããã§ãã
- ãã¼ã¸ã³ãè² ã®å ´åã赤ãè¦ç´ ãå¯è¦ã«ãªãå§ãã¦ããã«ã¼ãã®å¢çããã¯ã¹ã縮å°ããã¦ãããããã¾ã ã«ã¼ãã¨äº¤å·®ãã¦ããã¨ã¯ã¿ãªããã¾ããã
交差ã«ã¼ãã¨ã¹ã¯ãã¼ã«ãã¼ã¸ã³
ã«ã¼ãè¦ç´ ãå ¥ãåã«ãªã£ãã¹ã¯ãã¼ã«ã³ã³ããã¼ãå«ãã§ããããããã®ã¹ã¯ãã¼ã«å¯è½ãªã³ã³ããã¼ã®ããããã®å é¨ã«ãã対象ã¨ã®äº¤å·®ãç£è¦ãããå ´å ãèãã¦ã¿ã¾ãããã æ¢å®ã§ã¯ã対象è¦ç´ ã¨ã®äº¤å·®ã¯ã対象ãã«ã¼ãã§å®ç¾©ãããé åå ã«å¯è¦åãããæç¹ã§è¦³æ¸¬å¯è½ã«ãªãã¾ãã è¨ãæããã°ãã³ã³ãããã«ã¼ãå ã§ã¹ã¯ãã¼ã«è¡¨ç¤ºããããã¤å¯¾è±¡ãèªèº«ã®ã³ã³ããã¼ã®ã¯ãªããã³ã°ç©å½¢å ã§ã¹ã¯ãã¼ã«è¡¨ç¤ºãããæç¹ã§ãã
ã¹ã¯ãã¼ã«ãã¼ã¸ã³ã使ç¨ããã¨ã対象ãã¹ã¯ãã¼ã«ã³ã³ããã¼å ã§è¡¨ç¤ºãããåã¾ãã¯å¾ã®äº¤å·®ãç£è¦ãå§ãããã¨ãã§ãã¾ãã ãã®ãã¼ã¸ã³ã¯ãã«ã¼ãè¦ç´ ï¼ããèªä½ãã¹ã¯ãã¼ã«ã³ã³ããã¼ã§ããå ´åãå«ãï¼ãå«ããã«ã¼ãå ã®ãã¹ã¦ã®ãã¹ããããã¹ã¯ãã¼ã«ã³ã³ããã¼ã«è¿½å ããã交差ã®è¨ç®ã«ä½¿ç¨ãããã¯ãªããã³ã°é åãæ¡å¼µï¼æ£ã®ãã¼ã¸ã³ï¼ã¾ãã¯ç¸®å°ï¼è² ã®ãã¼ã¸ã³ï¼ãã广ãããã¾ãã
ã¡ã¢: ããããã®ã¹ã¯ãã¼ã«ã³ã³ããã¼ã§äº¤å·®ãªãã¶ã¼ãã¼ã使ãããã¼ã¸ã³é©ç¨ã叿ããã¹ã¯ãã¼ã«é åã«å¯¾ãã¦ã rootMargin ããããã£ã使ç¨ãããã¨ã§ãåæ§ã®å¹æãå®ç¾ã§ãã¾ãã ã¹ã¯ãã¼ã«ãã¼ã¸ã³ã使ç¨ããæ¹ã人éå·¥å¦çã§ãããªããªããã»ã¨ãã©ã®å ´åã 1 ã¤ã®äº¤å·®ãªãã¶ã¼ãã¼ã§ããã¹ã¦ã®å«ã¾ãã対象ãã«ãã¼ã§ããããã§ãã
ä¸è¨ã®ä¾ã§ã¯ãã¹ã¯ãã¼ã«å¯è½ãªããã¯ã¹ã¨ãåæç¶æ ã§ã¯ç»é¢å¤ã«ããç»åã«ã«ã¼ã»ã«ãããã¾ãã ã«ã¼ãè¦ç´ ä¸ã®ãªãã¶ã¼ãã¼ããã«ã«ã¼ã»ã«å ã®å¯¾è±¡ã¨ãªãç»åè¦ç´ ãç£è¦ãã¾ãã ç»åè¦ç´ ãã«ã¼ãè¦ç´ ã¨äº¤å·®ãå§ããæç¹ã§ãç»åãèªã¿è¾¼ã¾ããã交差ããã°åºåããããªãã¶ã¼ãã¼ãé¤å»ããã¾ãã
ä¸ã«ã¹ã¯ãã¼ã«ããã¨ã«ã«ã¼ã»ã«ã表示ãã¾ãã 表示ããã¦ããç»åã¯ããã«èªã¿è¾¼ã¾ããã¯ãã§ãã ã«ã«ã¼ã»ã«ãã¹ã¯ãã¼ã«ããå ´åãè¦ç´ ã表示ç¯å²ã«å ¥ã£ãç¬éã«ç»åãèªã¿è¾¼ã¾ããæ§åã確èªã§ããã¯ãã§ãã
ä¾ããªã»ããããå¾ãæä¾ããã¦ããã³ã³ããã¼ã«ã使ç¨ãã¦ã¹ã¯ãã¼ã«ãã¼ã¸ã³ã®å²åã調æ´ãããã¨ãã§ãã¾ãã 20% ã®ãããªæ£ã®å¤ãè¨å®ããã¨ãã¹ã¯ãã¼ã«ã³ã³ããã¼ã®ã¯ãªããç©å½¢ã 20% æ¡å¼µãããç»åã表示ç¯å²ã«å ¥ãåã«æ¤åºã»èªã¿è¾¼ã¾ããæ§åã確èªã§ããã¯ãã§ãã åæ§ã«ãè² ã®å¤ãè¨å®ããã¨ãç»åãæ¢ã«è¡¨ç¤ºç¯å²å ã«ããæç¹ã§äº¤å·®ãæ¤åºãããããã«ãªãã¾ãã
ãããå¤
交差ãªãã¶ã¼ãã¼ API ã¯ã対象è¦ç´ ãè¦ããéã®å¾®ç´°ãªå¤åãçºçãããã³ã«ç¥ãããã®ã§ã¯ãªãããããå¤ (threshold) ã使ç¨ãã¾ãããªãã¶ã¼ãã¼ã使ããéã«ã表示ããã対象è¦ç´ ãã©ã®ç¨åº¦è¦ãã¦ãããã®å²åã表ã 1 ã¤ä»¥ä¸ã®æ°å¤ãæå®ãããã¨ãã§ãã¾ããAPI ã¯ãããã®ãããå¤ãè¶ ãã¦è¦ãããã©ããã®å¤æ´ã®ã¿ãç¥ããã¾ãã
ä¾ãã°ã対象è¦ç´ ãè¦ããéã 25% åä½ã§å¢ãããæ¸ã£ãããããã³ã«éç¥ãåãããå ´åã¯ããªãã¶ã¼ãã¼ã使ããéã« [0, 0.25, 0.5, 0.75, 1] ã¨ããé åããããå¤ã®ãªã¹ãã¨ãã¦æå®ãã¾ãã
ã³ã¼ã«ããã¯ãå¼ã³åºãããã¨ã IntersectionObserverEntry ãªãã¸ã§ã¯ãã®ãªã¹ããåãåãã¾ããããã¯ãã«ã¼ãã¨äº¤å·®ãã度åããå¤åããé²åºéãããããã®æ¹åã«ãããå¤ãè¶ãã観測対象ãã¨ã« 1 ã¤ãã¤ããã¾ãã
対象ãç¾å¨ã«ã¼ãã¨äº¤å·®ãã¦ãããã©ããã¯ãé
ç®ã® isIntersecting ããããã£ãè¦ããã¨ã§ç¢ºèªã§ãã¾ããããã«ããããã®é
ç®ããè¦ç´ ã交差ãã¦ããç¶æ
ãã交差ããªããªãã¾ã§ã®é·ç§»ã表ãã®ãã交差ãã¦ããªãç¶æ
ãã交差ããç¶æ
ã¸ã®é·ç§»ã表ãã®ãã夿ãããã¨ãã§ãã¾ãã
交差ããç©å½¢ãã¼ãã«ãªããã¨ãããå¾ããã¨ã«æ³¨æãã¦ãã ãããããã¯ã交差é¨åã両è
ã®å¢çç·ã«ã´ã£ããæ²¿ã£ã¦ããããã¾ã㯠boundingClientRect ã®é¢ç©ãã¼ãã®å ´åã«èµ·ããå¾ããã¨ã§ãããã®ããã«å¯¾è±¡ã¨ã«ã¼ããå¢çç·ãå
±æãã¦ããç¶æ
ã¯ã交差ããç¶æ
ã«é·ç§»ããã¨ã¿ãªãã«ã¯ä¸ååã§ãã
ãããå¤ã®ä»çµã¿ãæãåãã«ã¯ãä¸ã®ããã¯ã¹ãã¹ã¯ãã¼ã«ãã¦è¦ã¦ãã ããããã®ä¸ã«ããåè²ã®ããã¯ã¹ã«ã¯åé å ¨ã¦ã«ãã¼ã»ã³ãå¤ã表示ããã¦ãã¾ããã³ã³ããã¼ãã¹ã¯ãã¼ã«ããæã«ãããã®ãã¼ã»ã³ãå¤ãå¤åãããã¨ãåããã¾ããåããã¯ã¹ã«ã¯ç°ãªããããå¤ãè¨å®ããã¦ãã¾ãã
- æåã®ããã¯ã¹ã«ã¯ãå¯è¦ç¹ã®åãã¼ã»ã³ãå¤ãè¨å®ããã¦ãã¾ããã¤ã¾ã
IntersectionObserver.thresholdsã®é åã¯[0.00, 0.01, 0.02, /*â¦,*/ 0.99, 1.00]ã¨ãªãã¾ãã - 2 ã¤ç®ã®ããã¯ã¹ã«ã¯åä¸ã®ãããå¤ãã 50% ã®ä½ç½®ã«ããã¾ãã
- 3 ã¤ç®ã®ããã¯ã¹ã«ã¯ãå¯è¦ç 10% æ¯ã«ãããå¤ãããã¾ã (0%, 10%, 20%...)
- æå¾ã®ããã¯ã¹ã®ãããå¤ã¯ 25% æ¯ã§ãã
å¯è¦æ§ã®è¿½è·¡ã¨é å»¶
æ¢å®ã§ã¯ããªãã¶ã¼ãã¼ã¯å¯¾è±¡è¦ç´ ãã«ã¼ãè¦ç´ ã®ãã¥ã¼ãã¼ãå ã«ã¹ã¯ãã¼ã«ãããéã«éç¥ãæä¾ãã¾ãã å¤ãã®ç¶æ³ã§ã¯ããã§ååã§ããã対象ããè¦è¦çã«æãªããããç¶æ ã§ã¯äº¤å·®ãå ±åããªããã¨ãéè¦ãªå ´åãããã¾ãã ä¾ãã°ãã¢ããªãã£ã¯ã¹ãåºåã¤ã³ãã¬ãã·ã§ã³ãè¨æ¸¬ããéã«ã¯ã対象è¦ç´ ãå ¨ä½ã¾ãã¯ä¸é¨ã§é ãããæªãã ããã¦ããªããã¨ãéè¦ã§ãã
trackVisibility è¨å®ã¯ãéæåº¦ã®å¤æ´ããã£ã«ã¿ã¼ã座æ¨å¤æã®é©ç¨ãªã©ã«ããããã©ã¦ã¶ã¼ãè¦è¦çã«æãªããã¦ããªãã¨èãã¦ã¿ã対象ã®äº¤å·®ã®ã¿ãå ±åãããããªãã¶ã¼ãã¼ã«æç¤ºãã¾ãã
ãã®ã¢ã«ã´ãªãºã ã¯ä¿å®çã§ãããããããªéæåº¦ä½ä¸ãªã©æè¡çã«ã¯å¯è¦ã§ããè¦ç´ ãçç¥ããå ´åãããã¾ãã
å¯è¦æ§ã®è¨ç®ã¯è¨ç®ã³ã¹ããé«ããããå¿
è¦ãªå ´åã«ã®ã¿ä½¿ç¨ããããã«ãã¾ãããã
å¯è¦æ§ã追跡ããéã«ã¯ãæå°å ±åééãå¶éããããã« delay ãè¨å®ããå¿
è¦ãããã¾ãã
æ¨å¥¨ãããè¨å®ã¯ã許容ã§ããæå¤§å¤ï¼å¯è¦æ§è¿½è·¡æã®æå°é
延㯠100 ããªç§ï¼ã«é
å»¶ãè¨å®ããããã¨ã§ãã
ã¯ãªããã³ã°ã¨äº¤å·®ç©å½¢
ãã©ã¦ã¶ã¼ã¯æ¬¡ã®ããã«æçµçãªäº¤å·®ç©å½¢ãè¨ç®ãã¾ããããã¯ãã¹ã¦å®äºããå¾ã®ç¶æ ãè¦ãã¾ããã交差ããã¤çºçããããæ£ç¢ºã«ææ¡ããããã«ããããã®æé ãçè§£ããã¨å½¹ç«ã¡ã¾ãã
- 対象è¦ç´ ã®å¤æ¥ç©å½¢ï¼ã¤ã¾ããè¦ç´ ãæ§æãããã¹ã¦ã®ã³ã³ãã¼ãã³ãã®å¤æ¥ããã¯ã¹ãå®å
¨ã«å²ãæå°ã®ç©å½¢ï¼ãã対象ã«å¯¾ãã¦
getBoundingClientRect()ãå¼ã³åºããã¨ã«ãã£ã¦åå¾ãã¾ãã ããã¯ã交差ã®ç©å½¢ã®æå¤§ã®å¤§ããã§ããæ®ãã®æé ã§ã交差ããªãé¨åãåé¤ãã¦ããã¾ãã - 対象ã®ç´æ¥ã®è¦ªãããã¯ããå¤å´ã«åãã¦ãããããã®å
å«ãããã¯ã®ã¯ãªããã³ã°ãï¼åå¨ããã°ï¼äº¤å·®ããç©å½¢ã«é©ç¨ãã¾ãã
ãããã¯ã®ã¯ãªããã³ã°ã¯ã 2 ã¤ã®ãããã¯ã®äº¤å·®ã¨ã
overflowããããã£ã§ï¼åå¨ããã°ï¼æå®ãããã¯ãªããã³ã°ã¢ã¼ãã«åºã¥ãã¦æ±ºå®ããã¾ããoverflowã«visible以å¤ãè¨å®ããã¨ãã¯ãªããã³ã°ãè¡ããã¾ãã - å
å«ããè¦ç´ ã®ä¸ã«ããã¹ããããé²è¦§ã³ã³ããã¹ãã®ã«ã¼ãããã£ãå ´åï¼
<iframe>ã«å«ã¾ããææ¸ãªã©ï¼ã交差ããç©å½¢ã¯å å«ããã³ã³ããã¹ãã®ãã¥ã¼ãã¼ãã§åãåãããã³ã³ããã¼ç¾¤ãéãã¦ä¸æ¹ã«å帰çã«ã³ã³ããã¼ã®å å«ãããã¯ãç¶ãã¾ããã§ããããæä¸ä½ã®<iframe>ã«å°éãããã交差ç©å½¢ã¯ãã¬ã¼ã ã®ãã¥ã¼ãã¼ãã«åãåããããã®ãã¬ã¼ã ã®è¦ªè¦ç´ ã交差ã«ã¼ãã«åããåå¸°ã®æ¬¡ã®ãããã¯ã«ãªãã¾ãã - 䏿¹ã¸ã®å帰ã交差ã«ã¼ãã«éããã¨ãçµæã®ç©å½¢ã交差ã«ã¼ãã®åº§æ¨ç©ºéã«å¯¾å¿ä»ãããã¾ãã
- çµæã®ç©å½¢ã¯ããããã«ã¼ã交差ç©å½¢ã¨äº¤å·®ãããã¨ã§æ´æ°ããã¾ãã
- ãã®ç©å½¢ã¯ãæçµçã«ã対象ã®
documentã®åº§æ¨ç©ºéã«å¯¾å¿ä»ãããã¾ãã
ã¤ã³ã¿ã¼ãã§ã¤ã¹
IntersectionObserver-
交差ãªãã¶ã¼ãã¼ API ã®ä¸»ãªã¤ã³ã¿ã¼ãã§ã¤ã¹ã§ããåä¸ã®äº¤å·®è¨å®ã«å¯¾ãã¦ä»»æã®æ°ã®å¯¾è±¡è¦ç´ ãç£è¦ãããªãã¶ã¼ãã¼ã使ã管çããããã®ã¡ã½ãããæä¾ãã¾ããåãªãã¶ã¼ãã¼ã¯ 1 ã¤ä»¥ä¸ã®å¯¾è±¡è¦ç´ ã¨å ±éã®è¦ªè¦ç´ ãã¾ãã¯æä¸ä½ã®
Documentã®ãã¥ã¼ãã¼ãã¨ã®äº¤å·®ã«ãããå¤åãéåæçã«ç£è¦ãããã¨ãåºæ¥ã¾ãããã®è¦ªè¦ç´ ã¾ãã¯ãã¥ã¼ãã¼ãã¯ã«ã¼ãã¨å¼ã°ãã¾ãã IntersectionObserverEntry-
ã¹ã¯ãã¼ã«ã«ãããå¤åã®ç¹å®ã®ç¬éã«ããã¦ã対象è¦ç´ ã¨ã«ã¼ãã¨ãªãã³ã³ããã¼ã¨ã®äº¤å·®ã表ç¾ãã¾ãããã®åã®ãªãã¸ã§ã¯ãã¯ã
IntersectionObserverã³ã¼ã«ããã¯ã¸ã®å ¥åãã¾ãã¯IntersectionObserver.takeRecords()ã®å¼ã³åºãã® 2 éãã®æ¹æ³ã§ã®ã¿åãåããã¨ãã§ãã¾ãã
åç´ãªä¾
ãã®åç´ãªä¾ã§ã¯ã対象è¦ç´ ã®è²ã¨éæåº¦ãè¦ç´ ã®å¯è¦æ§ã§å¤åããã¾ãã交差ãªãã¶ã¼ãã¼ API ã«ããè¦ç´ ã®è¡¨ç¤ºæéè¨å®ã§ã¯ãè¦ç´ ã®ã»ããï¼ä¾ãã°åºåãªã©ï¼ãã¦ã¼ã¶ã¼ã«è¡¨ç¤ºãããæéãæ¸¬å®ããçµ±è¨ãè¨é²ãããè¦ç´ ãæ´æ°ããããã¦ãã®æ å ±ã«ã¦ã¼ã¶ã¼ã©ãåå¿ãããã示ããããæ¡å¼µæ§ã®é«ãå ·ä½ä¾ãè¦ããã¨ãã§ããã§ãããã
HTML
ãã®ä¾ã«ããã HTML ã¯é常ã«çãã主ãªè¦ç´ ã¯å¯¾è±¡ã¨ãªãããã¯ã¹ï¼ID㯠"box" ã¨ãã¾ããï¼ã¨ããã¯ã¹å
ã®ã³ã³ãã³ãã§ãã
<div id="box">
<div class="vertical">Welcome to <strong>The Box!</strong></div>
</div>
CSS
ãã® CSS ã¯ãã®ä¾ã§ã¯ãã¾ãéè¦ã§ã¯ããã¾ããããã® CSS ã¯è¦ç´ ãã¬ã¤ã¢ã¦ããã background-color 㨠border 屿§ã CSS ãã©ã³ã¸ã·ã§ã³ã«å ãããã¨ãã§ããããã«ããè¦ç´ ãå¤å°è¦ããªããªãã¨ãã®å¤æ´ã«å½±é¿ãä¸ããã®ã«ä½¿ç¨ãã¾ãã
#box {
background-color: rgb(40 40 190 / 100%);
border: 4px solid rgb(20 20 120);
transition:
background-color 1s,
border 1s;
width: 350px;
height: 350px;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.vertical {
color: white;
font: 32px "Arial";
}
.extra {
width: 350px;
height: 350px;
margin-top: 10px;
border: 4px solid rgb(20 20 120);
text-align: center;
padding: 20px;
}
JavaScript
æå¾ã«ã交差ãªãã¶ã¼ãã¼ API ã使ã£ã¦ä½ãã§ããã®ãã JavaScript ã®ã³ã¼ããè¦ã¦ããã¾ãããã
ã»ããã¢ãã
ã¾ãã¯ãããã¤ãã®å¤æ°ãæºåãã¦ãªãã¶ã¼ãã¼ãã¤ã³ã¹ãã¼ã«ããå¿ è¦ãããã¾ãã
const numSteps = 20.0;
let boxElement;
let prevRatio = 0.0;
let increasingColor = "rgb(40 40 190 / ratio)";
let decreasingColor = "rgb(190 40 40 / ratio)";
// ã»ããã¢ãããã
window.addEventListener(
"load",
(event) => {
boxElement = document.querySelector("#box");
createObserver();
},
false,
);
ã»ããã¢ãããã宿°ã¨å¤æ°ã¯ä¸è¨ã®éãã§ãã
numSteps-
å¯è¦çã 0.0 ãã 1.0 ã®éã«ã©ã®ãããã®æ°ã®ãããå¤ãè¨å®ããã示ã宿°ã§ãã
prevRatio-
ãã®å¤æ°ã¯ãããå¤ãè¶ ããæå¾ã®å¯è¦çãè¨é²ããããã«ä½¿ç¨ãã¾ããããã¯å¯¾è±¡è¦ç´ ã大ä½è¦ããããã«ãªã£ããã©ããã調ã¹ããã¨ãåºæ¥ã¾ãã
increasingColor-
å¯è¦çãå¢å ãã¦ããæã«å¯¾è±¡è¦ç´ ã«é©ç¨ããè²ãå®ç¾©ããæååã§ããæååã®ä¸ã® "æ¯ç" ã¨ããåèªã¯å¯¾è±¡è¦ç´ ã®ç¾å¨ã®å¯è¦çã«ç½®ãæããããè¦ç´ ãè²ãå¤åãããã ãã§ãªãä¸éæã«ãªãã«ã¤ãã¦éæåº¦ãå¢ãã¦ããã¾ãã
decreasingColor-
åæ§ã«ãå¯è¦çãæ¸å°ãã¦ããæã«é©ç¨ããè²ãå®ç¾©ããæååã§ãã
Window.addEventListener() ãå¼ã³åºã㦠load ã¤ãã³ãã®å¾
ã¡åããéå§ãã¾ãããã¼ã¸ã®èªã¿è¾¼ã¿ãå®äºããã¨ãquerySelector() ã使ç¨ã㦠ID ã "box" è¦ç´ ã¸ã®åç
§ãåå¾ãã createObserver() ã¡ã½ãããå¼ã³åºãã¦äº¤å·®ãªãã¶ã¼ãã¼ã®è¨å®ã¨ã¤ã³ã¹ãã¼ã«å¦çãéå§ãã¾ãã
交差ãªãã¶ã¼ãã¼ã®ä½æ
createObserver() ã¡ã½ããã¯æ°ãã交差ãªãã¶ã¼ãã¼ (IntersectionObserver) ã使ãã対象è¦ç´ ã®ç£è¦ãéå§ããããã«ãã¼ã¸ãå®å
¨ã«èªã¿è¾¼ã¾ãã¦ããå¼ã³åºããã¾ãã
function createObserver() {
let observer;
let options = {
root: null,
rootMargin: "0px",
threshold: buildThresholdList(),
};
observer = new IntersectionObserver(handleIntersect, options);
observer.observe(boxElement);
}
ãã®é¢æ°ã§ã¯ãªãã¶ã¼ãã¼ã®è¨å®ãå«ã options ãªãã¸ã§ã¯ããè¨å®ãããã¨ããå§ãã¾ããææ¸ã®ãã¥ã¼ãã¼ãã«å¯¾ãã¦å¯¾è±¡è¦ç´ ãã©ã®ãããè¦ãã¦ãããã¨ããå¤åãç£è¦ãããã®ã§ã root 㯠null ã«ãã¾ãããã¼ã¸ã³ã¯å¿
è¦ããªãã®ã§ããã¼ã¸ã³ãªãã»ããã§ãã rootMargin è¨å®ã¯ "0px" ã¨æå®ãã¦ãã¾ããããã«ãã£ã¦ããªãã¶ã¼ãã¼ã¯è¿½å ãããï¼ã¾ãã¯å·®ãå¼ãããï¼ç©ºéããªãã¦ã対象è¦ç´ ã®å¢çã¨ãã¥ã¼ãã¼ãã®å¢çã®äº¤å·®ç¹ãã©ãå¤åããã®ãç£è¦ãéå§ãããã¨ãã§ãã¾ãã
å¯è¦çã®ãããå¤ã®ãªã¹ãã§ããã threshold ã¯é¢æ° buildThresholdList() ã«ãã£ã¦æ§æããã¾ãããããå¤ã®ãªã¹ãã¯ããã®ä¾ã§ã¯ããã°ã©ã ã«ãã£ã¦è¨ç®ããã¦ãã¾ãããã®æ°ãæå³çã«èª¿æ´å¯è½ã ããã§ãã
options ãç¨æã§ããããæ°ãããªãã¶ã¼ãã¼ã使ãã¤ã¾ãIntersectionObserver() ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãã¦ããããå¤ãã¾ããã éã«å¼ã°ãã颿° handleIntersect() ãæå®ãããªãã·ã§ã³ãæå®ãã¾ããæ¬¡ã«ãè¿ããããªãã¶ã¼ãã¼ã«å¯¾ã㦠observe() ãå¼ã³åºããå¿
è¦ãªå¯¾è±¡è¦ç´ ãæ¸¡ãã¾ãã
observer.observe() ãããããã®è¦ç´ ã«å¯¾ãã¦å¼ã³åºããã¨ã«ããããã¥ã¼ãã¼ãã«å¯¾ãã¦äº¤å·®ãå¤åãã¦ããããè¤æ°ã®è¦ç´ ããç£è¦ãããã¨ãåºæ¥ã¾ãã
ããã夿¯çã®é åãçµã¿ç«ã¦ã
ãããå¤ã®ãªã¹ãã使ãã buildThresholdList() 颿°ã¯æ¬¡ã®ããã«ãªãã¾ãã
function buildThresholdList() {
let thresholds = [];
let numSteps = 20;
for (let i = 1.0; i <= numSteps; i++) {
let ratio = i / numSteps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
ãã㯠1 㨠numSteps ã®éã®åæ´æ° i ã«å¯¾ãã¦ãå¤ i/numSteps ããããå¤ã®é
åã«å
¥ãããã¨ã§ãããããã 0.0 㨠1.0 ã®éã®æ¯çã§ãããããå¤ã®é
åã使ãã¦ãã¾ããã¾ãã0 ãé
åã«å«ãã¾ããæ¢å®ã® numSteps (20) ãæå®ãããçµæã以ä¸ã®ãããå¤ã®ãªã¹ãã表示ããã¾ãã
| # | ç | # | ç |
|---|---|---|---|
| 0 | 0.05 | 11 | 0.6 |
| 1 | 0.1 | 12 | 0.65 |
| 2 | 0.15 | 13 | 0.7 |
| 3 | 0.2 | 14 | 0.75 |
| 4 | 0.25 | 15 | 0.8 |
| 5 | 0.3 | 16 | 0.85 |
| 6 | 0.35 | 17 | 0.9 |
| 7 | 0.4 | 18 | 0.95 |
| 8 | 0.45 | 19 | 1 |
| 9 | 0.5 | 20 | 0 |
| 10 | 0.55 |
ãã¡ããããããå¤ã®é åããã¼ãã³ã¼ããããã¨ã¯å¯è½ã§ããããããããã¡ãªãã¨ã§ãããããããã®ä¾ã§ã¯è¨å®ã追å ãããã¨ã§ç²åº¦ã調æ´ãããããããä½å°ãæ®ã£ã¦ãã¾ãã
交差ã®å¤åã®å¦ç
ãã©ã¦ã¶ã¼ã¯å¯¾è±¡è¦ç´ ï¼ãã®å ´å㯠"box" ã¨ãã ID ãæã¤è¦ç´ ï¼ã表示ããã¦ããããã¾ãã¯ã©ã®ãããè¦ãã¦ãããã¨ããæ¯çãããããå¤ã®ãªã¹ãã«ããå¤ã® 1 ã¤ãã¾ãããã¨ãæ¤åºãã¦ã handleIntersect() ãå¼ã³åºãã¾ãã
function handleIntersect(entries, observer) {
entries.forEach((entry) => {
if (entry.intersectionRatio > prevRatio) {
entry.target.style.backgroundColor = increasingColor.replace(
"ratio",
entry.intersectionRatio,
);
} else {
entry.target.style.backgroundColor = decreasingColor.replace(
"ratio",
entry.intersectionRatio,
);
}
prevRatio = entry.intersectionRatio;
});
}
ãªã¹ãã§ãã entries å
ã«ãã IntersectionObserverEntry ã«ã¤ãã¦ãentry ã® intersectionRatio ã䏿ãã¦ãããã調ã¹ã¾ãã䏿ãã¦ããã°å¯¾è±¡ã® background-color ã« increasingColor ï¼"rgb(40 40 190 / ratio)" ã ã£ããã¨ãæãåºãã¦ãã ããï¼ã®å¤ãã»ãããããã®éã«ãã®ä¸ã«ãã "ratio" ã¨ããæååã entry ãæã¤ intersectionRatio ã¨ç½®ãæãã¾ãããã®çµæãè²ã夿´ãããã ãã§ãªãã対象è¦ç´ ã®éæåº¦ã夿´ããã¾ãã交差ããæ¯çãä¸ããã«é£ãã¦ãèæ¯è²ã®ã¢ã«ãã¡å¤ãä¸ããããéæåº¦ã®é«ãè¦ç´ ã¨ãªãã¾ãã
åæ§ã«ã intersectionRatio ãä¸ãã£ã¦ããå ´å㯠decreasingColor ãæååã¨ãã¦ä½¿ç¨ã "ratio" ã¨ããæååã intersectionRatio ã§ãã£ã¦ç½®ãæãããã¨ã«ãè¦ç´ ã® background-color ã¨ãã¦é©ç¨ãã¾ãã
æå¾ã«ã交差ããå²åãä¸ãã£ã¦ãããä¸ãã£ã¦ãããã追跡ããããã«ã夿° prevRatio ã«ç¾å¨ã®æ¯çã代å
¥ãã¦ããã¾ãã
çµæ
以ä¸ããã®çµæå 容ã§ãããã¼ã¸ãä¸ä¸ã«ã¹ã¯ãã¼ã«ãã¦ãããã¯ã¹ã®å¤è¦³ãã©ãå¤åãããã確èªãã¦ã¿ã¾ãããã
ããå¿ç¨çãªä¾ã¯äº¤å·®ãªãã¶ã¼ãã¼ API ã«ããè¦ç´ ã®è¡¨ç¤ºæéè¨å®ã®ç¯ãè¦ã¦ãã ããã
仿§æ¸
| Specification |
|---|
| Intersection Observer > # intersection-observer-interface > |