I need to read elements class name. I have elements like this:
<article class="active clrone moreclass">Article x</article>
<article class="active clrtwo moreclass">Article y</article>
<article class="active clrthree moreclass moreclass">Article z</article>
<article class="active clrone moreclass">Article xyza</article>
I need to parse out class name that starts with clr. So if second element was clicked then I would need to get clrtwo className.
You can use a regular expression match on the class name of the clicked item to find the class that begins with "clr" like this:
$("article").click(function() {
var matches = this.className.match(/\bclr[^\s]+\b/);
if (matches) {
// matches[0] is clrone or clrtwo, etc...
}
});
Here is solution for you:
$('article').click(function () {
var className = this.className.split(' ');
for (var i = 0; i < className.length; i+=1) {
if (className[i].indexOf('clr') >= 0) {
alert(className[i]);
}
}
});
http://jsfiddle.net/vJfT7/
There's no matter how you're going to order the different classes. The code will alert you a class name only of there's 'clr' as a substring in it.
Best regards.
If you don't need to find elements based on these classes (e.g. doing $('.clrtwo')) it would be nicer to store the data as a data-clr attribute. This is standards-compliant from HTML5, and is supported by jQuery using the .data() function.
In this instance, I would modify your HTML in this way:
<article class="active moreclass" data-clr="one">Article x</article>
<article class="active moreclass" data-clr="two">Article y</article>
<article class="active moreclass moreclass" data-clr="three">Article z</article>
<article class="active moreclass" data-clr="one">Article xyza</article>
I would then use Javascript like this:
$('article.active').click(function() {
console.log($(this).data('clr'));
});
jsFiddle example
If it is always the second class name which is of interest you can do this:
$("article").click(function () {
// split on the space and output the second element
// in the resulting array
console.log($(this)[0].className.split(" ")[1]);
});
http://jsfiddle.net/karim79/Z3qhW/
<script type="text/javascript">
jQuery(document).ready(function(){
$("article").click(function(){
alert($(this).attr('class').match(/\bclr[^\s]+\b/)[0]);
});
});
</script>
This should jquery script should do what you asked (tested on jsfiddle):
$(document).ready(function () {
function getClrClass(elem) {
var classes = elem.getAttribute('class').split(' ');
var i = 0;
var cssClass = '';
for (i = 0; i < classes.length; i += 1) {
if (classes[i].indexOf('clr') === 0) {
cssClass = classes[i];
i = classes.length; //exit for loop
}
}
return cssClass;
};
$('article').click(function (e) {
var cssClass = getClrClass($(this)[0]);
alert(cssClass);
e.preventDefault();
return false;
});
});
Hope this helps.
Pete
Use an attribute selector to get those that have class names that contain clr.
From there:
extract the class name (string functions)
analyze the position
determine the next element
The latter two might be best served by a translation array if you only had a few classes.
UPDATE
I agree with lonesomeday, you'd be far better off using data-* attribute to handle such logic. Using CSS as JavaScript hooks is a thing of the past.
http://jsfiddle.net/4KwWn/
$('article[class*=clr]').click(function() {
var token = $(this).attr('class'),
position = token.indexOf('clr');
token = token.substring(position, token.indexOf(' ', position));
alert(token);
});
Related
I'd like to select an element using javascript/jquery in Tampermonkey.
The class name and the tag of the elements are changing each time the page loads.
So I'd have to use some form of regex, but cant figure out how to do it.
This is how the html looks like:
<ivodo class="ivodo" ... </ivodo>
<ivodo class="ivodo" ... </ivodo>
<ivodo class="ivodo" ... </ivodo>
The tag always is the same as the classname.
It's always a 4/5 letter random "code"
I'm guessing it would be something like this:
$('[/^[a-z]{4,5}/}')
Could anyone please help me to get the right regexp?
You can't use regexp in selectors. You can pick some container and select its all elements and then filter them based on their class names. This probably won't be super fast, though.
I made a demo for you:
https://codepen.io/anon/pen/RZXdrL?editors=1010
html:
<div class="container">
<abc class="abc">abc</abc>
<abdef class="abdef">abdef</abdef>
<hdusf class="hdusf">hdusf</hdusf>
<ueff class="ueff">ueff</ueff>
<asdas class="asdas">asdas</asdas>
<asfg class="asfg">asfg</asfg>
<aasdasdbc class="aasdasdbc">aasdasdbc</aasdasdbc>
</div>
js (with jQuery):
const $elements = $('.container *').filter((index, element) => {
return (element.className.length === 5);
});
$elements.css('color', 'red');
The simplest way to do this would be to select those dynamic elements based on a fixed parent, for example:
$('#parent > *').each(function() {
// your logic here...
})
If the rules by which these tags are constructed are reliably as you state in the question, then you could select all elements then filter out those which are not of interest, for example :
var $elements = $('*').filter(function() {
return this.className.length === 5 && this.className.toUpperCase() === this.tagName.toUpperCase();
});
DEMO
Of course, you may want initially to select only the elements in some container(s). If so then replace '*' with a more specific selector :
var $elements = $('someSelector *').filter(function() {
return this.className.length === 5 && this.className.toUpperCase() === this.tagName.toUpperCase();
});
You can do this in vanilla JS
DEMO
Check the demo dev tools console
<body>
<things class="things">things</things>
<div class="stuff">this is not the DOM element you're looking for</div>
</body>
JS
// Grab the body children
var bodyChildren = document.getElementsByTagName("body")[0].children;
// Convert children to an array and filter out everything but the targets
var targets = [].filter.call(bodyChildren, function(el) {
var tagName = el.tagName.toLowerCase();
var classlistVal = el.classList.value.toLowerCase();
if (tagName === classlistVal) { return el; }
});
targets.forEach(function(el) {
// Do stuff
console.log(el)
})
I need to create a function which gets user input (a css selector) and removes all of those elements.
This is the function so far
function removeBySelector(selector) {
var thisOne = document.querySelectorAll(selector);
for(var i = 0; i<thisOne.length; i++) {
document.removeChild(thisOne[0]);
};
};
and the HTML that starts it
<button type="button" name="button" onclick="removeBySelector(prompt('Type the selector e.g p/ p.pClass'));">Remove By Selector</button>
change your method to
function removeBySelector(selector)
{
var thisOne = document.querySelectorAll(selector);
for(var i = 0; i<thisOne.length; i++)
{
thisOne[i].parentNode.removeChild( thisOne[i] ); //changed parentElement to parentNode
};
}
i'd advise using the framework jQuery! It is a very powerful tool that helps you simplify and improve your JavaScript code and it's performance.
With jQuery you can easily use this piece of code to remove any elements by CSS selector.
// Use any CSS Selector here
var elements = $(".class");
$.each(elements, function(){
$(this).remove();
)};
This keeps your code very easy to read and has a high performance.
//Try this code:
var removeElement=function(selector){
$(document).find(selector).remove();
};
removeElement('h1'); // will remove all H1 elements from Document.
You can do the same, without using any library with pure javascript (ES6 syntax in this case):
let elements = document.querySelectorAll(".please-remove");
elements.forEach(e => e.remove());
<div>
<div class="keep">Keep this element</div>
<div class="please-remove">1</div>
<div class="please-remove">2</div>
<div class="please-remove">3</div>
<div class="please-remove">4</div>
<div class="please-remove">5</div>
<div class="please-remove">6</div>
</div>
I have this html code.
<div class="breadcrumb">
Home
<a class="breadcrumb" href="#">About</a>
<a class="breadcrumb" href="#">History</a>
Message from our Founding Members
</div>
Using javascript I want to get the text from the div ".breadcrumb". The problem is the a tag under the div also has a class with the same name, when I run this code:
var names = document.querySelectorAll('.breadcrumb');
return [].map.call(names, function(name) {
return name.textContent;
});
My first element of the array gets the textContent of all the a elements and also the div.
How can I do to get the text of only the div. In this case I want to return only "Message from our Founding Members".
Is there a way to select only the root item of the html, when they have all the same class ?
Thanks
If you want to get the text from the <a> tags with the class="breadcrumb", you can do that by using more specific selectors that include the tag type like this:
var items = document.querySelectorAll("div.breadcrumb a.breadcrumb");
var text = [];
for (var i = 0; i < items.length; i++) {
text.push(items[i].textContent);
}
Working demo: http://jsfiddle.net/jfriend00/kVwH8/
If, what you're trying to do is to get the "Message from our Founding Members" text (I wasn't entirely clear from your original question), then you can do that like this::
var items = document.querySelectorAll("div.breadcrumb a.breadcrumb");
// get node after the last item (that should be the desired text node)
var txtNode = items[items.length - 1].nextSibling;
console.log(txtNode.nodeValue); // Message from our Founding Members
Working demo: http://jsfiddle.net/jfriend00/kynuE/
use div.breadcrumb because that will give you divs with class breadcrumb, not a tags.
You can do this:
var names = document.querySelectorAll('div.breadcrumb')[0].childNodes;
var text = Array.prototype.reduce.call(names,function(prev,node){
if(node.nodeType === 3) return (prev || '' + node.textContent.trim());
});
console.log(text);
There are a lot of ES5 stuff here like trim and reduce so better have those polyfills handy.
I need to hide all the elements that have the string "replies-36965584" anywhere in their IDs.
HTML:
<div id="replies-36965584_1">aaaa</div>
<div id="replies-36965584_2">aaaa</div>
<div id="replies-36965584_3">aaaa</div>
<div id="replies-36965584_4">aaaa</div>
<div id="replies-36222224_2">nnnn</div>
JavaScript:
document.getElementById("replies-36965584").style.display="none"
How can I modify this JS to select the first four elements?
You can do this with CSS and attribute selectors.
[att^=val]
Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.
Source: http://www.w3.org/TR/css3-selectors/#attribute-substrings
jsfiddle
CSS
[id^="replies-36965584_"] {
display: none;
}
Is using jQuery an option? If so, this is dead simple:
$(document).ready(function(){
$('div[id^="replies-36965584"]').hide();
});
If you're unfamiliar with jQuery, here's a link to get started: http://learn.jquery.com/javascript-101/getting-started/
EDIT: Fixed syntax error.
EDIT: Added jsFiddle: http://jsfiddle.net/xbVp9/
If you don't know certain literal values but you know the general pattern and only the number will change, then I will consider some matching with regular expresiion.
You can do it the painful way:
var o = document.getElementsByTagName("div");
for (var i=0;i<o.length;i++) {
if(o[i].id.indexOf('replies-36965584') == 0) {
o[i].style.display = 'none';
}
}
The only way to do this with vanilla javascript that I know of, is to fetch all the divs on the page, and test the id's for the ones you want.
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; ++i) {
var div = divs[i];
if (/replies-36965584/.test(div.id)) {
div.style.display = 'none';
}
}
I have two unordered lists, each filled with list items that have a DYNAMIC class name. When I say "dynamic" I mean they are not generated by me, but they don't change once the lists have been created. These class names are id's I'm getting from an API, so they're just random numbers. A simple example would be something like...
<ul class="listA">
<li class="123"></li>
<li class="456"></li>
<li class="789"></li>
</ul>
<ul class="listB">
<li class="789"></li>
<li class="101"></li>
<li class="112"></li>
</ul>
What I'm trying to do is compare the two lists, and have any matches be highlighted, in this case the items with the class "789" would match. When I say highlighted, I just mean I'll probably apply some css after a match is found, like maybe a background color or something (not too important yet). The problem really lies in the fact that the lists can be somewhat long (maybe 50 items) and the classes are just random numbers I don't choose, so I can't do any specific searches. Also, there will most likely be cases with multiple matches, or no matches at all.
I'm pretty new to jQuery, so there may be a fairly simple answer, but everything I find online refers to searching by a specific class, such as the .find() method. If anyone needs more info or a better example, I'll be happy to give more info, I'm just trying to keep it simple now.
Thanks so much in advance!
var $first = $('ul.listA li'),
$second = $('ul.listB li');
$first.each(function(){
var cls = this.className,
$m = $second.filter(function(){
return this.className === cls;
});
if ($m.length) {
$(this).add($m).addClass('matched');
}
});
http://jsfiddle.net/b4vFn/
Try it this way:
$("ul.listA li").each(function(){
var listAval = $(this).attr('class');
$("ul.listB li").each(function(){
if(listAval == $(this).attr('class')){
//matched..
return false; //exit loop..
}
}
}
you can find the code here: jsFiddle
var listA=$('.listA li')
var listB=$('.listB li')
listA.each(function(){
var classInA=$(this).attr('class');
listB.each(function(){
var classInB=$(this).attr('class');
if(classInA === classInB){
console.log(classInA);
//now you found the same one
}
})
})
Demo at http://jsfiddle.net/habo/kupd3/
highlightDups();
function highlightDups(){
var classes = [] ;
$('ul[class^="list"]').each(function(k,v){
//alert(v.innerHTML);
$($(this).children()).each(function(nK,nV){
// alert($(this).attr("class"));
classes.push($(this).attr("class"));
});
});
hasDuplicate(classes);
}
//Find duplicate picked from fastest way to detect if duplicate entry exists in javascript array?
function hasDuplicate(arr) {
var i = arr.length, j, val;
while (i--) {
val = arr[i];
j = i;
while (j--) {
if (arr[j] === val) {
// you can write your code here to handle when you find a match
$("."+val).text("This is Duplicate").addClass("match");
}
}
}
}
A slightly less verbose variant of Nix's answer:
$("ul.listA li").each(function(){
var a = $("ul.listB li").filter("." + $(this).attr('class'));
if (a.size()) {
a.add($(this)).css("background", "red");
}
});