Code Monkey home page Code Monkey logo

intersectionobserver's Introduction

intersectionobserver's People

Contributors

autokagami avatar dvoytenko avatar emilio avatar esprehn avatar foolip avatar johanna-hub avatar marcoscaceres avatar martinthomson avatar mike-seiler avatar miketaylr avatar mpb avatar nolanlawson avatar ojanvafai avatar ornhoj avatar philipwalton avatar plehegar avatar pottedmeat avatar rbyers avatar robinwhittleton avatar robwalch avatar samouri avatar shvaikalesh avatar siusin avatar slightlyoff avatar surma avatar szager-chromium avatar tabatkins avatar tcaptan-cr avatar triblondon avatar yoavweiss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

intersectionobserver's Issues

viewportModifier should be distance and need a boolean for predictive callbacks

Mozilla, Apple and Microsoft all felt that viewportModifier should only be a distance field. dbaron suggested that there should be an extra boolean that controls whether to fire the callback when the browser expects the element to intersect the modified viewport (e.g. due to scrolling) and all the vendors seemed OK with that.

MS Feedback: Please don't expose the paint-rect (viewportPaintRect)

Please don't expose the paint-rect (viewportPaintRect)

See also Issue #1

We are hoping for a much more robust definition and specification of the browser's viewport model (e.g., with regard to zooming) before exposing this data to web developers--it seems a bit premature to reveal it through this feature.

As far as implementation, we do have a PVR (paint-ahead bounding rect around the visible viewport) that we would not want to make observable or standardize because we view it as an implementation detail--we don't think those kinds of internal details should be the basis for signaling visibility because they would be difficult to get interoperable behavior.

Use of undefined variable "Document" throughout

All the processing model algorithms make reference to Document. But this is not defined. I assume it's meant to be a Document of some sort. But which one? From which window? This can be especially bad when e.g. code in one frame uses the IntersectionObserver constructor from another frame to observe an Element from a third frame.

MS Feedback: Define the callback rate (min/max?)

Define the callback rate (min/max?)

Rate of callback and time of callback should be more defined (or course). At least a rate limit would be nice (no more than 1 callback per 500 ms or some-such).

MS Feedback: Delay loading scenario applicability questioned

Delay loading scenario applicability questioned

We're both critical of this scenario and supportive of it. We've definitely seen lazy image loaders be a scenario that authors could consider solving with PositionObserver (versus their current approach of spamming scroll events). In our rough brainstorm, we came up with a much more direct solution to solving this problem that doesn't need all the PositionObserver machinery as only a simple notice is needed just before the node would come into view. See Alternative Ideas in #4 applied to <img> elements.

Use of dot notation is a bit confusing

E.g. talking about "Document.pendingCallbacks". I appreciate the efforts at precision to talk precisely about what internal slots each object has. In new specs that define their own objects I suggest notation like "Document@[[pendingCallbacks]]" and explicit discussion of internal slots.

For this case though, since you are extending objects defined in other specs which don't use those concepts, the use of dot notation is confusing. It is easy to think you are talking about normal JavaScript property access.

I'd suggest just going with ye olde "Document's pendingCallbacks".

The properties installed on other objects are named too generically

Since the internal properties of an object are shared across all specs, you need to be careful not to take up names that are too generic. For example, Document's "pendingCallbacks" or Element's "registeredObservers" are squatting on pretty valuable territory. Documents will probably have a variety of pending callbacks, and nodes already have a list of registered observers---I hope we aren't supposed to distinguish between "Element's registeredObservers" and "Element's registered observers."

Why the slight differences from MutationObserver?

There are a number of slight differences in design from MutationObserver:

  • IntersectionObserverInit is in the constructor, whereas for MutationObserver it is in the observe method.
  • IntersectionObserver has an unobserve() method; MutationObserver does not.

These changes are probably well-motivated, but since I'm not too familiar with the design space, I find the mismatch surprising. If they are intentional, it would be nice to add a non-normative note explaining them. It might be the case that MutationObserver has flaws and this is a slightly better iteration.

MS Feedback: Avoiding layout goal seems problematic

Avoiding layout goal seems problematic

We can't think of a good design that eliminates the need to perform layout for these scenarios; using our (off thread) display tree state may be out of date and not necessarily backed by a related DOM element. Perhaps there's something we're missing?

The design goals seem conflicting: don't necessarily run layout, yet be able to report thresholdCallbacks:false and get quads with specific pixel-perfect dimensions. We feel like this should land firmly on the side of accurate reporting if we will go through the trouble of notifying at the specific times.

Some assorted V2 features

Specifically, the definitelyVisibleRect for doing occlusion detection.

Maybe include time to viewport modifier?

MS Feedback: viewportModifier calc magic too tricky

viewportModifier calc magic too tricky

