0

In JavaScript I want to use document.querySelector to "grab" the last div (<div class="widget-footer">) in below HTML. However after many tries, I still can't figure out the correct CSS selector syntax to use.

The following code does not work:

document.querySelector (".skin-grid-widgets.ui-sortable.gridWidgetTemplatePositie.AgendaStandaard.disablesorting.hoogte-1-knoppen-0.breedte-1.widget-footer")

Here is the HTML I am working with

<div class="skin-grid enkeleKolom" id="Infobalk">
    <div class="skin-grid-widgets ui-sortable">
        <div class="gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1">
            <div class="widget-header">
                here comes the header text
             </div>
            <div class="widget-body">
                some body text
            </div>   
            <div class="widget-footer">
                here comes the footer text
            </div>
        </div>
    </div>
</div>

I've surfed everywhere to find example of complex CSS selectors used with querySelector, but to no avail. Any help would be really appreciated.

Heretic Monkey
  • 10,498
  • 6
  • 45
  • 102
  • 2
    because you do not have an element with the `class="skin-grid-widgets ui-sortable gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1 widget-footer"` – epascarello Apr 25 '17 at 17:32
  • use jquery, and all of your problems will be solved. mostly. – Yaakov Ainspan Apr 25 '17 at 17:36
  • 1
    @TricksfortheWeb That is funny.... How would it be solved when querySelector selects elements in the same manner. – epascarello Apr 25 '17 at 17:37
  • 1
    I have a feeling the route cause of the issue is trying to reference element before it is rendered. http://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element – epascarello Apr 25 '17 at 17:41
  • @epascarello I agree, considering my demo is working with the provided HTML – mhodges Apr 25 '17 at 17:46
  • @epascarello, it's a joke. mostly. – Yaakov Ainspan Apr 25 '17 at 18:58

3 Answers3

0

Your issue is you need a space in between each child element you are trying to select. If you do not have spaces in between your class selectors, by CSS specification, it will look for both classes on the same element.

Change your selector to look like the following:

var footer = document.querySelector(".skin-grid-widgets.ui-sortable .gridWidgetTemplatePositie.AgendaStandaard.disablesorting.hoogte-1-knoppen-0.breedte-1 .widget-footer");

footer.classList.add("highlight");
.highlight {
  background-color: yellow;
}
<div class="skin-grid enkeleKolom" id="Infobalk">
    <div class="skin-grid-widgets ui-sortable">
        <div class="gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1">
            <div class="widget-header">
                here comes the header text
             </div>
            <div class="widget-body">
                some body text
            </div>   
            <div class="widget-footer">
                here comes the footer text
            </div>
        </div>
    </div>
</div>
mhodges
  • 9,573
  • 1
  • 22
  • 43
  • Thanks, but that was one of the things I already tried. This code still returns "bummer": (document.querySelector(".skin-grid-widgets.ui-sortable .gridWidgetTemplatePositie.AgendaStandaard.disablesorting.hoogte-1-knoppen-0.breedte-1 .widget-footer") !== null){ alert("STRIKE"); } else { alert("BUMMER"); } – Dirk Bomans Apr 25 '17 at 17:35
  • 1
    @DirkBomans Then either you still have a typo, your DOM does not look like you have shown, or you have a timing issue – mhodges Apr 25 '17 at 17:38
  • @DirkBomans Are these elements being added dynamically? Also, are you loading your script in the `` tag, or at the bottom of your ``? – mhodges Apr 25 '17 at 17:47
0

try this:

<script>
   document.querySelector (".skin-grid-widgets .gridWidgetTemplatePositie .widget-footer");
</script>

You don't need to add adjacent classes like "skin-grid-widgets ui-sortable" in querySelector, if you do so then query selector assumes that "skin-grid-widgets" is parent of "ui-sortable". Use just one of the classes at one DOM level.

Neetigya
  • 91
  • 1
  • 9
  • 1
    Please add some explanation of why/how this code helps the OP. This will help provide an answer future viewers can learn from. See [this Meta question and its answers](http://meta.stackoverflow.com/q/256359/215552) for more information. – Heretic Monkey Apr 25 '17 at 17:44
0

The selector ain't complex, your thoughts are.

Listen to yourself, to the description you provide of what you want to select:

"grab" the last div in below HTML

Not grab the node with the class widget-footer inside of a node that has all these classes: gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1, inside a node ...

//a utility, because DRY.
//and because it's nicer to work with Arrays than with NodeLists or HTMLCollections.
function $$(selector, ctx=document){
    return Array.from(ctx.querySelectorAll(selector));
}

//and the last div in this document:
var target = $$('div').pop();

or

"grab" <div class="widget-footer"> in below HTML

var target = document.querySelector("div.widget-footer");

or the combination: grab the last div.widget-footer in the HTML

var target = $$('div.widget-footer').pop();
Thomas
  • 8,708
  • 1
  • 10
  • 21
  • It depends on how many assumptions you can make. For example, I find it unlikely that you can just do document.querySelector("div.widget-footer") because that assumes that there is only one div.widget-footer in the entire document (unless you think that fragment is all there is in the entire page...). There's probably a very good reason the asker wants the div.widget-footer only in that particular ancestor - and therefore a very good reason why their thoughts are that complex. – BoltClock Apr 26 '17 at 04:53
  • What I find most amusing about this is that you specify a ctx argument in your $$ definition... but your example just goes with the default of the document object anyway. – BoltClock Apr 26 '17 at 04:56
  • @BoltClock, that's the ambiguity between what the asker is describing what he wants and what he's trying. Finally he's the only one who knows what his entire document structure looks like. I was orientating on what he describes he wants and not on his failing attempt to implement it. – Thomas Apr 26 '17 at 13:41
  • @BoltClock And about `$$` and the amusing `ctx`. This utility is oversized for this specific task, but in my experience this won't stay the only place in a page one wants to select a list of nodes and somehow iterate/process them. And although most of the time I use `document` as the context for the queries, sometimes I need a different Element there. And I don't want, that I have to be explicit/repeat myself, for like 90% of the default cases, like I don't want to write another (pretty much identical) function for these 10% of cases. – Thomas Apr 26 '17 at 13:44