I learned jQuery on a project where everyone was expected to be full stack but only 2.5 of us could do any deep work on the front end.
I have done much, much harder things than convincing my coworkers to distinguish between 'important' nodes in a composition and incidental ones. Never put the incidental ones in your selectors.
If I'm a "Select All" checkbox, I need to find all of the checkboxes in "my" block of HTML that are not me, and select or unselect them. I don't give a shit if that's two divs up, one over and three down. Or if some IE bug means now it's three divs up and two over. I care about some top level element, and any of its children at any depth.
That's it. If I write my element selectors that way, I'm done and the layout people can put in a scrollbar later, or an expando. Also if I write my CSS the same way, it's easy to make these sorts of changes and it's easy to correlate the CSS with the Javascript that affects the same elements.
So much simpler than spending all day in a debugger when you're not in bug triage.
Most of those query selectors we relied on now have feature parity in the spec. I don't see why you couldn't use the same strategies in a vanilla situation today.
Could you expand upon what you mean when you say a checkbox has "my" block of html? That a given element should not make changes in elements that are at a higher level in the tree?
There are a bunch of elements we add to the page or remove to get certain visual effects to work well but they really have nothing to do with the logic of the page. Few if any interactive components ever care about them, or only for one specific interaction.
Classic example of the 'only one interaction' situation: the coworker who thinks he can use string concatenation for query parameters and you know that if you just wrap it in a form element, all of that is cheap or free and you just have to hook the form submit event to turn it into an AJAX request instead of a navigation. But that means that you've wrapped all of his DOM in a form element and now all of the CSS and half of the handlers stop working because they're looking for body>div>div>option and now it's body>div>div>form>option and now you wish you hadn't even touched this stinking pile but it's the principle and by god you're gonna finish this.
Or you had a block of elements on a page and now your boss wants it on the other side of the page, on another page, on every page, all over this page, or on a completely separate site.
What you want to solve these problems in a way that mostly stays solved is to try for a query selector with the lowest specificity (and no IDs) that still exactly identifies the DOM elements you are looking for. So there is some titular 'owner' element that all of these interactions are contained in, and they find each other by walking up until they find a particular shared parent and call parent.querySelectorAll() to find their peers, and only their peers. Not some other random element halfway down the page.
So for instance a click on .preferences .selectAll should find the first parent with class 'preferences', call querySelectorAll(".options"), and then invoke foo.selected = true on all of them. Not parent.parent.parent and then down through div>div>ul>li>input[type="checkbox"]
I have done much, much harder things than convincing my coworkers to distinguish between 'important' nodes in a composition and incidental ones. Never put the incidental ones in your selectors.
If I'm a "Select All" checkbox, I need to find all of the checkboxes in "my" block of HTML that are not me, and select or unselect them. I don't give a shit if that's two divs up, one over and three down. Or if some IE bug means now it's three divs up and two over. I care about some top level element, and any of its children at any depth.
That's it. If I write my element selectors that way, I'm done and the layout people can put in a scrollbar later, or an expando. Also if I write my CSS the same way, it's easy to make these sorts of changes and it's easy to correlate the CSS with the Javascript that affects the same elements.
So much simpler than spending all day in a debugger when you're not in bug triage.
Most of those query selectors we relied on now have feature parity in the spec. I don't see why you couldn't use the same strategies in a vanilla situation today.