I need to find a group of elements by the end of their class names, it's highly similar to this Get element by part of Name or ID however using document.querySelectorAll([class~=<constant string>]) does not work but [class=<full class name including randoms chars (see below) does work.
The elements in question have a class name like. (random string of three chars)-(Some constant String) is it possible to find them by the (some constant string)?
The correct syntax is $= to find a class that ends with a particular string.
If you want to use a variable in that selector use a template string to insert it.
const constant = '123';
const divs = document.querySelectorAll(`[class$="${constant}"]`);
divs.forEach(div => console.log(div.textContent));
<div class="abc-123">Will be selected 1</div>
<div class="def-234">Will not be selected 1</div>
<div class="ghi-123">Will be selected 2</div>
<div class="jkl-234">Will not be selected 2</div>
Related
i want to detect the parent of element that has "_" character in it
that could be achieved using jquery and css3 selcetor ":contain" like the following
$('.class a:contains("_")').parent()
but im trying to avoid using jquery too much , so is there any way to do this using native js
There is no CSS to check if it contains text. Only way you can do text matching is if that text happened to be in an attribute on the element. So you are going to have to select all the parent elements and loop over them looping at the text/children's text.
To do that you can select all the elements and use filter to check the text. If you only care there is an underscore you can just text the text content of the element.
const elemsWithUnderscore = [...document.querySelectorAll('.yourClass')].filter(el => el.textContent.includes('_'));
console.log(elemsWithUnderscore);
<div class="yourClass"><a>a</a></div>
<div class="yourClass"><a>b_</a></div>
<div class="yourClass"><a>c</a></div>
<div class="yourClass"><a>d_</a></div>
<div class="yourClass"><a>e</a></div>
If it only can be in the anchor tag and there is one you can selector the anchor tag.
const elemsWithUnderscore = [...document.querySelectorAll('.yourClass')].filter(el => [...el.querySelectorAll('a')].some(a => a.textContent.includes('_')));
console.log(elemsWithUnderscore);
<div class="yourClass">_<a>a</a></div>
<div class="yourClass"><a>b</a><a>b_</a></div>
<div class="yourClass"><a>c</a></div>
<div class="yourClass"><a>d_</a></div>
<div class="yourClass"><a>e</a></div>
If there is more than one anchor as children then you need to use some to see if one of them has an underscore.
const elemsWithUnderscore = [...document.querySelectorAll('.yourClass')].filter(el => el.querySelector('a')?.textContent.includes('_'));
console.log(elemsWithUnderscore);
<div class="yourClass">_<a>a</a></div>
<div class="yourClass"><a>b_</a></div>
<div class="yourClass"><a>c</a></div>
<div class="yourClass"><a>d_</a></div>
<div class="yourClass"><a>e</a></div>
You can use document.querySelectorAll and check the textContent of the children.
[...document.querySelectorAll('.class')].filter(el =>
[...el.querySelectorAll('a')].some(a => a.textContent.includes('_')))
.forEach(el => console.log(el.outerHTML));
<div class="class"><a>_</a></div>
<div class="class">
<div><a>abc_def</a><span>123</span></div>
</div>
<div><a>nothing to see</a></div>
site i am selecting from looks roughly like this
<div class="start-left">
...
<div class="news-post">...</div>
<div class="news-post">...</div>
<!-- want to get this one above -->
<div class="news-post">...</div>
<div class="news-post">...</div>
<div class="news-post">...</div>
<div class="news-post">...</div>
...
</div>
tried this but didnt work on either firefox or chrome
document.querySelector('.start-left div:nth-child(2)')
is this even possible or do i need to rething how i am doing this? I am using puppeteer for a webscraper and need to be able to press a link in a specific news post, e.g the second one
nth-child(n) counts all children of the element, regardless of the type of element (tag name). If there are other elements of different type coming before your target element nth-child will fail to find the correct element and may return null.
However, the selector nth-of-type(n)
matches elements based on their position among siblings of the same
type (tag name)
and ignores elements of a different type.
// nth-child(2) returns null because the 2nd element is not a div
var wrongElement = document.querySelector('.start-left div:nth-child(2)');
// nth-of-type(2) filters using the type of element
var correctElement = document.querySelector('.start-left div:nth-of-type(2)');
console.log('div:nth-child(2): ' + wrongElement);
console.log('div:nth-of-type(2): ' + correctElement.outerHTML);
<div class="start-left">
<p class="news-post">...</p>
<p class="news-post">Not this</p>
<div class="news-post">...</div>
<div class="news-post">This one</div>
<!-- want to get this one above -->
<div class="news-post">...</div>
</div>
You could use your work-around by adding the number of preceding elements to the selector, eg nth-child(4), however, a more robust solution is to use nth-of-type(2).
I want to remove the class and id in the website using only Javascript. But that site's class and id contains random numbers and random characters, which looks like this:
<body class="class-abc ahwk-1726-rand_banner-lauwj-5210 other-class">
<div id="fire-id 3762-kahm-rand-banner_9728-jege other-id">
...
The common point of these classes and ids are in the form (some digits or characters)(- or _)banner(- or _)(some numbers or characters).
With CSS, I can easily select them using the CSS Selector: [class*="banner" i] and [id*="banner" i].
However, with the remove() in javascript it does not support CSS Selector.
So, how do I remove classes and ids of this form using Javascript?
Your answer will be highly appreciated!
As you are happy with the CSS selector, just iterate over the matches and delete them. But please note that it is not valid HTML when you have id attributes with spaces in them. An id attribute specifies one identifier, not a space-separated list of them.
So assuming that your HTML would be valid, you can do as follows:
for (let elem of document.querySelectorAll('[id*="banner" i]')) {
elem.removeAttribute("id");
}
for (let elem of document.querySelectorAll('[class*="banner" i]')) {
elem.classList.remove(...elem.className.match(/\S+banner\S+/gi));
}
console.log(document.querySelector("div").outerHTML);
<div class="class-abc ahwk-1726-rand_banner-lauwj-5210 other-class">
<div id="fire-id">
</div>
<div id="3762-kahm-rand-banner_9728-jege">
</div>
<div id="other-id">
</div>
</div>
So for id attributes we may assume that the id attribute can be removed. For class attributes we can search the value for the match(es) using a regular expression, and then pass the matching list to the classList.remove method.
Dealing with invalid HTML
If you really want to change the value of an invalid id property with spaces, then proceed as follows:
for (let elem of document.querySelectorAll('[id*="banner" i]')) {
elem.setAttribute("id", elem.getAttribute("id").replace(/\S+banner\S+/gi, "").replace(" ", " "));
}
for (let elem of document.querySelectorAll('[class*="banner" i]')) {
elem.classList.remove(...elem.className.match(/\S+banner\S+/gi));
}
console.log(document.querySelector("div").outerHTML);
<div class="class-abc ahwk-1726-rand_banner-lauwj-5210 other-class">
<!-- invalid HTML follows... --->
<div id="fire-id 3762-kahm-rand-banner_9728-jege other-id">
</div>
</div>
If you want to remove class or id from specific elements then find elements by tag name and remove class / id attrs like: element.removeAttribute('class') OR element.removeAttribute('id')
Just wondered how I would search for all the ids starting with "content_" in the whole page and also a way to only find them in a named div called "extra_content". Once i have all the ids i want to hide them.
Below is an example of what i want to find.
<div id="content_1"></div> <-- Find
<div id="content_2"></div> <-- Find
<div id="contet_3"></div>
<div id="extra_content">
<div id="content_extra_1"></div> <-- Find
<div id="content_extra_2"></div> < -- Find
</div>
Examples would be helpful.
Thanks
Use the attribute-starts-with selector:
$('[id^="content_"]').hide();
To limit the search to elements within extra_content:
$('#extra_content [id^="content_"]').hide();
I know it is a stupid question but i couldn't find a solution for this. Knocking my head for hours.
I have a HTML Structure,
<div class= 'container'>
<div class="someclass">
<input>some content</input>
<input>some content</input>
</div>
<input id="question-xxx" type="hidden"></input>
</div>
I need to get the count of all the Input elements inside the class = 'someclass' using the id = "question-xxx".
I tried using
$("#question-xxx").closest('.someclass').find('input').length;
or
$('#question-xxx').closest('.someclass').children().length;
I googled it out, and I have no clue what I'm doing wrong. Any help would be quite appreciable.
.someclass will not be found using closest try finding it by siblings.
closest is used to find the parent element of given element. Here someclass is not parent of question-xxx.
closest and parent are same. You can find more info here
$("#question-xxx").siblings('.someclass').find('input').length
var count = $('#question-xxx').prev('.someclass').find('input').length;
alert(count)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class= 'container'>
<div class="someclass">
<input>some content</input>
<input>some content</input>
</div>
<input id="question-xxx" type="hidden"></input>
</div>
use .prev() to get the div that contains the input
Description: Get the immediately preceding sibling of each element in the set of matched elements. If a selector is provided, it retrieves the previous sibling only if it matches that selector.
use .length to count