Search code examples
javascriptdomselectors-api

querySelectorAll for element contain specific class


I have few divs that contain two classes such as this:

<div class="dateNumbers"></div>
<div class="dateNumbers {{month.year + '-' + month.monthName + '-' + 'end'}}"></div>
<div class="dateNumbers {{month.year + '-' + month.monthName + '-' + 'end'}}"></div>
<div class="dateNumbers {{month.year + '-' + month.monthName + '-' + 'end'}}"></div>

where {{month.year + '-' + month.monthName + '-' + 'end'}} for a certain month is 2018-August-end

I want to select the divs that contain only 2018-August-end which I store into a variable so I tried something like this

var dataName = `2018-August-end`; // this is dynamic but for this example I have it static

document.querySelectorAll( "." + dataName);

but I get this error

Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Document': '.2018-August-end' is not a valid selector. at :1:10

why is that ?

Thanks


Solution

  • Class name dot (.) selectors can't start with an unescaped digit (2, in your case).

    The simplest solution is to just start them with a letter instead, which I strongly recommend:

    Example:

    const datePart = "x2018-August-end";
    console.log(
      document.querySelectorAll(".\\" + datePart).length
    );
    <div class="dateNumbers"></div>
    <div class="dateNumbers x2018-August-end"></div>
    <div class="dateNumbers x2018-August-end"></div>
    <div class="dateNumbers x2018-August-end"></div>

    Alternately, you can use the [class~=value] notation, which is functionally identical (for HTML):

    document.querySelectorAll("[class~='" + datePart + "']")
    

    Example:

    const datePart = "2018-August-end";
    console.log(
      document.querySelectorAll("[class~='" + datePart + "']").length
    );
    <div class="dateNumbers"></div>
    <div class="dateNumbers 2018-August-end"></div>
    <div class="dateNumbers 2018-August-end"></div>
    <div class="dateNumbers 2018-August-end"></div>

    It's also possible to escape the first digit with . notation, but it's painful. (You can't just throw a backslash in front of it, as you can with some libraries like jQuery.)