-
Notifications
You must be signed in to change notification settings - Fork 38
Intersection Meta #664
Intersection Meta #664
Conversation
This reverts commit 51e2cf4327c281ad93395bb2438512c87769a6c6.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also needs updating to the latest Evented
meta implementation and then can give another review.
options: IntersectionGetOptions; | ||
root: string; | ||
rootMargin: string | undefined; | ||
thresholds: number[]; // thresholds the observe should be attached with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can you add this as jsdoc and not an inline comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I didn't because it's a private interface.
export interface IntersectionGetOptions { | ||
root?: string; | ||
rootMargin?: string; | ||
threshold?: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need threshold
and thresholds
? If we need a convenience of passing a single threshold, can we not just type it number | number[]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My preference would be to go with thresholds and make it always number[]
private _details: IntersectionDetail[] = []; | ||
|
||
private _getDetails(options: IntersectionGetOptions): IntersectionDetail { | ||
let { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these all lets
? Does root
need a default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If thresholds is always an array, the let
doesn't matter and I can allow root
to be undefined
in the details object.
const { | ||
_details: details | ||
} = this; | ||
if (typeof threshold === 'number' && !thresholds.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We wouldn't need this thresholds
, is typed as number | number[]
.
Could just do:
thresholds = Array.isArray(thresholds) ? thresholds : [ thresholds ];
root === detail.root && | ||
rootMargin === detail.rootMargin && | ||
thresholds.length === detail.thresholds.length && | ||
thresholds.every(function(i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I reading this wrong? is this using the threshold as an index?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this seems wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have added a test for this to ensure the same set of options doesn't create additional observers.
// Look to see if a detail record has already been created for these options | ||
let cached: IntersectionDetail | undefined = undefined; | ||
for (const detail of details) { | ||
if ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can simplify this if condition some what....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of formatting or?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic is pretty complicated, i'd either break these logical conditions up so each one is done individually, like:
if (options !== detail.options) {
continue;
}
Or perhaps even better, use a different mechanism for the options caching (like a map, using the serialised options as the key)? It would look something like this:
private _details: Map<string, IntersectionDetail> = new Map();
private _getDetails(options: IntersectionGetOptions): IntersectionDetail {
const cacheKey = JSON.stringify(options);
let cached = this._details.get(cacheKey);
if (!cached) {
const entries = new WeakMap<Element, IntersectionObserverEntry>();
cached = { ...options, entries };
this._details.set(cacheKey, cached);
}
return cached;
}
details.intersectionObserver = observer; | ||
this.own({ | ||
destroy() { | ||
observer.disconnect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shows as uncovered in the test coverage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm not sure why it's not getting called.
const { | ||
intersectionRatio, | ||
isIntersecting | ||
} = <(IntersectionObserverEntry & { isIntersecting: boolean })> entry; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have to cast like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Until TypeScript is updated to include this property.
intersectionObserver?: IntersectionObserver; // attached observer | ||
options: IntersectionGetOptions; | ||
root: string; | ||
rootMargin: string | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rootMargin?: string;
over rootMargin: string | undefined
?
Closed in lieu of Ant's PR |
Type: feature
The following has been addressed in the PR:
Description:
Allows for observing intersections with a root node, root margin, and intersection thresholds (passed as a second argument to
get
andhas
). Returns an object withisIntersecting
andintersectionRatio
.Contains code to optionally change which intersection cause an invalidation (Within, Outside, Never, and Custom) by calling
invalidateIf
.Resolves #644