Find all elements containing a value in an attribute - javascript

I use this to take some attributes:
window.document.getElementsByClassName("atbk")
However the class atbk is used in different elements. I would like to keep the attributes which only have in their href a common word /url
I tried this:
window.document.getElementsByClassName("atbk").href.indexOf("/url")
but it is not helpful. Is there anything I could do?

You can use the css selector [href*="/url"] to select elements containing a substring in an attribute.
window.document.querySelectorAll('.atbk[href*="/url"]');

Try this:
var list = window.document.getElementsByClassName("atbk");
var newlist =[];
for (z = 0; z < list.length; z++)
{
if (list[z].href.indexOf('/url') > -1)
{
newlist.push(list[z]);
}
}
// use newlist...

Related

Is there an elegant way of checking whether at least one element has a certain class?

I have a list of elements, and I want to check whether at least one has the class demo_control
The following code works. Is there a more elegant way?
var a='f_date1,f_date2,f_date3,f_date4,f_field1,f_field2'.split(',');
var flag=false;
var i;
for (i = 0; i < a.length; i++) {
if ($('#'+a[i]).hasClass('demo_control')) {
flag=true;
}
}
The documentation of hasClass says:
Determine whether any of the matched elements are assigned the given class.
So no need to loop explicitly; just select the elements in one go, and apply the method on that selection:
let flag = $('#f_date1,#f_date2,#f_date3,#f_date4,#f_field1,#f_field2').hasClass('demo_control');
This could be a possible elegant solution
const ids = 'f_date1,f_date2,f_date3,f_date4,f_field1,f_field2';
const query = ids.split(',').map(el => `#${el}.demo_control`).join(', ');
const flag = $(query).length > 0;
What I've done is just created a single selector for you ids with class. And check if there are any elementa matching this selector.
If demo_control is unique to these fields, why not do:
flag = $(".demo_control").length > 0
This is all you need to do to get a class count...
flag=document.getElementsByClassName('demo_control').length>0;

How to remove a classname from an element's classlist by index?

There's this situation in which you don't know a classname's value beforehand. You do know that the classname is, for example, the 3rd class of an html element.
If you know the classname's index in the classlist, but you don't know its exact value, then how to remove it?
I'd guessed something like this would work:
var elements = document.querySelector('.element');
for (var i = 0; i < elements.length; i++) {
var classes = elements[i].classList;
for (var j = 0; j < classes.length; j++) {
if (classes[2] !== null) {
elements[i].classList.delete(elements[i].classList[2])
elements[i].classList.add('classname')
}
}
}
How can you delete a classname by index of the classlist? And how to replace or toggle the value of the classname with this same index?
The effort a Jquery answer would be appreciated, but most of my curiosity goes out to a vanilla Javascript solution.
The following code should work. Assuming domElement is the element and index is the index to remove the class
But I must say the browsers(or some user extensions) may change the classList order and it is generally not a very good idea.
var domElement = document.querySelector('.element');
let classToDelete = Array.from(domElement.classList)[index];
domElement.classList.remove(classToDelete);

document.getElementsByClassName exact match to class

There are two similar classes - 'item' and 'item one'
When I use document.getElementsByClassName('item') it returns all elements that match both classes above.
How I can get elements with 'item' class only?
The classname item one means the element has class item and class one.
So, when you do document.getElementsByClassName('item'), it returns that element too.
You should do something like this to select the elements with only the class item:
e = document.getElementsByClassName('item');
for(var i = 0; i < e.length; i++) {
// Only if there is only single class
if(e[i].className == 'item') {
// Do something with the element e[i]
alert(e[i].className);
}
}
This will check that the elements have only class item.
Live Demo
document.querySelectorAll('.item:not(.one)');
(see querySelectorAll)
The other way is to loop over the what document.getElementsByClassName('item') returns, and check if the one class is present (or not):
if(element.classList.contains('one')){
...
}
You're going to want to make your own function for exact matches, because spaces in a class means it has multiple classes. Something like:
function GetElementsByExactClassName(someclass) {
var i, length, elementlist, data = [];
// Get the list from the browser
elementlist = document.getElementsByClassName(someclass);
if (!elementlist || !(length = elementlist.length))
return [];
// Limit by elements with that specific class name only
for (i = 0; i < length; i++) {
if (elementlist[i].className == someclass)
data.push(elementlist[i]);
}
// Return the result
return data;
} // GetElementsByExactClassName
You can use Array.filter to filter the matched set to be only those with class test:
var elems = Array.filter( document.getElementsByClassName('test'), function(el){
return !!el.className.match(/\s*test\s*/);
});
Or only those with test but not one:
var elems = Array.filter( document.getElementsByClassName('test'), function(el){
return el.className.indexOf('one') < 0;
});
(Array.filter may work differently depending on your browser, and is not available in older browsers.) For best browser compatibility, jQuery would be excellent for this: $('.test:not(.one)')
If you have jQuery, it can be done using the attribute equals selector syntax like this: $('[class="item"]').
If you insist on using document.getElementsByClassName, see the other answers.

How to get html element's class tags

