Is it possible to get multi pseudo-element to using javascript? - javascript

Actually, I want to get multiple pseudo-element to using querySelectorAll.
I read some of the related articles there all of the developers say we haven't access to use querySelectorAll to get multiple pseudo-element.
We can get just one element to use querySelector and code like the bellow the code.
const textAfter = window.getComputedStyle(
document.querySelector(".text-after"), ":after"
).getPropertyValue("color")
console.log(textAfter)
But sometimes our project purpose needs to use multiple selectors.
So, that's why have anyone experienced in here? who can help to solved this problem?
Thanks to #All

Reverse the order. Instead of trying to compute the properties of a list of elements, for each element in the list, compute the properties for each single element:
const elements = Array.from(document.querySelectorAll(`.text-after`));
const allOfThem = elements.map(element =>
window.getComputedStyle(element, ":after").getPropertyValue("color")
);
console.log(allOfThem);
(We use Array.from here, because while an HTMLCollection comes with .forEach, it does not come with .map so we need to force it into being a real array before we do our mapping)

Related

Is there a way to combine string and span elements into one coherent element?

Currently I'm working in a version of React and have an array of strings and JSX.Elements. For example, the array would look like this: [<span class="name">JCrew0</span>, "edited this document"]. I'm then trying to display the elements of the array next to each other to make a sentence. However, because each element is on its own, the wrapping applies to each element separately, causing the spans and the strings to wrap by themselves. This then causes all sorts of weird formatting. Is there any way to combine these array elements into one JSX.Element while still applying the styles from class="name" onto the names (wrapping them in an outer div does not work)?
Perhaps you need something like this (if I assume correctly this small array is just array in array and it will stand this way):
arr.unshift(<p>);
arr.append(</p>);
const elementString = arr.join('')

Use parentElement multiple times

I'm editing a plugin that creates filters on an table like excel(drop-down), the problem is when I use it on a table that uses a table inside it, in fact the plugin will also take the values ​​of the sub-table.
I therefore decided to exclude from the initial array, made up of all the rows, those elements that have a parent with a table that does not have an id.
So i forEach array and see if have id like:
this.tds.forEach((el) =>{
console.log(el.parentElement.parentElement.parentElement.id);
});
I was wondering if using parentElement three times like this is correct or there is another way
It's perfectly fine, as long as you're sure that the structure will always be the same.
But let's assume that you don't know if the structure will always be like this, but you do know the class of the parent you're looking for (or any other CSS query), then you could use the Element.closest() method to query your way up.
So let's say you want to find the closest table with an id value.
this.tds.forEach((el) => {
const parent = el.closest('table:not([id=""])');
if (parent !== null) {
console.log(parent.id);
}
});
This will walk up the DOM tree from the el as starting point, doing something in the likes of parentElement.parentElement.parentElement... until it reaches an element that has a value in the id attribute.
There's nothing wrong with the code.
But if you want to make the code a little more robust you can use Optional Chaining.
this.tds.forEach((el) =>{
console.log(el?.parentElement?.parentElement?.parentElement?.id);
});

JS querySelectorAll and a regular expression as selector

I wish to write something like:
var N = document.querySelectorAll("input[id^='left"+/^[0-9]*$/+"right']").length;
How do I do in JS / JQuery?
You can't. Attribute selectors do not support regexp. You can select based on prefix and suffix, though:
[id^="left"][id$="right"]
If you want to exclude elements with IDs missing the digits in between left and right, you'll have to filter them out:
Array.from(queryResults).filter(elt => /^left\d*right$/.test(elt.id));
In general, however, using IDs with complex internal structure is often not the best approach. You will have to keep constructing them and picking them apart. Consider using classes and/or data attributes, or it's often the case that if you are creating the elements yourself, you can just remember the elements and reference them directly.

Identity selectors in jQuery returning arrays

Suppose I have a div tag like this:
<div id="group-dialog" class="modal-dialog">
Now I want to grab it as a jQuery object (in this case so I can run .dialog()).
When I try this:
var gDialog = $('#group-dialog');
I get an array back (!!).
Why am I getting an array? Isn't the point of having an ID attribute that there's only one? I can see getting multiple p's or .my-css-thing back ...
Next question:
I have this array with 1 object in it that I now want to access as a jQuery object.
When I do this:
$(gDialog[0])
And pull it up in F12, I still have an array!! I thought I de-referenced the array already by picking the first element.
This doesn't seem to help either:
var gDialog = $('#group-dialog:first');
This is basic, but I run into this problem a lot. It seems like it used to be a lot simpler!
What is the best way to access this DOM element as a jQuery object?
Answer 1
jQuery selectors always return arrays.
Selection with id attribute is a particular use case and ideally the result should be unique. However, there is nothing preventing you from having duplicated ids in a HTML document (although this is bad practice).
Answer 2
The following code will get you the first element as a DOM object:
var gDialog = $('#group-dialog')[0];
Note: you may want to check the size of the return array first.
As far as I know, there is no way to transform this DOM element back to a jQuery object. The standard use case would be to directly used $('#group-dialog') and asume that it is found and unique.
Try using .get(). Though I'm not sure it will work with dialog()
Retrieve the DOM elements matched by the jQuery object.
var gDialog = $('#group-dialog').get();
If you're trying to grab it to use it on a dialog, you can just put
$(document).ready(function(){
$('#group-dialog').dialog({put options here})
});

Restructuring DOM searching method?

As part of a Chrome extension I am searching the entire DOM for elements containing specific words inside each ID/Class.
Currently it looks something like:
"allSelectors": document.querySelectorAll("[id*='example'][class*='example']"),
"collapse": function () {
for (var i = 0; i < MyObject.allSelectors.length; i++) {
// Manipulate MyObject.allSelectors[i] etc
}
},
First, I would like to restructure it somehow (possibly using an array?) so that it is easy to add new selectors as doing it like this:
document.querySelectorAll("[id*='example'][class*='example'][id*='other'][class*='other']")
Isn't easily scaleable or good.
Secondly, I think document.querySelectorAll is very slow - the reason I am using it is because I need to search anywhere in an id/class (hence the use of *=) and cannot use a big external library (such as jQuery), as this is a small file and is being injected user side.
Is there an any solution to either of these problems? because if there are many matches then this slowness might become an issue.
First of all I would totally go for querySelectorAll, I don't think it's that slow, and also it totally fits in a situation like yours. I agree with you that adding a library is overkill for this, and additionally it might not be as beneficial as someone thinks (let's test it here).
Then, again I agree with you that the current solution is not very scalable and that the array is the way to go. Here's a very basic implementation using an array:
// an array of classes and ids to match
var nodes,
searches = [
'[id*="test"]',
'[class*="example"]'
];
// a simple function to return an array of nodes
// that match the content of the array
function getNodes(arr){
return Array.prototype.slice.call(document.querySelectorAll( arr.join() ));
}
nodes = getNodes(searches);
The good thing is that new classes and ids can be easily added or removed from the array, for example, later on you can add:
searches.push('[id*="some"]');
nodes = getNodes(searches); // new nodes will be fetched
Here's a jsbin with a full example code.

Categories