简体   繁体   中英

Get the argument of an existing document.querySelector in JavaScript?

Is there any way to get the string argument of document.querySelector in JavaScript?

For instance, say I have this existing selector:

const myElement = document.querySelector("div[some-complicated=selector]");

Is there any way to get just "div[some-complicated=selector]" from myElement ?

I know I could theoretically put the selector itself in a variable and then pass the variable to the querySelector , then reference that variable elsewhere. But I'd like to avoid doing that if possible.


My actual use case is event delegation; I want to avoid repeating the same selector. So currently I'm doing:

document.querySelectorAll("[data-component=tabs]").forEach((element) => {
  const tabs = element.querySelectorAll("[role=tab]");

  document.addEventListener("click", (event) => {
    if(!(event.target.matches("[role=tab]") && event.path.indexOf(element) > -1)) {
      return;
    }

    // Do stuff...
  });
});

So basically I'm wanting to pull the selector string from the querySelectorAll so I can pass it to the matches method, but without having to variablize [role=tab] .

Okay, @Teemu's comment sent me down a rabbit hole and I kind of found a roundabout way of doing it via Element.attributes . It's not pretty and doesn't really save me any of the verbosity I was trying to avoid by not simply variablizing the selector string, but for the sake of the thought experiment I figured I'd post a solution here (I could see it having practical use in some cases but there should really be a native API for this).

Essentially, I can reconstruct a selector by joining all the attributes together in the form of a CSS selector.

Array.from(element.attributes).map((attribute) => `[${attribute.name}='${attribute.value}']`).join("");

Or if using querySelectorAll like in my actual example:

Array.from(elements[0].attributes).map((attribute) => `[${attribute.name}='${attribute.value}']`).join("");

Note this doesn't recreate the selector actually used to query the element, but creates a selector from all the attributes of the given element, which is kind of a bummer. But in my event delegation example this would be sufficient.

Theoretically though, you could even narrow it down to specific attributes (eg role ), or even just go through the classList instead of all the attributes . For example:

Array.from(elements.classList).map((className) => `.${className}`).join("");

Like I said, doesn't really help me, but answers the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM