【この訳に特有な表記規約】
◎表記記号- 用語 `文書@ は、 `Document$I ~interfaceを実装する~objのうち, (この語が現れる文脈に適切な,ある`閲覧~文脈$にて)`作動中な文書$bcを指す。 【!原文では window.document を指す document 】
- 用語 `要素@ は、 `Element$I ~interfaceを実装する~objの略記である。
- %target . `xyz^sl という表記は、[ %target の `xyz^sl 内部~slot ]の略記である。
1. 序論
~webの伝統的な位置~計算の仕組みは、 ~DOM状態を明示的に~queryすることに依拠する。 それは、 (高価な)~styleの再計算, および~layoutを生じさせることが既知である。 この情報の継続的な~pollingは、 有意な処理能~overheadの~~要因になることは頻繁にある。 ◎ The web’s traditional position calculation mechanisms rely on explicit queries of DOM state that are known to cause (expensive) style recalculation and layout and, frequently, are a source of significant performance overhead due to continuous polling for this information.
上述の挙動に依拠するような,共通的な実施~自体は — 次に挙げるものを含めて — 発展したが: ◎ A body of common practice has evolved that relies on these behaviors, however, including (but not limited to):
- ~DOMや~dataに対する~customな事前読込み/遅延読込みを築くとき。 ◎ Building custom pre- and deferred-loading of DOM and data.
- ~data集合の一部分を読込んで描画するような,~dataに束縛された高-処理能な~scroll用~listを実装するとき。 これは、 携帯~機において中心的な対話上の成句になっている。 ◎ Implementing data-bound high-performance scrolling lists which load and render subsets of data sets. These lists are a central mobile interaction idiom.
-
要素の可視率を計算するとき。 特に,広告~networkでは、 今や,`収益集計~用に広告の “可視率” を報告することが要求されている@http://www.iab.net/iablog/2014/03/viewability-has-arrived-what-you-need-to-know-to-see-through-this-sea-change.html$。 その結果、 多くの~siteが,次に至っている: ◎ Calculating element visibility. In particular, ad networks now require reporting of ad "visibility" for monetizing impressions. This has led to many sites\
- ~scroll~handlerを濫用する (その結果、~scroll時に詰まる( “`scroll jank^en” )) ◎ abusing scroll handlers (causing jank on scroll),\
- `同期的~layoutを呼出すような再読取り@http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html$ ( `requestAnimationFrame()@~HTMLGAPI#dom-animationframeprovider-requestanimationframe$m ~loop内で不必要に重い作業を行う) 【例: `getComputedStyle()@~CSSOM1#dom-window-getcomputedstyle$m で最新な~layout情報を~queryするなど。】 ◎ synchronous layout invoking readbacks (causing unnecessary critical work in rAF loops),\
- 要素の “真の” 可視率を算出するため,~~外部~pluginによる解決策に頼る (~plugin~architectureによる~overheadすべてが伴われる) ◎ and resorting to exotic plugin-based solutions for computing "true" element visibility (with all the associated overhead of the plugin architecture).
これらの利用事例には、 共通な性質がある: ◎ These use-cases have several common properties:
- 個々の要素の[ 他の要素(または大域的な`表示域$)に~~相対的な状態 ]を受動的に “~queryするもの” として表現できる。 ◎ They can be represented as passive "queries" about the state of individual elements with respect to some other element (or the global viewport).
- 厳しい刻限を課すものではない。 つまり、 情報を代償なしに非同期的に(例:別~threadから)送達できる。 ◎ They do not impose hard latency requirements; that is to say, the information can be delivered asynchronously (e.g. from another thread) without penalty.
- 既存の~web~platform特能の どの組合nからも,ほぼ~supportに乏しいため、 普及しているにもかかわらず,開発者は余計な労を要している。 ◎ They are poorly supported by nearly all combinations of existing web platform features, requiring extraordinary developer effort despite their widespread use.
目標とされてはいないが注目すべき点として、 実際に何が表示されているかについての,~pixel~~単位の情報もある (ある種の~browser~architectureにおいては、 ~filter, WebGL, その他の特能に面したとき,効率的にこれを得するのは極めて困難なこともある)。 この情報は、 これらの局面すべてに有用になる — たとえ、 遅延が少しあって,送達される~dataが不完全な組成結果によるときでも。 ◎ A notable non-goal is pixel-accurate information about what was actually displayed (which can be quite difficult to obtain efficiently in certain browser architectures in the face of filters, webgl, and other features). In all of these scenarios the information is useful even when delivered at a slight delay and without perfect compositing-result data.
交差~観測器~APIは、[ 他の要素や大域的な`表示域$に~~相対的な要素の位置 ]を[ 非同期的に~queryするための新たな~method ]を開発者に与えることにより, 上述の課題に取組む。 非同期的な送達により,~costがかかる[ ~DOMや~styleの~query/ 継続的な~polling/ ~custom~pluginの利用 ]は不要になるので、 ~appは[ CPU, GPU, ~energy ]~costを有意に抑制できるようになる。 ◎ The Intersection Observer API addresses the above issues by giving developers a new method to asynchronously query the position of an element with respect to other elements or the global viewport. The asynchronous delivery eliminates the need for costly DOM and style queries, continuous polling, and use of custom plugins. By removing the need for these methods it allows applications to significantly reduce their CPU, GPU and energy costs.
var %observer = new IntersectionObserver(%changes => { for (const %change of %changes) { /* 変化が生じた時点を表す時刻印: */ console.log(%change.`time$m); /* `交差~root$の区画: */ console.log(%change.`rootBounds$m); /* %target が占める区画( `getBoundingClientRect()$m ): */ console.log(%change.`boundingClientRect$m); /* `交差~root$内の %target の可視~域 ( `boundingClientRect^m を %target の`包含塊~連鎖$に属する各 先祖で~clipして得られる区画と `rootBounds^m との交差域): */ console.log(%change.`intersectionRect$m); /* %target が占める区画のうち, %target の可視~部分が占める比率 ( `intersectionRect^m の面積 ~DIV `boundingClientRect^m の面積): */ console.log(%change.`intersectionRatio$m); /* `~target$にされた要素( %target ): */ console.log(%change.`target$m); } }, {}); var %target = ... /* `~target$にする要素 */ ; /* 特定の`~target$に対し,交差~eventを観測し始める: */ %observer.`observe(target)$m; /* 特定の`~target$に対し,観測するのを停止する: */ %observer.`unobserve(target)$m; /* すべての`~target$に対し,観測するのを停止する: */ %observer.`disconnect()$m;
var observer = new IntersectionObserver(changes => { for (const change of changes) { console.log(change.time); // Timestamp when the change occurred console.log(change.rootBounds); // Unclipped area of root console.log(change.boundingClientRect); // target.getBoundingClientRect() console.log(change.intersectionRect); // boundingClientRect, clipped by its containing block ancestors, and intersected with rootBounds console.log(change.intersectionRatio); // Ratio of intersectionRect area to boundingClientRect area console.log(change.target); // the Element target } }, {}); // Watch for intersection events on a specific target Element. observer.observe(target); // Stop watching for intersection events on a specific target Element. observer.unobserve(target); // Stop observing threshold events on all target elements. observer.disconnect();
2. 交差~観測器
`交差~観測器@ ~APIは、 開発者が次を得れるようにする ⇒ `~target@ にされた~DOM要素†の,`交差~root$の中での[ 可視率, 位置 ] 【† 具体的には、観測器の `ObservationTargets$sl 内にあるもの。】 ◎ The Intersection Observer API enables developers to understand the visibility and position of target DOM elements relative to an intersection root.
2.1. `IntersectionObserverCallback^I
callback `IntersectionObserverCallback@I = `undefined$ (`sequence$<`IntersectionObserverEntry$I> %entries, `IntersectionObserver$I %observer);
この~callbackは、 `~target$と`交差~root$との交差に変化が生じたとき,`§ 処理~model$にしたがって呼出されることになる。 ◎ This callback will be invoked when there are changes to a target’s intersection with the intersection root, as per the processing model.
【 見かけ上の交差が~UAからどう認識されるかは、 ~UAや処理能に依存するかもしれない — 例えば,高速に~scrollしたとき、 その途上で~~表示が “間引かれた” 箇所があれば,その箇所にある~targetとの交差は見過ごされることになる — 交差が検出される時機は,~UAの`各~描画~更新ごと@#event-loop$なので。 】
2.2. `IntersectionObserver^I ~interface
`IntersectionObserver$I ~interfaceを利用することで、[ `交差~root$と`~target$にされた各`要素$ ]の交差における変化を観測できる。 ◎ The IntersectionObserver interface can be used to observe changes in the intersection of an intersection root and one or more target Elements.
所与の `IntersectionObserver$I ~obj %観測器 用の `交差~root@ は、 %観測器 . `root$sl %~root に応じて:
-
~NULL でないならば, %~root になる。
この場合, %観測器 は、 `明示的な~root観測器@ と称され,次を満たす どの`要素$も`~target$として観測できる ⇒ `包含塊~連鎖$において %~root の子孫である 【すなわち,`~box~tree$における子孫である】
-
~NULL ならば,`暗黙的な~root$になる。
`暗黙的な~root@ とは、 `~top-level閲覧~文脈$の文書~node†である。
【† 精確には、 %観測器 に`関連な大域~obj$に`対応する閲覧~文脈$の`~top-level閲覧~文脈$bcにて`作動中な文書$bcになろう。 】【 この仕様は,`閲覧~文脈$に基づいて述べているが、 `~navigable$に基づくよう改められるべきに思われる。 】
この場合, %観測器 は、 `暗黙的な~root観測器@ と称され,[ `~top-level閲覧~文脈$, およびその`子孫~閲覧~文脈~list$ ]を成すどの`要素$も, %観測器 用の妥当な`~target$になる。
~APIは、 `暗黙的な~root観測器$を処するとき,その各`~target$のうち[ `同じ生成元~domainに属する$もの, 他のもの ]を区別して処する。 `~target$は、[ それに`関連な設定群~obj$の`生成元$enV【!`生成元$】は`~top-level生成元$enVと`同じ生成元~domain$である ]ならば, `同じ生成元~domainに属する@ ( `same-origin-domain target^en ) とされ,他の場合は `同じ生成元~domainに属さない@ ( `cross-origin-domain target^en ) とされる。 `明示的な~root観測器$の`~target$は、 常に`同じ生成元~domainに属する$ — その`~target$は、 `交差~root$と同じ`文書$内にあることが要求されるので。 ◎ When dealing with implicit root observers, the API makes a distinction between a target whose relevant settings object’s origin is same origin-domain with the top-level origin, referred to as a same-origin-domain target; as opposed to a cross-origin-domain target. Any target of an explicit root observer is also a same-origin-domain target, since the target must be in the same document as the intersection root.
注記: `MutationObserver$I においては, `MutationObserverInit$I が~option群として `~observe0()$m に渡される一方で、 `IntersectionObserver$I においては,~option群は構築子に渡される。 この違いは、 `MutationObserver$I においては,観測する `Node$I ごとに 【変異の~~種類を】 絞込むための属性の集合を違えれることによる。 `IntersectionObserver$I においては、 開発者は,[ 同じ~option群を利用している単独の観測器 ]を利用して複数の~targetを追跡できる — あるいは、 追跡する各~targetごとに異なる観測器を利用できる。 各`~target$ごとに[ `rootMargin$mb / `threshold$mb ]値を違えれるようにしても、 利用事例は拡がらず,複階性が増すだけに見える。 その必要が将来に発生したときは、 `observe()$m ごとに~optionを供することもあり得る。 ◎ Note: In MutationObserver, the MutationObserverInit options are passed to observe() while in IntersectionObserver they are passed to the constructor. This is because for MutationObserver, each Node being observed could have a different set of attributes to filter for. For IntersectionObserver, developers may choose to use a single observer to track multiple targets using the same set of options; or they may use a different observer for each tracked target. rootMargin or threshold values for each target seems to introduce more complexity without solving additional use-cases. Per-observe() options could be provided in the future if the need arises.
[`Exposed$=Window] interface `IntersectionObserver@I { `IntersectionObserver$mc(`IntersectionObserverCallback$I %callback, optional `IntersectionObserverInit$I %options = {}); readonly attribute (`Element$I or `Document$I)? `root$m; readonly attribute `DOMString$ `rootMargin$m; readonly attribute `DOMString$ `scrollMargin$m; readonly attribute `FrozenArray$<`double$> `thresholds$m; readonly attribute `long$ `delay$m; readonly attribute `boolean$ `trackVisibility$m; `undefined$ `observe$m(`Element$I %target); `undefined$ `unobserve$m(`Element$I %target); `undefined$ `disconnect$m(); `sequence$<`IntersectionObserverEntry$I> `takeRecords$m(); };
`unobserve(target)@m ~method~手続きは: ⇒ `~target要素を観測し終える$( コレ, %target ) ◎ unobserve(target) • Run the unobserve a target Element algorithm, providing this and target.
注記: `MutationObserver$I は `unobserve()$m を実装しない。 `unobserve()$m は、 `IntersectionObserver$I 用に,~lazy読込ngの利用事例に取組むためにある — その事例では、 %target 用の読込ngが起動された後は追跡する必要もなくなるので。 [ すべての`~target$を `disconnect()$m した上で,必要なものを `observe()$m するとき ]や[ 各 `~target$ごとに別々な `IntersectionObserver$I を作成するとき ]には、 もっと作業が要ることになる。 ◎ • Note: MutationObserver does not implement unobserve(). For IntersectionObserver, unobserve() addresses the lazy-loading use case. After loading is initiated for target, it does not need to be tracked. It would be more work to either disconnect() all targets and observe() the remaining ones, or create a separate IntersectionObserver for each target.
`disconnect()@m ~method~手続きは:
- コレ . `ObservationTargets$sl を成す ~EACH( %~target ) に対し ⇒ %~target . `RegisteredIntersectionObservers$sl から[ `観測器$rp ~EQ コレ ]を満たす`交差~観測器~登録$を除去する
- コレ . `ObservationTargets$sl を空にする
`takeRecords()@m ~method~手続きは: ◎ takeRecords()
- %~queue ~LET コレ . `QueuedEntries$sl の複製 ◎ • Let queue be a copy of this’s internal [[QueuedEntries]] slot.
- コレ . `QueuedEntries$sl を空にする ◎ • Clear this’s internal [[QueuedEntries]] slot.
- ~RET %~queue ◎ • Return queue.
【 この訳では、 以下に挙げられる各~属性の[ 意味論に関する記述 ]を[ 対応する`各~内部~slotの定義@#intersection-observer-private-slots$ ]へ移動することにする — 他所からは、 内部~slotの方が首に参照されるので。 】
`rootMargin@m 取得子~手続きは ⇒ ~RET `~marginを直列化する$( コレ . `rootMargin$sl ) ◎ rootMargin, of type DOMString, readonly • Offsets applied to the root intersection rectangle, effectively growing or shrinking the box that is used to calculate intersections. These offsets are only applied when handling same-origin-domain targets; for cross-origin-domain targets they are ignored. • On getting, return the result of serializing the elements of [[rootMargin]] space-separated, where pixel lengths serialize as the numeric value followed by "px", and percentages serialize as the numeric value followed by "%".\
注記: 結果が[ コレの構築-時に渡された %options の `rootMargin$mb ]に一致することは、 保証されないことに注意。 %options にて `rootMargin$mb を省略した場合の結果は、 `0px 0px 0px 0px^l になる。 ◎ • Note that this is not guaranteed to be identical to the options.rootMargin passed to the IntersectionObserver constructor. If no rootMargin was passed to the IntersectionObserver constructor, the value of this attribute is "0px 0px 0px 0px".
`scrollMargin@m 取得子~手続きは ⇒ ~RET `~marginを直列化する$( コレ . `scrollMargin$sl ) ◎ scrollMargin, of type DOMString, readonly • Offsets are applied to scrollports on the path from intersection root to target, effectively growing or shrinking the clip rects used to calculate intersections. • On getting, return the result of serializing the elements of [[scrollMargin]] space-separated, where pixel lengths serialize as the numeric value followed by "px", and percentages serialize as the numeric value followed by "%".\
注記: 結果が[ コレの構築-時に渡された %options の `scrollMargin$mb ]に一致することは、 保証されないことに注意。 %options にて `scrollMargin$mb を省略した場合の結果は、 `0px 0px 0px 0px^l になる。 ◎ • Note that this is not guaranteed to be identical to the options.scrollMargin passed to the IntersectionObserver constructor. If no scrollMargin was passed to the IntersectionObserver constructor, the value of this attribute is "0px 0px 0px 0px".
所与の`要素$ %要素 が `内容~clip@ を有するとは、 次を満たすことをいう ⇒ %要素 の `overflow-*@~CSSOVERFLOW3#overflow-properties$p ~propに算出される~styleは、 %要素 の内容を %要素 の`~padding辺$で~clipする ◎ An Element is defined as having a content clip if its computed style has overflow properties that cause its content to be clipped to the element’s padding edge.
`IntersectionObserver$I ~obj %O の `~root交差~矩形@ は、 各`~target$が交差しているかどうか検査するときに利用する矩形であり, 次を遂行した結果になる: ◎ The root intersection rectangle for an IntersectionObserver is the rectangle we’ll use to check against the targets.
- %~root ~LET [ %O は`暗黙的な~root観測器$であるならば `~top-level閲覧~文脈$に属する文書/ ~ELSE_ %O の`交差~root$ ] ◎ If the IntersectionObserver is an implicit root observer, • it’s treated as if the root were the top-level browsing context’s document, according to the following rule for document.
-
%~root矩形 ~LET %~root に応じて,次で与えられる矩形: ◎ ↓
- `文書$である場合 ⇒ `文書$の`表示域$の~size (この段に達するのは、 文書が`全部的に作動中$であるときに限られることに注意。) ◎ If the intersection root is a document, • it’s the size of the document's viewport (note that this processing step can only be reached if the document is fully active).
- 他の場合, %~root は`内容~clip$を有するならば ⇒ %~root の`~padding区画$ ◎ Otherwise, if the intersection root has a content clip, • it’s the element’s padding area.
- 他の場合 ⇒ `要素~用の限界~boxを取得する$( %~root ) ◎ Otherwise, • it’s the result of getting the bounding box for the intersection root.
-
~IF[ `~target$は`同じ生成元~domainに属する$† ] ⇒ %~root矩形 ~SET `矩形を~marginで拡幅する$( %~root矩形, %O . `rootMargin$sl ) ◎ When calculating the root intersection rectangle for a same-origin-domain target, the rectangle is then expanded according to the offsets in the IntersectionObserver’s [[rootMargin]] slot\ ↓↓ in a manner similar to CSS’s margin property, with the four values indicating the amount the top, right, bottom, and left edges, respectively, are offset by, with positive lengths indicating an outward offset. Percentages are resolved relative to the width of the undilated rectangle.
【† したがって,`~root交差~矩形$は`~target$にも依存することになるが、 この仕様の他所は,そのように記されていない。 】
- ~RET %~root矩形 ◎ ↑
注記: `rootMargin$m が適用されるのは、 `交差~root$ 自身に限られる。 `~target$`要素$が`交差~root$以外の ある先祖の区画~内に~clipされる場合でも、 その~clippingは `rootMargin$m からは影響されない。 ◎ Note: rootMargin only applies to the intersection root itself. If a target Element is clipped by an ancestor other than the intersection root, that clipping is unaffected by rootMargin.
`~scrollportに~scroll~marginを適用する@ ときは、 所与の ( `IntersectionObserver$I ~obj %O, ~scrollportを成す矩形 %矩形, `~target$ %~target ) に対し, 以下に従って,~scrollportの交差~矩形を計算する:
- ~IF[ %~target は`同じ生成元~domainに属する$ ] ⇒ ~RET `矩形を~marginで拡幅する$( %矩形, %O . `scrollMargin$sl )
- ~RET %矩形
これらの~offsetは、 `~target$が`同じ生成元~domainに属する$場合に限り適用され,他の場合は無視される。 ◎ These offsets are only applied when handling same-origin-domain targets; for cross-origin-domain targets they are ignored.
注記: `scrollMargin$m は、 `交差~root$までにあるすべての~scroll可能な先祖による`~target$の~clippingに影響する。 ~scroll可能な`交差~root$の矩形には、[ `scrollMargin$m, `rootMargin$m ]どちらも適用される。 ◎ Note: scrollMargin affects the clipping of target by all scrollable ancestors up to and including the intersection root. Both the scrollMargin and the rootMargin are applied to a scrollable intersection root’s rectangle.
注記: [ `~root交差~矩形$, `~scrollportの交差~矩形$ ]は、 どちらも~pinch-zoom【`視覚-表示域$の`拡縮率$vV】からは影響されず, 単に`表示域$を報告することになる — ~pinch-zoomの主旨は、 ~layoutは変えずに, 拡大鏡の様に動作することにあるので。 ◎ Note: Root intersection rectangle and scrollport intersection rectangles are not affected by pinch zoom and will report the unadjusted viewport, consistent with the intent of pinch zooming (to act like a magnifying glass and NOT change layout.)
`矩形を~marginで拡幅する@ ときは、 所与の ( %矩形, `~margin~list$ %~margin ) に対し, %矩形 の各~辺を %~margin を成す 4 個の~offset値に則って,~CSSの `margin$p ~propに類似な方式で拡幅した結果を返す — すなわち:
- 値は順に,[ 上端, 右端, 下端, 左端 ]辺が~offsetされる量を指示する。 ◎
- 正な長さは外方への~offsetを指示する。
- 百分率は、 ~~元の矩形の横幅【`論理-横幅$】を基準に解決する。
(~root/~scroll) `~marginを構文解析する@ ときは、 所与の ( 文字列 %~margin文字列 ) に対し,次を走らす — これは、[ 4 個の値が成す~list/ `失敗^i ]を返す (前者の~listを成す各~値は、[ ~pixel長さ/百分率 ]になる): ◎ To parse a margin (root or scroll) from an input string marginString, returning either a list of 4 pixel lengths or percentages, or failure:
- %~token~list ~LET %~margin文字列 から`成分~値~listを構文解析する$ ◎ Parse a list of component values marginString, storing the result as tokens.
- %~token~list からすべての`空白~token$を除去する ◎ Remove all whitespace tokens from tokens.
- ~IF[ %~token~list の長さ ~GT 4 ] ⇒ ~RET `失敗^i ◎ If the length of tokens is greater than 4, return failure.
- ~IF[ %~token~list の長さ ~EQ 0 ] ⇒ %~token~list に `0px^l を付加する ◎ If there are zero elements in tokens, set tokens to ["0px"].
- %結果 ~LET 空~list ◎ ↓
-
%~token~list を成す ~EACH( %token ) に対し: ◎ Replace each token in tokens:
- ~IF[ %token は`絶対~長さ$による `dimension$t ~tokenである ] ⇒ %結果 に %token に等価な~pixel長さを付加する ◎ If token is an absolute length dimension token, replace it with a an equivalent pixel length.
- ~ELIF[ %token は `percentage$t ~tokenである ] ⇒ %結果 に %token に等価な百分率を付加する ◎ If token is a <percentage> token, replace it with an equivalent percentage.
- ~ELSE ⇒ ~RET `失敗^i ◎ Otherwise, return failure.
- ~WHILE[ %結果 の長さ ~LT 3 ] ⇒ %結果 に[ %結果 を成す 1 個目の値の~~複製 ]付加する ◎ ↓
- ~IF[ %結果 の長さ ~EQ 3 ] ⇒ %結果 に[ %結果 を成す 2 個目の値の~~複製 ]を付加する ◎ If there is one element in tokens, append three duplicates of that element to tokens. Otherwise, if there are two elements are tokens, append a duplicate of each element to tokens. Otherwise, if there are three elements in tokens, append a duplicate of the second element to tokens.
- ~RET %結果 ◎ Return tokens.
2.3. `IntersectionObserverEntry^I ~interface
[`Exposed$=Window] interface `IntersectionObserverEntry@I { `IntersectionObserverEntry@mc(`IntersectionObserverEntryInit$I %intersectionObserverEntryInit); readonly attribute `DOMHighResTimeStamp$ `time$m; readonly attribute `DOMRectReadOnly$I? `rootBounds$m; readonly attribute `DOMRectReadOnly$I `boundingClientRect$m; readonly attribute `DOMRectReadOnly$I `intersectionRect$m; readonly attribute `boolean$ `isIntersecting$m; readonly attribute `boolean$ `isVisible$m; readonly attribute `double$ `intersectionRatio$m; readonly attribute `Element$I `target$m; }; dictionary `IntersectionObserverEntryInit@I { required `DOMHighResTimeStamp$ `time@mb; required `DOMRectInit$I? `rootBounds@mb; required `DOMRectInit$I `boundingClientRect@mb; required `DOMRectInit$I `intersectionRect@mb; required `boolean$ `isIntersecting@mb; required `boolean$ `isVisible@mb; required `double$ `intersectionRatio@mb; required `Element$I `target@mb; };
【 個々の交差~event通知は、 この~interfaceが表現する。 】
`IntersectionObserverEntry$I ~obj %~entry を `生成した観測器@ とは、 %~entry が`交差~観測器に~entryを~queueする$手続きにより構築されたならば, その手続きに渡された `IntersectionObserver$I ~objを指す。 他の場合は未定義とする。
【 この用語は、 以下の記述を明確化するためにこの訳に導入している。 `生成した観測器$が未定義な場合 — 例えば~scriptから `new IntersectionObserverEntry()$m 構築子を呼出して作成されるものなど — の挙動は、 この仕様には述べられていない (が、 単に各~属性が所与の `IntersectionObserverEntryInit$I 引数で初期化されることになろう)。 】【 この節の以下に与えられる各~interface~memberの記述は、 規範的な定義ではない。 それらは、 上述した手続きを含む `§ 処理~model$にて規範的に定義される。 】
- `boundingClientRect@m ◎ boundingClientRect, of type DOMRectReadOnly, readonly
- 次により得される `DOMRectReadOnly$I ~objになる 【 `DOMRect$I ではなく】 ⇒ `要素~用の限界~boxを取得する$( コレの `target$m ) ◎ A DOMRectReadOnly obtained by getting the bounding box for target.
- `intersectionRect@m ◎ intersectionRect, of type DOMRectReadOnly, readonly
-
次に挙げる矩形すべての交差域(共通域)になる:
- コレの `boundingClientRect$m
- 次を満たす各~要素の~clipping矩形 ⇒ [ コレを`生成した観測器$の`交差~root$の子孫である【!*root】 ]~AND[ コレの `target$m の先祖である ]
- コレを`生成した観測器$の`~root交差~矩形$
この値は、 `target$m が[ コレを`生成した観測器$の`~root交差~矩形$ ]と交差する部位を表現する。
◎ boundingClientRect, intersected by each of target's ancestors' clip rects (up to but not including root), intersected with the root intersection rectangle. This value represents the portion of target that intersects with the root intersection rectangle. - `isIntersecting@m ◎ isIntersecting, of type boolean, readonly
- コレの `target$m がコレ . `root$sl に交差しているならば ~T / ~ELSE_ ~F を返す。 ◎ True if the target intersects with the root; false otherwise.\
- この~flagにより、 交差~矩形の面積が 0 であるような交差 (辺が接しているか `boundingClientRect$m の面積が 0 の場合に起こる) においても,交差するように遷移したか, その逆に遷移したかを判別-可能になる。 ◎ This flag makes it possible to distinguish between an IntersectionObserverEntry signalling the transition from intersecting to not-intersecting; and an IntersectionObserverEntry signalling a transition from not-intersecting to intersecting with a zero-area intersection rect (as will happen with edge-adjacent intersections, or when the boundingClientRect has zero area).
- `isVisible@m ◎ isVisible, of type boolean, readonly
- 次の結果に設定される ⇒ `可視性を算出する$( コレの `target$m【, コレ】 ) ◎ Contains the result of running the visibility algorithm on target.
- `intersectionRatio@m ◎ intersectionRatio, of type double, readonly
- コレの `boundingClientRect$m の面積 %面積 ~GT 0 ならば、 ( コレの `intersectionRect$m の面積 ~DIV %面積 ) になる。 他の場合、 コレの `isIntersecting$m に応じて[ ~T ならば 1 / ~F ならば 0 ]になる。 ◎ If the boundingClientRect has non-zero area, this will be the ratio of intersectionRect area to boundingClientRect area. Otherwise, this will be 1 if the isIntersecting is true, and 0 if not.
- `rootBounds@m ◎ rootBounds, of type DOMRectReadOnly, readonly, nullable
- `target$m は`同じ生成元~domainに属する$ならば、 コレを`生成した観測器$の`~root交差~矩形$になる。 ~ELSE_ ~NULL になる。 ◎ For a same-origin-domain target, this will be the root intersection rectangle. Otherwise, this will be null.\
- ~targetが`交差~root$と異なる`閲覧~文脈$内にある場合の結果は、[ `boundingClientRect$m, `intersectionRect$m ]とは異なる座標系に属することに注意。 ◎ Note that if the target is in a different browsing context than the intersection root, this will be in a different coordinate system than boundingClientRect and intersectionRect.
- `target@m ◎ target, of type Element, readonly
- コレを`生成した観測器$の`交差~root$との交差が変化した`要素$を返す。 ◎ The Element whose intersection with the intersection root changed.
- `time@m ◎ time, of type DOMHighResTimeStamp, readonly
- 交差が記録された時刻を,[ コレを`生成した観測器$に結付けられた大域~obj ]の`時刻起点$を基準にして表す `DOMHighResTimeStamp$I 型~値を返すモノトスル。 ◎ The attribute must return a DOMHighResTimeStamp that corresponds to the time the intersection was recorded, relative to the time origin of the global object associated with the IntersectionObserver instance that generated the notification.
2.4. `IntersectionObserverInit^I 辞書
dictionary `IntersectionObserverInit@I { (`Element$I or `Document$I)? `root$mb = null; `DOMString$ `rootMargin$mb = "0px"; `DOMString$ `scrollMargin$mb = "0px"; (`double$ or `sequence$<`double$>) `threshold$mb = 0; `long$ `delay$mb = 0; `boolean$ `trackVisibility$mb = false; };
- `root@mb ◎ root, of type (Element or Document), nullable, defaulting to null
- 利用する`交差~root$を与える。 供されなかった場合( ~NULL )、 `暗黙的な~root$が利用される。 ◎ The root to use for intersection. If not provided, use the implicit root.
- `rootMargin@mb ◎ rootMargin, of type DOMString, defaulting to "0px"
- `交差~root$に適用する~marginを[ ~CSS `margin$p ~propと類似に, 1 〜 4 個の[ `絶対~長さ$/百分率 ]成分からなる文字列 ]として与える。 ◎ Similar to the CSS margin property, this is a string of 1-4 components, each either an absolute length or a percentage.
-
値の例と適用される~margin 値 上端 右端 下端 左端 `5px^l `5px^v `5px^v `5px^v `5px^v `5px 10px^l `5px^v `10px^v `5px^v `10px^v `-10px 5px 8px^l `-10px^v `5px^v `8px^v `5px^v `-10px -5px 5px 8px^l `-10px^v `-5px^v `5px^v `8px^v "5px" // all margins set to 5px "5px 10px" // top & bottom = 5px, right & left = 10px "-10px 5px 8px" // top = -10px, right & left = 5px, bottom = 8px "-10px -5px 5px 8px" // top = -10px, right = -5px, bottom = 5px, left = 8px
- `scrollMargin@mb ◎ scrollMargin, of type DOMString, defaulting to "0px"
- `rootMargin$mb と類似に,`~scrollportの交差~矩形$に適用する~marginを[ 1 〜 4 個の[ `絶対~長さ$/百分率 ]成分からなる文字列 ]として与える。 ◎ Similar to rootMargin, this is a string of 1-4 components, each either an absolute length or a percentage.
- その例は、 上の `rootMargin$mb を見よ。 ◎ See rootMargin above for the example.
- `threshold@mb ◎ threshold, of type (double or sequence<double>), defaulting to 0
- ~callbackを誘発するための,~thresholdたちが成す~listを与える。 ~callbackは、 `intersectionRect$m の面積【の`~root交差~矩形$の面積に対する比率】が[ いずれかの~threshold以上から それ未満に変化した / その逆に変化した ]とき,呼出されるようになる。 ◎ List of threshold(s) at which to trigger callback. callback will be invoked when intersectionRect’s area changes from greater than or equal to any threshold to less than that threshold, and vice versa.
- どの~thresholdも 0.0 以上 1.0 以下でなければナラナイ 【さもなければ、例外が投出される】 。 それらは、 次の結果を成す矩形~区画の可視率を表現する ⇒ `要素~用の限界~boxを取得する$( `~target$ ) ◎ Threshold values must be in the range of [0, 1.0] and represent a percentage of the area of the rectangle produced by getting the bounding box for target.
- 注記: 値 0.0 は、 実質的に, “非~zero個の~pixel” を表す。 【すなわち、少しでも交差しているかどうか。】 ◎ Note: 0.0 is effectively "any non-zero number of pixels".
- `delay@mb ◎ delay, of type long, defaulting to 0
- この観測器からの所与の~target用の[ 各~通知から次回の通知まで ]は、 ~milli秒数で この値~以上は遅延するよう指示する。 ◎ A number specifying the minimum delay in milliseconds between notifications from the observer for a given target.
- `trackVisibility@mb ◎ trackVisibility, of type boolean, defaulting to false
- この観測器は`可視性$を追跡するべきかどうかを指示する真偽値。 ◎ A boolean indicating whether the observer should track visibility.\
- `可視性$の追跡は、 交差の追跡よりも高価な演算になる見込みが高いことに注意。 この~optionは、 必要yなときに限り利用することが推奨される。 ◎ Note that tracking visibility is likely to be a more expensive operation than tracking intersections. It is recommended that this option be used only when necessary.
3. 処理~model
この節では、 ~UAが`交差~観測器$ ~APIを実装するときに従うモノトスル手続きを要旨する。 ◎ This section outlines the steps the user agent must take when implementing the Intersection Observer API.
3.1. 内部~slotの定義
3.1.1. 文書
各 `文書$には `交差~観測器~taskは処理待ちか@ ( `IntersectionObserverTaskQueued flag^en ) が結付けられる — それは、 真偽値をとり,初期~時は ~F とする。 ◎ Each document has an IntersectionObserverTaskQueued flag which is initialized to false.
【 この~flagは、 いっときに生じた一連の交差が 1 回の通知に集約されるように処理を制御する。 交差が生じたとき (それは、 `~event~loop処理@#event-loop$の中で`交差~観測nを更新する$ことにより検出される)、 最終的に 【!交差~観測器に~entryを~queueする$ → 交差~観測器~taskを~queueする$】 `交差~観測器たちに通知する$~taskが~queueされる。 その~task (それは、 観測器の構築子に渡された %callback を呼出して~scriptに交差を通知する) が実際に走り始めるまで、 この~flagは ~T にされる。 その間に検出された新たな交差の通知は、 新たな~taskを~queueすることなく留め置かれ,先送りされることになる。 言い換えれば、 この~flagは,ある程度の最適化の裁量を~UAに与えるためにあるように見受けられる。 】
3.1.2. 要素
各 `要素$は、 `RegisteredIntersectionObservers@sl 内部~slotを有する — それは、[ `交差~観測器~登録@ と呼ばれる~record ]たちを保持する~listであり, 初期~時は空になるモノトスル。 各~recordは、 次に挙げるものを有する: ◎ Element objects have an internal [[RegisteredIntersectionObservers]] slot, which is initialized to an empty list. This list holds IntersectionObserverRegistration records, which have:
- `観測器@rp ⇒ 【当の要素を観測している】 `IntersectionObserver$I を保持する。 ◎ an observer property holding an IntersectionObserver.
-
`前回の~threshold~index@rp ⇒ 範囲 { −1 〜 `観測器$rp . `thresholds$sl の長さ } に入る整数を保持する。
【 −1 は初期~値。 0 以上の値は、 一部の特殊な事例を除き,要素の直近の交差~比率が 一連の~thresholdで区切られる何番目の区間に入っているかを指示する。 0 は 最小~threshold未満, 最大~値は 最大~threshold以上の区間に対応する。 】
◎ a previousThresholdIndex property holding a number between -1 and the length of the observer’s thresholds property (inclusive). -
`前回に交差したか@rp ⇒ 真偽値を保持する。
【 要素が交差しているかどうかを指示する。 その変化を追跡するためにあり、 変化-時には通知が生成される。 】
◎ a previousIsIntersecting property holding a boolean. - `最後の更新~時刻@rp ⇒ `DOMHighResTimeStamp$I 値を保持する。 ◎ a lastUpdateTime property holding a DOMHighResTimeStamp value.
- `前回は可視か@rp ⇒ 真偽値を保持する。 ◎ a previousIsVisible property holding a boolean.
3.1.3. `IntersectionObserver^I
各 `IntersectionObserver$I ~obj %O は、 次に挙げる内部~slotを有する: ◎ IntersectionObserver objects have the following internal slots:
- `QueuedEntries@sl ◎ A [[QueuedEntries]] slot\
- ~list — 初期~時は空とする。 ◎ initialized to an empty list.
- 【 %O が観測している各`~target$における交差の変化を表現する通知たちを,内部的に保持する。 】
- `ObservationTargets@sl ◎ A [[ObservationTargets]] slot\
- ~list — 初期~時は空とする。 ◎ initialized to an empty list.
- 【 %O が観測している`~target$たちを,内部的に保持する。 順序は、 ~targetを引数に %O の `observe()$m が~callされた順になる。 】
- `callback@sl ◎ A [[callback]] slot\
- %O の構築-時に — すなわち, `new IntersectionObserver()$m 構築子~手続きにて(以下同様)— 初期化され, 渡された %callback を内部的に保持する。 ◎ which is initialized by IntersectionObserver(callback, options).
- `root@sl
- 【 この内部~slotは、 他所を集約するための,この訳による追加。 】
- %O の構築-時に初期化され,渡された %options[ "`root$mb" ] を内部的に保持する (供されなかった場合は ~NULL になる)。
- これは、 %O 用の`交差~root$として利用される。
- `rootMargin@sl ◎ A [[rootMargin]] slot\
- `~margin~list$ — %O の構築-時に初期化され, 渡された %options[ "`rootMargin$mb" ] を(構文解析した結果を)内部的に保持する。 ◎ which is a list of four pixel lengths or percentages.
- この~listを成す各~offsetは、 `~root交差~矩形$に適用され, 交差域を計算するときに利用される~boxを実質的に[ 拡げる/狭める ]ために利用される。 ◎ ↑↑
- これは、 `~target$が`同じ生成元~domainに属する$場合に限り適用され,他の場合は無視される。 ◎ ↑↑
- `scrollMargin@sl ◎ A [[scrollMargin]] slot\
- `~margin~list$ — %O の構築-時に初期化され, 渡された %options[ "`scrollMargin$mb" ] を(構文解析した結果を)内部的に保持する。 ◎ which is a list of four pixel lengths or percentages.
- この~listを成す各~offsetは、 `交差~root$から`~target$までの経路~上にある`~scrollport$たちに適用され, 交差域を計算するときに利用される~clip矩形を実質的に[ 拡げる/狭める ]ために利用される。 ◎ ↑↑
- `thresholds@sl ◎ A [[thresholds]] slot\
- 0 以上 1 以下の実数たちが成す~list — %O の構築-時に初期化され,渡された %options[ "`threshold$mb" ] を成す~thresholdたちを昇順で~sortした結果の~listを内部的に保持する (供されなかった場合/空な連列が供された場合、 1 個の 0 のみからなる~listになる)。 ◎ which is initialized by IntersectionObserver(callback, options).
- 各~thresholdは、 %O が観測している各~targetの限界~box区画の交差~比率と比較され、 ある~targetのそれが いずれかの~thresholdを横切ったとき,対する通知が生成される。 ◎ ↑↑
- `delay@sl ◎ A [[delay]] slot\
- 整数 — %O の構築-時に初期化され, 渡された %options[ "`delay$mb" ] を内部的に保持する — `trackVisibility$sl ~EQ ~T の場合、 100 以上に切り上げられる。 ◎ which is initialized by IntersectionObserver(callback, options).
- これは、 次を~milli秒数で指示する ⇒ %O からの所与の~target用の[ 各~通知から次回の通知まで ]の最小な遅延 ◎ ↑↑
- `trackVisibility@sl ◎ A [[trackVisibility]] slot\
- 真偽値 — %O の構築-時に初期化され, 渡された %options[ "`trackVisibility$mb" ] を内部的に保持する。 ◎ which is initialized by IntersectionObserver(callback, options).
- これは、 %O が[ ~targetの`可視性@#visibility$における変化を追跡する ]ことになるか否かを指示する。 ◎ ↑↑
`~margin~list@ は、 4 個の[ ~pixel長さ/百分率 ]が成す~listとする。
`~marginを直列化する@ ときは、 所与の ( `~margin~list$ %~list ) に対し:
- %結果 ~LET 空~文字列
-
~EACH( %~index ~IN { 0 〜 3 } ) に対し,昇順に:
- %成分 ~LET %~list[ %~index ]
-
%結果 に %成分 の数量-値を付加する
【 その数を表現する 10 進記数法による文字列であろうが、 詳細は指定されていない。 (`~CSS成分~値を直列化する$手続きに従う?) 】
- %結果 に %成分 の型に応じて[ ~pixel長さならば `px^l / 百分率ならば `%^l ]を付加する
- ~IF[ %~index ~NEQ 3 ] ⇒ %結果 に 1 個の~spaceを付加する
- ~RET %結果
【 [ `~margin~list$, `~marginを直列化する$ ]は、 他所の記述を集約するための,この訳による追加。 】
3.2. 各種~algo
3.2.1. 新たな交差~観測器を初期化する
`新たな交差~観測器を初期化する@ ときは、 所与の ( `IntersectionObserver$I %観測器, `IntersectionObserverCallback$I %~callback, `IntersectionObserverInit$I 辞書 %~option群 ) に対し,次の手続きを走らす: ◎ To initialize a new IntersectionObserver, given an IntersectionObserverCallback callback and an IntersectionObserverInit dictionary options, run these steps:
- %観測器 . `callback$sl ~SET %callback ◎ Let this be a new IntersectionObserver object ◎ Set this’s internal [[callback]] slot to callback.
- %~root~margin ~LET `~marginを構文解析する$( %~option群[ "`rootMargin$mb" ] ) ◎ Attempt to parse a margin from options.rootMargin.\
- ~IF[ %~root~margin ~EQ `失敗^i ] ⇒ ~THROW `SyntaxError$E ◎ ↓
- %観測器 . `rootMargin$sl ~SET %~root~margin ◎ If a list is returned, set this’s internal [[rootMargin]] slot to that. Otherwise, throw a SyntaxError exception.
- %~scroll~margin ~LET `~marginを構文解析する$( %~option群[ "`scrollMargin$mb" ] ) ◎ Attempt to parse a margin from options.scrollMargin.\
- ~IF[ %~scroll~margin ~EQ `失敗^i ] ⇒ ~THROW `SyntaxError$E ◎ ↓
- %観測器 . `scrollMargin$sl ~SET %~scroll~margin ◎ If a list is returned, set this’s internal [[scrollMargin]] slot to that.\ Otherwise, throw a SyntaxError exception.
- %~threshold群 ~LET %~option群[ "`threshold$mb" ] ◎ Let thresholds be a list equal to options.threshold.
- ~IF[ %~threshold群 は `double^c 型である (連列~型でない) ] ⇒ %~threshold群 ~SET « %~threshold群 » ◎ ↑
- ~IF[ %~threshold群 を成す ある値は[ 0.0 以上 1.0 以下 ]でない ] ⇒ ~THROW `RangeError$E ◎ If any value in thresholds is less than 0.0 or greater than 1.0, throw a RangeError exception.
- %~threshold群 を昇順に~sortする ◎ Sort thresholds in ascending order.
- ~IF[ %~threshold群 は空である ] ⇒ %~threshold群 に 0 を付加する ◎ If thresholds is empty, append 0 to thresholds.
- %観測器 . `thresholds$sl ~SET %~threshold群 ◎ The thresholds attribute getter will return this sorted thresholds list.
- %遅延 ~LET %~option群[ "`delay$mb" ] ◎ Let delay be the value of options.delay.
- %可視性を追跡するか ~LET %~option群[ "`trackVisibility$mb" ] ◎ ↓
- ~IF[ %可視性を追跡するか ~EQ ~T ]~AND[ %遅延 ~LT 100 ] ⇒ %遅延 ~SET 100 ◎ If options.trackVisibility is true and delay is less than 100, set delay to 100.
- %観測器 . `delay$sl ~SET 【!to options.delay】 %遅延 ◎ Set this’s internal [[delay]] slot to options.delay to delay.
- %観測器 . `trackVisibility$sl ~SET %可視性を追跡するか ◎ Set this’s internal [[trackVisibility]] slot to options.trackVisibility. ◎ Return this.
- %観測器 . `root$sl ~SET %~option群[ "`root$mb" ] ◎ [[root]] を見よ
【 原文の~algoは `IntersectionObserver$I の新たな~instanceを作成して返しているが、 この訳では,~Web~IDLの`構築子~手続き$の規約に則って初期化のみ遂行するよう改める。 】
3.2.2. ~target要素を観測し始める
`~target要素を観測し始める@ ときは、 所与の ( `IntersectionObserver$I %観測器, `要素$ %~target ) に対し,次の手続きに従う: ◎ To observe a target Element, given an IntersectionObserver observer and an Element target, follow these steps:
- ~IF[ %~target ~IN %観測器 . `ObservationTargets$sl ] ⇒ ~RET ◎ If target is in observer’s internal [[ObservationTargets]] slot, return.
- %登録 ~LET 新たな`交差~観測器~登録$ — その ⇒# `観測器$rp ~SET %観測器, `前回の~threshold~index$rp ~SET −1, `前回に交差したか$rp ~SET ~F `前回は可視か$rp ~SET ~F 【`最後の更新~時刻$rpもここで初期化する必要があろう。】 ◎ Let intersectionObserverRegistration be an IntersectionObserverRegistration record with an observer property set to observer, a previousThresholdIndex property set to -1, a previousIsIntersecting property set to false, and a previousIsVisible property set to false.
- %~target . `RegisteredIntersectionObservers$sl に %登録 を付加する ◎ Append intersectionObserverRegistration to target’s internal [[RegisteredIntersectionObservers]] slot.
- %観測器 . `ObservationTargets$sl に %~target を付加する ◎ Add target to observer’s internal [[ObservationTargets]] slot.
3.2.3. ~target要素を観測し終える
`~target要素を観測し終える@ ときは、 所与の ( `IntersectionObserver$I %観測器, `要素$ %~target ) に対し,次の手続きに従う: ◎ To unobserve a target Element, given an IntersectionObserver observer and an Element target, follow these steps:
- %~target . `RegisteredIntersectionObservers$sl から[ `観測器$rp ~EQ %観測器 ]を満たす`交差~観測器~登録$を除去する ◎ Remove the IntersectionObserverRegistration record whose observer property is equal to this from target’s internal [[RegisteredIntersectionObservers]] slot, if present.
- %観測器 . `ObservationTargets$sl から %~target を除去する ◎ Remove target from this’s internal [[ObservationTargets]] slot, if present
3.2.4. 交差~観測器~taskを~queueする
`交差~観測器~task~source@ は、 `交差~観測器たちに通知する$~taskを~scheduleするために利用される`~task~source$である。 ◎ The IntersectionObserver task source is a task source used for scheduling tasks to § 3.2.5 Notify Intersection Observers.
`文書$ %文書 用に `交差~観測器~taskを~queueする@ ときは、 次を走らす: ◎ To queue an intersection observer task for a document document, run these steps:
- ~IF[ %文書 の`交差~観測器~taskは処理待ちか$ ~EQ ~T ] ⇒ ~RET ◎ If document’s IntersectionObserverTaskQueued flag is set to true, return.
- %文書 の`交差~観測器~taskは処理待ちか$ ~SET ~T ◎ Set document’s IntersectionObserverTaskQueued flag to true.
-
`~taskを~queueする$( `交差~観測器~task~source$, 次の手続き, %文書 の`~event~loop$【単に,`暗黙な~event~loop$を指すであろう】, %文書 )
手続きは ⇒ `交差~観測器たちに通知する$( %文書 )◎ Queue a task on the IntersectionObserver task source associated with the document's event loop to notify intersection observers.
3.2.5. 交差~観測器たちに通知する
`交差~観測器たちに通知する@ ときは、 所与の ( `文書$ %文書 ) に対し,次を走らす: ◎ To notify intersection observers for a document document, run these steps:
- %文書 の`交差~観測器~taskは処理待ちか$ ~SET ~F ◎ Set document’s IntersectionObserverTaskQueued flag to false.
- %通知-~list ~LET 次を満たす `IntersectionObserver$I すべてが成す~list ⇒ その `root$sl 【 `交差~root$?】 は %文書 の~DOM~tree内にある ◎ Let notify list be a list of all IntersectionObservers whose root is in the DOM tree of document.
-
%通知-~list を成す ~EACH( %観測器 ) に対し: ◎ For each IntersectionObserver object observer in notify list, run these steps:
- ~IF[ %観測器 . `QueuedEntries$sl は空である ] ⇒ ~CONTINUE ◎ If observer’s internal [[QueuedEntries]] slot is empty, continue.
- %~queue ~LET %観測器 . `QueuedEntries$sl の複製 ◎ Let queue be a copy of observer’s internal [[QueuedEntries]] slot.
- %観測器 . `QueuedEntries$sl を空にする ◎ Clear observer’s internal [[QueuedEntries]] slot.
-
`~callback関数を呼出す$( %観測器 . `callback$sl, « %~queue, %観測器 », %観測器 )
この段で例外が投出された場合は、 その`例外を報告する$ 【この手続き自体は継続する】
◎ Let callback be the value of observer’s internal [[callback]] slot. ◎ Invoke callback with queue as the first argument, observer as the second argument, and observer as the callback this value. If this throws an exception, report the exception.
3.2.6. `IntersectionObserverEntry^I を~queueする
`交差~観測器に~entryを~queueする@ ときは、 所与の ⇒# `IntersectionObserver$I %観測器, `文書$ %文書, `DOMHighResTimeStamp$I %time, `DOMRect$I %rootBounds, `DOMRect$I %boundingClientRect, `DOMRect$I %intersectionRect, `boolean^I %isIntersecting, `要素$ %target ◎終 に対し,次を走らす: ◎ To queue an IntersectionObserverEntry for an IntersectionObserver observer, given a document document; DOMHighResTimeStamp time; DOMRects rootBounds, boundingClientRect, intersectionRect, and isIntersecting flag; and an Element target; run these steps:
- %~entry ~LET 新たな `IntersectionObserverEntry$I — その ⇒# `time$m ~SET %time, `rootBounds$m ~SET %rootBounds, `boundingClientRect$m ~SET %boundingClientRect, `intersectionRect$m ~SET %intersectionRect, `isIntersecting$m ~SET %isIntersecting, `target$m ~SET %target ◎ Construct an IntersectionObserverEntry, passing in time, rootBounds, boundingClientRect, intersectionRect, isIntersecting, and target.
- %観測器 . `QueuedEntries$sl に %~entry を付加する ◎ Append it to observer’s internal [[QueuedEntries]] slot.
- %文書 用に`交差~観測器~taskを~queueする$() ◎ Queue an intersection observer task for document.
3.2.7. ~target要素と~rootとの交差域を算出する
`交差域を算出する@ ときは、 所与の ( `~target$ %~target, `交差~root$ %~root【, `IntersectionObserver$I %観測器 】) に対し,次を走らす: ◎ To compute the intersection between a target target and an intersection root root, run these steps:
- %交差~矩形 ~LET `要素~用の限界~boxを取得する$( %~target ) ◎ Let intersectionRect be the result of getting the bounding box for target.
- %容器 ~LET %~target の`包含塊$ 【を確立している~boxを生成した要素, または包含塊は`表示域$ならば %~target の`~node文書$(下に現れる “包含塊” も同様)】 ◎ Let container be the containing block of target.
-
~WHILE[ %容器 ~NEQ %~root ]: ◎ While container is not root:
- %親~容器 ~LET %容器 が`属する閲覧~文脈$の`容器$bc【!`閲覧~文脈~容器$】 ◎ ↓
- ~IF[ %容器 は`文書$である ]~AND[ %親~容器 ~NEQ ~NULL 【!`入子な閲覧~文脈$】 ] ⇒# %交差~矩形 ~SET %交差~矩形 を %容器 の`表示域$で~clipした結果; %容器 ~SET %親~容器 ◎ If container is the document of a nested browsing context, update intersectionRect by clipping to the viewport of the document, and update container to be the browsing context container of container.
- %交差~矩形 ~SET %交差~矩形 を %容器 の座標~空間に写像した結果 ◎ Map intersectionRect to the coordinate space of container.
-
~IF[ %容器 は`~scroll容器$である ] ⇒ %容器 の~clip矩形 ~SET `~scrollportに~scroll~marginを適用する$( %観測器, %容器 の`~scrollport$を成す矩形, %~target )
【 結果は、 次の段に利用される “~clip” に影響するものと見受けられる。 】【 引数は、 この訳による補完。 】
◎ If container is a scroll container, apply the IntersectionObserver’s [[scrollMargin]] to the container’s clip rect as described in apply scroll margin to a scrollport. - ~IF[ %容器 は`内容~clip$を有する ]~OR[ %容器 は~CSS `clip-path$p ~propにより~clipされている ] ⇒ %交差~矩形 ~SET %交差~矩形 に当の~clipを適用した結果 ◎ If container has a content clip or a css clip-path property, update intersectionRect by applying container’s clip.
- ~IF[ %容器 は ある`文書$ %文書 【!`閲覧~文脈$】の~root要素である ] ⇒ %容器 ~SET %文書 (すなわち %親~容器 の親)【! the 閲覧~文脈の`文書$】 ◎ If container is the root element of a browsing context, update container to be the browsing context’s document;\
- ~ELSE ⇒ %容器 ~SET %容器 の`包含塊$ ◎ otherwise, update container to be the containing block of container.
- %交差~矩形 ~SET %交差~矩形 を %~root の座標~空間に写像した結果 ◎ Map intersectionRect to the coordinate space of root.
- %交差~矩形 ~SET %交差~矩形 と`~root交差~矩形$との交差域 ◎ Update intersectionRect by intersecting it with the root intersection rectangle.
- %交差~矩形 ~SET %交差~矩形 を[ %~target を包含している`文書$の`表示域$の座標~空間 ]に写像した結果 ◎ Map intersectionRect to the coordinate space of the viewport of the document containing target.
- ~RET %交差~矩形 ◎ Return intersectionRect.
3.2.8. ~targetは[遮られていない, 変形されていない, ~filterされていない, 不透明である]をすべて満たすかどうかを算出する
`可視性を算出する@ ときは、 所与の( `~target$ %~target【, `IntersectionObserver$I %観測器 】 ) に対し ⇒ ~RET ~IS[ ~AND↓ ]: ◎ To compute the visibility of a target, run these steps:
- %観測器 . `trackVisibility$sl【!`trackVisibility$m 属性】 ~EQ ~T ◎ If the observer’s trackVisibility attribute is false, return false.
-
次の結果は、 ~2D並進や~~縦横比を保つ~2D拡縮( `proportional 2D upscaling^en )†を表現する ⇒ `実効~変形~行列を算出する$( %~target, %観測器 )
【† 原文を字義どおり解釈するなら、 “~~拡大” のみになるが,~~縮小も含まれよう。 これは、[ ~scrollや~page~zoom ]による変形に限られ, ~CSS `transform$p ~propによる変形は除外することを意図しているのかもしれない (はっきりしない)。 】
◎ If the target has an effective transformation matrix other than a 2D translation or proportional 2D upscaling, return false. - [ %~target, %~target の`包含塊~連鎖$内の要素 ]は、 いずれも次を満たす ⇒ [ 実質的な【すなわち,描画-時における】不透明度 ~EQ 100% ]~AND[ ~filterは適用されていない ] ◎ If the target, or any element in its containing block chain, has an effective opacity other than 100%, return false. ◎ If the target, or any element in its containing block chain, has any filters applied, return false.
-
実装は次を保証できる ⇒ %~target は他の~page内容により完全に遮られている ◎ If the implementation cannot guarantee that the target is completely unoccluded by other page content, return false.
注記: 実装は、 遮られているかどうか決定するときは, ~page内容の`~ink~overflow矩形$を利用するべきある。 [ 理論的には無限な拡がりになる,ボカシ効果 ]用には、 `~ink~overflow矩形$は[ `blur()$v ~filter関数~用に述べられた有限な区画による近似 ]により定義される。 ◎ Note: Implementations should use the ink overflow rectangle of page content when determining whether a target is occluded. For blur effects, which have theoretically infinite extent, the ink overflow rectangle is defined by the finite-area approximation described for the blur filter function. ◎ Return true.
3.2.9. ~targetの実効~変形~行列の計算-法
`実効~変形~行列を算出する@ ときは、 所与の( `~target$ %~target【, `IntersectionObserver$I %観測器 】 ) に対し: ◎ To compute the effective transformation matrix of a target, run these steps:
- %行列 ~LET 4×4 の単位i行列 ◎ Let matrix be the serialization of the identity transform function.
- %容器 ~LET %~target ◎ Let container be the target.
-
~WHILE[ %容器 ~NEQ %観測器 用の`交差~root$ ]: ◎ While container is not the intersection root:
- %行列 に %容器 の`変形~行列$を`左から乗算する@~TRANSFORM#pre-multiply$ 【!~TRANSFORM#post-multiply/~TRANSFORM#post-multiplied】 ◎ Set t to container’s transformation matrix. ◎ Set matrix to t post-multiplied by matrix.
- %親~容器 ~LET %容器 が`属する閲覧~文脈$の`容器$bc【!`閲覧~文脈~容器$】 ◎ ↓
- %容器 ~SET [ 次が満たされるならば %親~容器 / ~ELSE_ %容器 の`包含塊$【を確立している~boxを生成した要素】 ] ⇒ [ %容器 は~root要素である ]~AND[ %親~容器 ~NEQ ~NULL【!`入子な閲覧~文脈$】 ] ◎ If container is the root element of a nested browsing context, update container to be the browsing context container of container. Otherwise, update container to be the containing block of container.
- ~RET %行列 ◎ Return matrix.
3.2.10. 交差~観測nを更新する手続き
`交差~観測nを更新する@ ときは、 所与の ( `文書$ %文書, 時刻印 %時刻 ) に対し,次を走らす: ◎ To run the update intersection observations steps for a Document document given a timestamp time, run these steps:
- %観測器~list ~LET 次を満たす `IntersectionObserver$I ~objすべてが成す~list ⇒ `交差~root$は %文書 の~DOM~tree内にある (`~top-level閲覧~文脈$用には、 これには`暗黙的な~root観測器$も含まれる。) ◎ Let observer list be a list of all IntersectionObservers whose root is in the DOM tree of document. For the top-level browsing context, this includes implicit root observers.
-
%観測器~list を成す ~EACH( %観測器 ) に対し: ◎ For each observer in observer list:
- %~root ~LET %観測器 の`交差~root$ ◎ ↓
- %~root限界域 ~LET %観測器 の`~root交差~矩形$ ◎ Let rootBounds be observer’s root intersection rectangle.
-
%観測器 . `ObservationTargets$sl を成す ~EACH( %~target ) に対し: 【!observe(target) が~callされた順に】 ◎ For each target in observer’s internal [[ObservationTargets]] slot, processed in the same order that observe() was called on each target:
- %登録 ~LET %~target . `RegisteredIntersectionObservers$sl を成す`交差~観測器~登録$のうち[ その`観測器$rp ~EQ %観測器 ]を満たすもの ◎ Let registration be the IntersectionObserverRegistration record in target’s internal [[RegisteredIntersectionObservers]] slot whose observer property is equal to observer.
- ~IF[ %時刻 ~LT %登録 の`最後の更新~時刻$rp ~PLUS %観測器 . `delay$sl【!`delay$m】 ] ⇒ ~CONTINUE ◎ If (time - registration.lastUpdateTime < observer.delay), skip further processing for target.
- %登録 の`最後の更新~時刻$rp ~SET %時刻 ◎ Set registration.lastUpdateTime to time.
- %~threshold~index ~LET 0 ◎ Let: ◎ thresholdIndex be 0.
- %交差しているか ~LET ~F ◎ isIntersecting be false.
- %~target矩形 ~LET 新たな `DOMRectReadOnly$I ~obj ◎ targetRect be a DOMRectReadOnly\
- `矩形を初期化する$( %~target矩形, 0, 0, 0, 0 ) ◎ with x, y, width, and height set to 0.
- %交差~矩形 ~LET 新たな `DOMRectReadOnly$I ~obj ◎ intersectionRect be a DOMRectReadOnly\
- `矩形を初期化する$( %交差~矩形, 0, 0, 0, 0 ) ◎ with x, y, width, and height set to 0.
-
~IF[ %~root は`暗黙的な~root$である(`要素$でない) ]~OR[ ~AND↓ ]…
- %~root は`要素$である
- %~target は %~root と同じ`文書$内にある
- %~target は`包含塊~連鎖$における %~root の子孫である 【すなわち、`~box~tree$において子孫でないものは除外される】
…ならば:
◎ If the intersection root is not the implicit root, and target is not in the same document as the intersection root, skip to step 11. ◎ If the intersection root is an Element, and target is not a descendant of the intersection root in the containing block chain, skip to step 11.- %~target矩形 ~SET 次の結果と同じ矩形を表現する新たな `DOMRectReadOnly$I ~obj ⇒ `要素~用の限界~boxを取得する$( %~target ) ◎ Set targetRect to the DOMRectReadOnly obtained by getting the bounding box for target.
- %交差~矩形 ~SET 次の結果を表現する新たな `DOMRectReadOnly$I ~obj ⇒ `交差域を算出する$( %~target, %~root【, %観測器】 ) ◎ Let intersectionRect be the result of running the compute the intersection algorithm on target and observer’s intersection root. ◎ ↓Let targetArea be targetRect’s area. ◎ ↓Let intersectionArea be intersectionRect’s area.
-
【!step 11】 %交差しているか ~SET ~IS[ %~target矩形 と %~root限界域 は交差する ]
ここでは、 辺どうしが接する場合も含め,互いの区画が重なるならば、 交差域の面積が 0 であっても (例: %~root限界域 や %~target矩形 の面積が 0 ), 交差するとする。
◎ Let isIntersecting be true if targetRect and rootBounds intersect or are edge-adjacent, even if the intersection has zero area (because rootBounds or targetRect have zero area). - ~IF[ %~target矩形 の面積 ~GT 0 ] ⇒ %交差~比率 ~SET ( %交差~矩形 の面積 ~DIV %~target矩形 の面積 ) ◎ If targetArea is non-zero, let intersectionRatio be intersectionArea divided by targetArea.
- ~ELSE ⇒ %交差~比率 ~SET %交差しているか に応じて ⇒# ~T ならば 1 / ~F ならば 0 ◎ Otherwise, let intersectionRatio be 1 if isIntersecting is true, or 0 if isIntersecting is false.
- %~threshold~index ~SET %~threshold群 の長さ ◎ ↓
- ~WHILE[ %~threshold~index ~GTE 1 ]~AND[ %観測器 . `thresholds$sl[ %~threshold~index ~MINUS 1 ] ~GT %交差~比率 ] ⇒ %~threshold~index ~DECBY 1 ◎ Set thresholdIndex to the index of the first entry in observer.thresholds whose value is greater than intersectionRatio, or the length of observer.thresholds if intersectionRatio is greater than or equal to the last entry in observer.thresholds.
- %可視か ~LET `可視性を算出する$( %~target【, %観測器】 ) ◎ Let isVisible be the result of running the visibility algorithm on target.
-
~IF[ ~OR↓ ]…
- %~threshold~index ~NEQ %登録 の`前回の~threshold~index$rp
- %交差しているか ~NEQ %登録 の`前回に交差したか$rp
- %可視か ~NEQ %登録 の`前回は可視か$rp
ならば ⇒ `交差~観測器に~entryを~queueする$( ↓ ) ⇒# %観測器, %文書【!*原文抜け】, %時刻, %~root限界域, %~target矩形, %交差~矩形, %交差しているか, %可視か, %~target
◎ Let previousThresholdIndex be the registration’s previousThresholdIndex property. ◎ Let previousIsIntersecting be the registration’s previousIsIntersecting property. ◎ Let previousIsVisible be the registration’s previousIsVisible property. ◎ If thresholdIndex does not equal previousThresholdIndex, or if isIntersecting does not equal previousIsIntersecting, or if isVisible does not equal previousIsVisible, queue an IntersectionObserverEntry, passing in observer, time, rootBounds, targetRect, intersectionRect, isIntersecting, isVisible, and target. - %登録 の ⇒# `前回の~threshold~index$rp ~SET %~threshold~index, `前回に交差したか$rp ~SET %交差しているか, `前回は可視か$rp ~SET %可視か ◎ Assign thresholdIndex to registration’s previousThresholdIndex property. ◎ Assign isIntersecting to registration’s previousIsIntersecting property. ◎ Assign isVisible to registration’s previousIsVisible property.
3.3. `IntersectionObserver^I の存続期間
`IntersectionObserver$I %O は、 次が満たされる間は,生き残り続ける ⇒ [ %O を参照している~scriptが在る ]~OR[ %O が観測している~targetは在る ] ◎ An IntersectionObserver will remain alive until both of these conditions hold: • There are no scripting references to the observer. • The observer is not observing any targets.
`IntersectionObserver$I %O は、 次のいずれかが生じるまで,`~target$ %target を観測し続ける ⇒# %O に対し `unobserve(target)$m が~callされた/ %O に対し `disconnect()$m が~callされた ◎ An IntersectionObserver will continue observing a target until either\ the observer’s unobserve() method is called with the target as argument;\ or the observer’s disconnect() is called.
3.4. 外部~仕様との統合
3.4.1. ~HTMLの~event~loop処理~model
`交差~観測器$の処理【すなわち,`交差~観測nを更新する$】は、 ~HTMLの`~event~loop処理~model$における “`描画を更新する$” 段の中で行われる。 ◎ An Intersection Observer processing step exists as a substep within the "Update the rendering" step, in the HTML Event Loops Processing Model.
3.4.2. 処理待ち初期~交差~観測器~target
所与の`文書$ %文書 において, ~AND↓ を満たす `IntersectionObserver$I %観測器 は、 `処理待ち初期~交差~観測器~target@ であるとされる: ◎ A document is said to have pending initial IntersectionObserver targets if there is at least one IntersectionObserver meeting these criteria:
- %観測器 の`交差~root$は %文書 内にある (`~top-level閲覧~文脈$用には、 これには`暗黙的な~root観測器$も含まれる。) ◎ The observer’s root is in the document (for the top-level browsing context, this includes implicit root observers).
- %観測器 の `ObservationTargets$sl ~slot内に, `IntersectionObserverEntry$I をまだ~queueしていないものがある ◎ The observer has at least one target in its [[ObservationTargets]] slot for which no IntersectionObserverEntry has yet been queued.
~HTMLの`~event~loop処理~model$における`描画を更新する$ 段の中の “`不必要な描画^i” 段は、 描画~更新を飛ばすためとして, 次の要件を追加する【次を満たす %文書 も除去する】よう改変されるべきである ⇒ %文書 には`処理待ち初期~交差~観測器~target$は無い ◎ In the HTML Event Loops Processing Model, under the "Update the rendering" step, the "Unnecessary rendering" step should be modified to add an additional requirement for skipping the rendering update: • The document does not have pending initial IntersectionObserver targets.
4. ~accessibilityの考慮点
◎非規範的`IntersectionObserver$I の中核~仕様(この文書)には、 既知な~accessibilityの考慮点は無い。 しかしながら,この仕様を活用して参照rしている仕様や提案には、 自前の~accessibility考慮点があるかもしれない。 特に,次に挙げる仕様は: ◎ There are no known accessibility considerations for the core IntersectionObserver specification (this document). There are, however, related specifications and proposals that leverage and refer to this spec, which might have their own accessibility considerations. In particular, specifications for\
- `HTML^cite `§ ~lazy読込ng属性@~HTMLurl#lazy-loading-attributes$ ◎ HTML § 2.5.7 Lazy loading attributes and\
- `CSS Containment^cite § `content-visibility@~CSSCONTAIN#content-visibility$p ~prop ◎ CSS Containment 2 § 4 Suppressing An Element’s Contents Entirely: the content-visibility property\
次に挙げるものに対する~accessibilityの含意があり得る: ◎ may have implications for\
- `HTML^cite `§ ~find-in-page@~HTMLinteraction#find-in-page$ ◎ HTML § 6.9 Find-in-page,\
- `HTML^cite § `tabindex@~HTMLinteraction#the-tabindex-attribute$a 属性 ◎ HTML § 6.6.3 The tabindex attribute,\
- `空間的~navi@~CSSNAV$ 【!https://githumb.com/WICG/spatial-navigation】 ◎ and spatial navigation.
5. ~privacyと~security
◎非規範的この~APIに対する主な~privacyの懸念は、 非同一-生成元に属する~iframeの文脈で走っている~codeに供し得る情報に関係する (すなわち、 ~targetが`同じ生成元~domainに属さない$事例)。 特に: ◎ The main privacy concerns associated with this API relate to the information it may provide to code running in the context of a cross-origin iframe (i.e., the cross-origin-domain target case). In particular:
- [ ある~iframeが大域的な表示域の中にあるかどうか ]が露呈されることによる~privacy含意に関しては、 普遍的な総意は無い。 ◎ There is no universal consensus on the privacy implications of revealing whether an iframe is within the global viewport.
- この~APIは、 大域的な表示域~自体の幾何についての情報を探査するために利用され得る~riskがある。 それは、 利用者の~hardware環境設定を演繹するために利用され得る。 [ `rootMargin$m, `scrollMargin$m の効果を不能化する / ~targetが`同じ生成元~domainに属さない$ときは `rootBounds$m を抑止する ]ことの動機は、 そのような探査を防止することにある。 ◎ There is a risk that the API may be used to probe for information about the geometry of the global viewport itself, which may be used to deduce the user’s hardware configuration. The motivation for disabling the effects of rootMargin and scrollMargin, and suppressing rootBounds for cross-origin-domain targets is to prevent such probing.
`IntersectionObserver$I に先立って、[ ~web開発者たちは、 それが可用にする情報を何とか引き出すために,他の~APIを巧妙な(かつ異様な)仕方で利用していた ]ことも挙げておくべきであろう。 純粋に実施~上の問題mとしては、 この~APIが露呈する情報は,他の手段でも可用であったものしかない。 ◎ It should be noted that prior to IntersectionObserver, web developers used other API’s in very ingenious (and grotesque) ways to tease out the information available from IntersectionObserver. As a purely practical matter, this API does not reveal any information that was not already available by other means.
別の考慮として, `IntersectionObserver$I は `DOMHighResTimeStamp$I を利用することが挙げられ、 それには自前の[ ~privacy/~security ]の考慮点がある。 しかしながら, `IntersectionObserver$I が計時に関係する悪用に対し脆弱になると見込まれてはいない。 時刻印が生成されるのは,描画~更新ごとに 1 回までであり ( `§ ~HTMLの~event~loop処理~model@#event-loop$ を見よ)、 その頻度は,同類の計時~攻撃~用には全然足らないので。 ◎ Another consideration is that IntersectionObserver uses DOMHighResTimeStamp, which has privacy and security considerations of its own. It is however unlikely that IntersectionObserver is vulnerable to timing-related exploits. Timestamps are generated at most once per rendering update (see § 3.4.1 HTML Processing Model: Event Loop), which is far too infrequent for the familiar kind of timing attack.
6. 国際-化
◎非規範的国際-化の懸念になる課題は無い。 ◎ There are no known issues concerning internationalization.
謝辞
この仕様に技術的な~~意見や示唆を寄せられ, `貢献されたすべて方々@https://github.com/w3c/IntersectionObserver/graphs/contributors$ に。 ◎ Special thanks to all the contributors for their technical input and suggestions that led to improvements to this specification.