I'm using a custom modernizer config which has selected the features I employ in my page (and only those features).
So, I'd like to simply grab the className of the <html> of the page so I can check to see how many no- prefixed classes are present (maybe checking classlist.match(/no-/g).length) and determine if my javascript should just give up.
It's not clear whether I should use
document.getElementsByTagName('html').className
or
$('html').attr('class')
or
document.documentElement.className
I will go for:
document.documentElement.className;
Because doesn't involve any function's call, neither an additional layer like jquery. Ideally this one is the cleanest and the fastest.
you can use jQuery hasClass` method:
Determine whether any of the matched elements are assigned the given class.
if ( $('html').hasClass('no-something')) {
// do something here
}
If using plain JS, the equivalent would be:
document.getElementsByTagName('html')[0].className
If you are using jquery in your project why to not use this one:
var classList = $("html").attr('class').split(/\s+/);
var prefix = 'no-';
$.each( classList, function(index, item){
if (item.substring(0, 2) === prefix) {
//do something
}
});
?
var allClasses = [];
var allElements = document.querySelectorAll('*');
for (var i = 0; i < allElements.length; i++) {
if (allElements[i].hasAttribute("class")) {
var classes = allElements[i].className.toString().split(/\s+/);
for (var j = 0; j < classes.length; j++) {
var cls = classes[j];
if (cls && allClasses.indexOf(cls) === -1)
allClasses.push(cls);
}
}
}
console.log(allClasses);

Javascript getElementById based on a partial string

I need to get the ID of an element but the value is dynamic with only the beginning of it is the same always.
Heres a snippet of the code.
<form class="form-poll" id="poll-1225962377536" action="/cs/Satellite">
The ID always starts with poll- then the numbers are dynamic.
How can I get the ID using just JavaScript and not jQuery?
You can use the querySelector for that:
document.querySelector('[id^="poll-"]').id;
The selector means: get an element where the attribute [id] begins with the string "poll-".
^ matches the start
* matches any position
$ matches the end
jsfiddle
Try this.
function getElementsByIdStartsWith(container, selectorTag, prefix) {
var items = [];
var myPosts = document.getElementById(container).getElementsByTagName(selectorTag);
for (var i = 0; i < myPosts.length; i++) {
//omitting undefined null check for brevity
if (myPosts[i].id.lastIndexOf(prefix, 0) === 0) {
items.push(myPosts[i]);
}
}
return items;
}
Sample HTML Markup.
<div id="posts">
<div id="post-1">post 1</div>
<div id="post-12">post 12</div>
<div id="post-123">post 123</div>
<div id="pst-123">post 123</div>
</div>
Call it like
var postedOnes = getElementsByIdStartsWith("posts", "div", "post-");
Demo here: http://jsfiddle.net/naveen/P4cFu/
querySelectorAll with modern enumeration
polls = document.querySelectorAll('[id ^= "poll-"]');
Array.prototype.forEach.call(polls, callback);
function callback(element, iterator) {
console.log(iterator, element.id);
}
The first line selects all elements in which id starts ^= with the string poll-.
The second line evokes the enumeration and a callback function.
Given that what you want is to determine the full id of the element based upon just the prefix, you're going to have to do a search of the entire DOM (or at least, a search of an entire subtree if you know of some element that is always guaranteed to contain your target element). You can do this with something like:
function findChildWithIdLike(node, prefix) {
if (node && node.id && node.id.indexOf(prefix) == 0) {
//match found
return node;
}
//no match, check child nodes
for (var index = 0; index < node.childNodes.length; index++) {
var child = node.childNodes[index];
var childResult = findChildWithIdLike(child, prefix);
if (childResult) {
return childResult;
}
}
};
Here is an example: http://jsfiddle.net/xwqKh/
Be aware that dynamic element ids like the ones you are working with are typically used to guarantee uniqueness of element ids on a single page. Meaning that it is likely that there are multiple elements that share the same prefix. Probably you want to find them all.
If you want to find all of the elements that have a given prefix, instead of just the first one, you can use something like what is demonstrated here: http://jsfiddle.net/xwqKh/1/
I'm not entirely sure I know what you're asking about, but you can use string functions to create the actual ID that you're looking for.
var base = "common";
var num = 3;
var o = document.getElementById(base + num); // will find id="common3"
If you don't know the actual ID, then you can't look up the object with getElementById, you'd have to find it some other way (by class name, by tag type, by attribute, by parent, by child, etc...).
Now that you've finally given us some of the HTML, you could use this plain JS to find all form elements that have an ID that starts with "poll-":
// get a list of all form objects that have the right type of ID
function findPollForms() {
var list = getElementsByTagName("form");
var results = [];
for (var i = 0; i < list.length; i++) {
var id = list[i].id;
if (id && id.search(/^poll-/) != -1) {
results.push(list[i]);
}
}
return(results);
}
// return the ID of the first form object that has the right type of ID
function findFirstPollFormID() {
var list = getElementsByTagName("form");
var results = [];
for (var i = 0; i < list.length; i++) {
var id = list[i].id;
if (id && id.search(/^poll-/) != -1) {
return(id);
}
}
return(null);
}
You'll probably have to either give it a constant class and call getElementsByClassName, or maybe just use getElementsByTagName, and loop through your results, checking the name.
I'd suggest looking at your underlying problem and figure out a way where you can know the ID in advance.
Maybe if you posted a little more about why you're getting this, we could find a better alternative.
You use the id property to the get the id, then the substr method to remove the first part of it, then optionally parseInt to turn it into a number:
var id = theElement.id.substr(5);
or:
var id = parseInt(theElement.id.substr(5));
<form class="form-poll" id="poll-1225962377536" action="/cs/Satellite" target="_blank">
The ID always starts with 'post-' then the numbers are dynamic.
Please check your id names, "poll" and "post" are very different.
As already answered, you can use querySelector:
var selectors = '[id^="poll-"]';
element = document.querySelector(selectors).id;
but querySelector will not find "poll" if you keep querying for "post": '[id^="post-"]'
If you need last id, you can do that:
var id_list = document.querySelectorAll('[id^="image-"]')
var last_id = id_list.length
alert(last_id)

Categories

Resources