- 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:42 UTC