- From: Sean Hogan <shogun70@westnet.com.au>
- Date: Sun, 21 Sep 2014 22:02:09 +1000
- To: Anne van Kesteren <annevk@annevk.nl>
- CC: Boris Zbarsky <bzbarsky@mit.edu>, "Tab Atkins Jr." <jackalmage@gmail.com>, "www-style@w3.org" <www-style@w3.org>, "www-dom@w3.org" <www-dom@w3.org>, David Håsäther <hasather@gmail.com>
On 4/09/14 7:54 PM, Anne van Kesteren wrote:
> On Tue, Sep 2, 2014 at 6:53 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:
>> ...
> So let's see. If we don't pass a :scope elements argument we get
>
> E.matches(":scope") -> false
> E.closest(":scope") -> null
> E.closest(":has(> :scope)" -> null
>
> If we pass E as :scope elements we get
>
> E.matches(":scope") -> true
> E.closest(":scope") -> E
> E.closest(":has(> :scope)" -> E's parent
>
> Now for closest() we could also pass the current ancestor A as :scope
> elements, then we get
>
> E.closest(":scope") -> E
> E.closest(":has(> :scope)" -> null
>
> It seems to me that passing the element on which the method is invoked
> as :scope elements (i.e. E) makes the most sense. That argues for 1).
>
>
My last response was a bit disorganized, mostly because I was thinking
aloud.
Take 2:
E.closest() and E.matches() should take an additional argument - an
explicit scoping root.
If the explicit scoping root is not an ancestor of E then E.matches()
will fail and E.closest() will find nothing.
If no explicit scoping root is passed then EITHER:
the selector must be an absolute selector
OR
the implied scoping root is assumed to be the **document** or
fragment or virtual fragment of E.
E.closest(selector, scope) attempts to find a matching element by
testing E against the selector, and if that fails then testing E's
parent, and-so-on until the scoping root is reached. The scoping root is
NOT tested, even if it is an element.
The use-cases for this form of call are in scoped-event-delegation.
E.matches(selector, scope) will be used when the event listener at the
scoping root needs to detect that the event-target matches the scoped
selector. e.g.
function listener(event) {
if (!event.target.matches(relativeSelector,
event.currentTarget)) return;
// event.target does match. Perform handler
}
E.closest(selector, scope) will be used when the event listener at the
scoping root needs to detect that the event bubbles through an element
that matches the scoped selector. e.g.
function listener(event) {
var myTarget = event.target.closest(relativeSelector,
event.currentTarget);
if (!myTarget) return;
// event has bubbled thru a matching element. Perform handler
}
If no explicit scoping root is passed and no explicit ":scope" is in the
selector, e.g.
E.matches('ul li')
then
assuming this is an absolute selector
is equivalent to
assuming it has an implied :scope which matches the document.
If the scoping root is assumed to be E then you can only have absolute
selectors.
regards,
Sean
Received on Sunday, 21 September 2014 12:02:46 UTC