Attempting to evaluate velocity and projected visibility of the target in terms of time seems exceptionally error-prone, hard to get interop, hard to test, etc. There is a clear desire to want an extended viewport dimension, and it seems much easer to go with something simple here (an extended border dimension, in pixels, for example would do fine--if you need more lead time, make the border bigger).

MS Feedback: Usage for Ad Impression Usage Scenario (what is importance for into/out-of view)?

Usage for Ad Impression Usage Scenario (what is importance for into/out-of view)?

Occlusion seems pretty important (for ad impression accuracy). We think that occlusion should somehow be addressed in the solution.

Are the percent-in-view requirements really important? E.g., is this a deal-breaker for ad-impression tracking?

How do the quads relate to the trip-wire for what is considered in threshold? Is it the bounding box? Does this meet the accuracy requirements?

We assume various applied element transformations should be covered, as they are frequently used in advertising attention-grabbing strategies:

  • CSS animations (in flight) (often used in the image carosel scenario)
  • CSS transforms (incl. preserve-3d, rotations with no backface-visibility, etc.)
  • SVG elements (polylines--these are to be bounding boxes?)
  • elements whose DOM manipulation suddenly puts them in view (w/no scrolling)

It's not clear what the use-case is for thresholdCallbacks: false

I think we should remove the concept until we find a use-case for it. With it being async, I don't see any benefit to it.

We just need to make sure that if the element jumps from fully outside the viewport to fully inside or vice versa that you still get a callback.

The spammy thresholdCallbacks: false is just a performance foot-gun without a use-case.

@esprehn @slightlyoff sound ok?

MS Feedback: Data scrollers (List view) scenario likely not in scope

Data scrollers (List view) scenario likely not in scope

The list view scenario is not fully covered. In Microsoft's first version of the WinJS virtualized list view, we had an implementation similar to the one that this proposal tries to help facilitate. However, our experience with the v1 showed that frequent element cycling/thrashing led to terrible perf (in all UAs). Now in our v2+ we preload a larger subset of elements to avoid too frequence cycling, and this works better for avoiding the flashes of white and DOM thrashing as well.

There's a lot of code in our virtual list view for maintaining the virtual content length (for accurate scrollbar calculation). This is tightly coupled with addition/removal of virtual contents and is not really addressed by the proposal.

In the virtual list view case, there's usually not one specific element target which is the basis for determining when and how to hydrate/de-hydrate elements. To that end, the PositionObserver does not provide a direct solution here (though it might be useful indirectly by way of extending an element target's rectangle).

In general, we don't think the virtual list view scenario is/should be a target scenario for the feature. Its implementation is rather complicated and not likely fully addressed by PositionObserver.

Explainer is out of date

Edit: Overall, the Explainer is out of date. Needs to be updated to the current spec. Below describes just one difference, not comprehensive.


The interfaces don't have the same methods. The spec has DOMString threshold = "1px", the explainer has boolean thresholdCallbacks = true.

https://github.com/slightlyoff/IntersectionObserver/blob/master/index.bs#L235

dictionary IntersectionObserverInit {
  ..[snip]..
  DOMString threshold = "1px";
};

https://github.com/slightlyoff/IntersectionObserver/blame/master/explainer.md#L54

