Closed orangemug closed 9 years ago
So what is the general opinion on this PR? Merge or close?
OK. I am really sorry that it has taken me so long to think this through and I think I am finally clear in my head about how I feel about this.
One of the main design principles behind DOM Delegate is that you should be able to detach it from one bit of DOM and attach it to another and for it to continue working.
So imagine the DOM looked like this
<body>
<section id="pane-1">
<button>Click me</button>
</section>
<section id="pane-2">
<button>No, Click me</button>
</section>
</body>
var pane1 = document.getElementById('pane-1');
var pane2 = document.getElementById('pane-1');
var dd = new Delegate();
dd.on('click', '> button', function() {
console.log("button clicked");
});
dd.root(pane1);
// Clicking 'Click me' => console.log
// Clicking 'No, click me' => nothing
dd.root(pane2);
// Clicking 'Click me' => nothing
// Clicking 'No, click me' => console.log
To being able to support this I believe we need to keep all state in memory in javascript. (Or also add UIDs to the DOM as you de-root
and re-root
DOM delegates - which feels like a fair amount of overhead...)
Even though it'd probably be less performant I'd actually prefer an implementation that walked over the root element's current children looking for a match - as that wouldn't require modifying (and therefore holding state in) the DOM. I don't mind doing this work.
Something like...
function matchesDirectChild(selector, element) {
var children = this.rootElement.children;
for (var i=0, l=children.length; i<l; i++) {
if (element === children[i] && matches.call(children[i], selector)) {
return true;
}
}
}
What do you think?
I'm not sure that works, unless I'm misunderstanding something. I think you're going to have to write a css rule parser to achieve this functionality. Imagine the DOM structure
<div>
<div>
<div></div>
</div>
</div>
How would the following selector get matched in your above example?
> div
I'm also not sure its exactly storing state in the DOM, it's just making them selectable. It just happens to be unique it's no different to any other class/id on the DOM element is it? Also what are the downsides of having a unique data-attribute on a DOM element?
Removing data-attributes when we change the root (good spot) won't be difficult, let me know what you think.
It works in firefox/chrome locally but not on travis, I'll work that out tomorrow. Let me know what you think
I realised I hadn't yet put a use case for this. So if you're using a framework like fruitmachine and you have a module with nested modules of the same type. How would you bind to the correct DOM node. For example
<div class="menu">
<a href="#" class="menu__title">root</a>
<div class="menu__children">
<div class="menu">
<a href="#" class="menu__title">sub-menu item1</a>
</div>
<div class="menu">
<a href="#" class="menu__title">sub-menu item2</a>
</div>
</div>
</div>
Adding a selector of .menu__title
to the root would fire on any child nodes as well as the root menu. The current API makes nested menus really difficult.
Also note this functionality is included in http://dev.w3.org/2006/webapi/selectors-api2/ and looks like there is a shim https://github.com/lazd/scopedQuerySelectorShim. However I don't think Element.matches
would work with :scope
, so we'd have to change domdelegate to use querySelector in the scoped case.
So I still think this pull request is the correct approach, I also prefer the > .direct
syntax, rather than the :scope > .direct
syntax for our usage.
@matthew-andrews any thoughts?
Just chiming in here as the author of scopedQuerySelectorShim. I believe scoped delegation is required functionality, but unfortunately something you'll have to implement manually even full support for :scope
is present in the browser. The querySelector
approach will work, and you can require that your customers include a shim if they want to support it. This will change the browser support for this library, so it is definitely a breaking change.
This will change the browser support for this library, so it is definitely a breaking change.
@lazd sorry I don't understand, are you saying this pull request will change browser support? If so can you highlight which bit.
@orangemug, I was implying that, without an ID hack (as in scopedQuerySelectorShim), relying on querySelector
alone would result in a browser support change.
Looking at your PR, since you do the ID hack, it should work everywhere.
Thanks @lazd, just waiting to see if @matthew-andrews is happy with this in the lib now (then I'll work out why the tests are failing on travis)
@matthew-andrews can you decide if you want this in the lib or not, and comment / close.
Ok I've decided I'm going to try to maintain my own fork of ftdomdelgate, I'll merge this ticket into that fork instead. Closing ticket, I'll update this ticket with details for anyone thats interested.
Started a forked repo at https://github.com/orangemug/domdelegate for anyone who wants this feature
Added scoped selector support. This uses data attributes so it'll suffer on perf a bit, although looking at this its not too bad http://jsperf.com/queryselectorall-vs-getelementbyid/32