(Sorry for linking to the blame, I couldn't figure out how to link directly to a line in the markdown)

dictionary IntersectionObserverInit {
  ..[snip]..
  // Whether to give callbacks only when an element starts/stops intersecting
  // the root bounds or everytime it changes how much it intersects.
  // Callback only fires if the element isn’t intersecting an edge of the
  // viewport in the case that the element jumps from being entirely outside
  // the viewport to entirely inside it.
  // Defaults to true, a less power-hungry option.
  boolean thresholdCallbacks = true;
};

What should happen if the viewport-defining element is an inline?

Related to issue #10, what should happen if the viewport-defining element is an inline?

I see a couple options I'd be happy with:

  1. Use the bounding box of the inline ancestor.
  2. Stop delivering callbacks and queueing change records.

This is not a use-case we need to support, so whatever is simplest.

IntersectionObserver's second argument must be optional

It is currently

Constructor(IntersectionObserverCallback callback, IntersectionObserverInit options)

It must instead be

Constructor(IntersectionObserverCallback callback, optional IntersectionObserverInit options)

Per Web IDL:

If the type of an argument is a dictionary type or a union type that has a dictionary type as one of its flattened member types, and that dictionary type and its ancestors have no required members, and the argument is either the final argument or is followed only by optional arguments, then the argument MUST be specified as optional

Data Scrollers example should not observe each scrolled item

There's no need for an O(n) observation here. You just need a placeholder item above and a placeholder item below. So, you only need to observe two elements.

Also, this example needs to more clearly show that the items are recycled to make it clear that there can never be that many items in the scroller.

Both of these have been confusing to just about everyone who has read the explainer.

@slightlyoff @esprehn, one of you feel like you have time to fix this example?

IntersectionObserverEntry should have a constructor

IntersectionObserverEntry objects are not exotic and there's no reason to keep their creation magic that I can see. They should have a constructor. I'd suggest one that takes a dictionary

dictionary IntersectionObserverEntryInit {
  required DOMHighResTimeStamp time;
  required DOMRectInit rootBounds;
  required DOMRectInit boundingClientRect;
  required DOMRectInit intersectionRect;
  required Element target;
}

You could try to add smart defaults instead of making everything required but that doesn't seem worth the trouble.

[[RegisteredIntersectionObservers]] setup is broken

This might be related to #35.

[[RegisteredIntersectionObservers]] is defined on Document and used in https://rawgit.com/slightlyoff/IntersectionObserver/master/index.html#3-3-event-loop, but nobody ever adds to it or removes from it.

In contrast, another [[RegisteredIntersectionObservers]] is defined on Element and modified by IntersectionObserver's methods, but nobody ever reads from it.

Again it might be worth consulting what Mutation Observers do here.

MS Feedback: Alternative Idea: imperative and event-based

Alternative Idea: imperative and event-based

While we think the modeling of this feature on the MutationObserver pattern is good and familiar, we do wonder if a far-simpler design could be used to address the ad case. We see two common questions:

  1. Set me up to respond when I'm visible (for some definition of this) -- the current approach
  2. Tell me right now (or really soon) if I'm visible (I don't want to wait till later.) - an imperative approach.

The key aspects to preserve are:

  • async
  • can collect, consolidate, and service multiple requests at once.

In our quick brainstorm, the simplest solution was an event (e.g., "isvisible") that is fired to the element in question and carries some data about it's occlusion state (fully, partially, rect list...?). The occlusion state could be accurate enough for author code to determine percentage visibility, and/or what other elements are above it in stacking context (e.g., something like elementsFromPoint, but for a rectangle... elementsFromRect?).

We also think a Promise-based isVisible() or some-such will be a strongly-requested feature.

We think a simple way of extending the target/viewport dimensions is also useful.

DOMRectReadOnly is probably more appropriate than DOMRect

readonly DOMRect rootBounds means that entry.rootBounds = {} fails; readonly DOMRectReadOnly rootBounds means that entry.rootBounds.x = -1 fails. Unless there are sensible semantics for allowing changes to the rects, it seems better to make them DOMRectReadOnlys.

Definition of `IntersectionObserverEntry.time` needs to say what the zero time is

Unfortunately, DomHighResTimeStamp doesn't have a well-defined zero time (thank you, web perf working group), so whenever you use it you have to say what your zero time is... You probably want the navigationStart of something, but please coordinate with the webperf people for the right way to phrase this, especially in cases when a single Window has multiple Documents or vice versa.

viewport rect should be the intersection of ancestor scrollers

At the CSS F2F, there was clear agreement that this is a common enough non-malicious case that the viewport rect should be the intersection of all the ancestor clipping due to overflow (hidden, auto, scroll).

To be clear, this should only apply if the viewport parameter is null, right?

@esprehn

Queueing intersection observer tasks is pretty underdefined

It looks like the UA is allowed to post a task or to post an idle request callback. Those have quite different observable behavior and it wouldn't surprise me if pages came to depend on one or the other in practice, leading them to work in some UAs but not others.

We should just pick a behavior here and define it, in my opinion.

getComputedOpacity is insufficient

The getComputedOpacity() query in the example needs to test all ancestors too. It should also test for ‘visibility’ on the element and ancestors.

Don't call public API methods; instead call their backing algorithms

A few places in the spec refer to public API methods:

The DOMRect corresponding to the target’s getBoundingClientRect().

Let boundingClientRect be the value of target.getBoundingClientRect().

For each observer in node’s internal [[RegisteredIntersectionObservers]] slot, invoke unobserve() on observer, passing in node as target.

This is not quite the right thing to do, since it implies that e.g. if I do Element.prototype.getBoundingClientRect = () => { throw new Error("boo"); }, you'll call that overriden function.

Instead, the correct thing to do is to refer to the backing concept or algorithm behind that method. For unobserve, you'd probably define something in the processing model like

"To remove an intersection observer o from an Element target, perform the following steps: ..."

Then unobserve() algorithm would do "Remove the intersection observer this from target," and instead of doing "invoke unobserve()," you would do a similar thing.

For getBoundingClientRect(), things are more annoying, since CSSOM View hasn't factored themselves appropriately. There you could do something like "Let boundingClientRect be a DOMRectReadonly obtained by the same algorithm as that of Element's getBoundingClientRect() performed on target."

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.