Efficient way of hiding elements with certain classes $.each, for, etc - javascript

I have an array populated with classes. I need to loop across this array and hide any elements with that particular class.
// Array of classes
// hide.length ~ 100
This is my current implemntation:
// Hide all elements with these class names
$.each(hide, function(key, filter_class){
$('li.'+filter_class, '.result_row_items').hide();
});
I believe this would be a more efficient (performance wise) way:
for(i=0;i<hide.length;i++){
$('li.'+hide[i], '.result_row_items').hide();
}
Would this be even better?
// Create string of class names
var classes = '';
for(i=0;i<hide.length;i++){
classes += 'li.'+ hide[i] + ', '
}
// Remove trailing comma and space
classes = classes.substring(0, classes.length - 2);
$(classes, '.result_row_items').hide();

How about something like that?
$("li." + hide.join(",li."), ".result_row_items").hide();
DEMO: http://jsfiddle.net/B9fXP/

Maybe something like this?
$(hide).filter('.class').hide();
or
for (var i = 0; class = classes[i++];) {
$('li.'+ class).hide();
}

Related

JS. How to get list of div's with similar class name?

I have html, like this:
<div id="c0" class="bz_comment bz_first_comment"></div>
<div id="c1" class="bz_comment"></div>
<div id="c2" class="bz_comment"></div>
<div class="bz_add_comment"></div>
How can I get array of all the div's (3 div in example) by class that's starts with "bz_comment[anysymbols]" in JavaScript (not using JQuery)?
Or can i get array of div's by id that's starts with "c[numeric_value]"?
[numeric_value_can_consist_of_some_numbers]
It's the similar question like stackoverflow.com/questions/1225611/ (but i don't have reputation to ask in that question). Thanks in advance.
You should use .querySelectorAll
var matching = document.querySelectorAll('[class*="bz_comment"]')
I see some worrying things in your code though:
You have sequential numeric IDs, consider using an Array to represent sequential data instead.
You are selecting things by class name identifiers, if you must do this - use a data-* attribute instead. Better yet, store the elements in an array instead and have a direct reference to them.
You can write a function to process elements on the page that contain the class you're looking for:
function containsClass(matchClassName) {
var matches = new Array();
var elems = document.getElementsByTagName('div'), i;
for (i in elems) {
if((' ' + elems[i].className + ' ').indexOf(' ' + matchClassName + ' ') > -1) {
matches.push(elems[i]);
}
}
return matches;
}
now you can write
var matches = containsClass('bz_comment');

jQuery: Getting "secondary" class

I'm using jQuery to loop through some elements in a document. These elements are of type <tr> with class .input-row. Some of the elements can also have a secondary class (for example .input-area).
I use $(".input-row").each() to loop through the elements, but how can I determine if the $(this)-element has a "secondary" class and if so, get the name of this?
$(".input-row").each(function(){
$.each($(this).attr('class').split(/\s+/), function(i, v){
if(v !== 'input-row'){
alert(v);
}
});
});
You can get the list of all classes using attr, and you could simply get rid of the the class you used to select the elements:
$(".input-row").each(function() {
var allClasses = $(this).attr("class"),
otherClasses = allClasses.replace("input-row", "");
});
If the element has more than two classes, then you will be left with a list of the other classes. To separate them, you could split on the spaces.
You can get all the classes on the element and then remove the one you know exists('input-row'), then you will be left with any other classes on that element.
$('.input-row').each(function() {
var classes = $.trim($(this).attr('class').replace('input-row', ''));
if (classes.length > 1) {
alert(classes) // Names of all of the remaining classes
}
}
If you want to get them individually, you can do classes.split(' ') to get an array.
I prefer a declarative approach. You know which classes there can be, so write cases for them:
$(".input-row.input-area").each( /* ... */ );
$(".input-row.input-field").each( /* ... */ );
If you for some reason don't know the class name, you can extract it along the lines of:
$(".input-row").each(function () {
var myClasses = this.className.split(" ");
$.each(myClasses, function (i, className) {
if (className != 'input-row') {
alert(className);
}
});
});
I'd go for this
var otherClasses = $('.input-row').attr('class').split(' ');
otherClasses.splice($.inArray("input-row", otherClasses),1);
Simply doing this
var otherClasses = $('.input-row').attr('class').replace('input-row', '').split(' ');
Will give you an extra string in the array with an empty value in it, because of the space behind "input-row"
You could also do something like this to detect the number of classes:
var nc = $('#myId').attr('class').split(' ').length;
Then if nc is greater than 1:
$('#myID').attr('class').split(' ')[1]
should return the 'secondary' class
See a fiddle

select an array of elements and use them

Using this syntax:
var position = array($('#ipadmenu > section').attr('data-order'));
I cannot get my code to work. I have never used arrays before so im kind of lost on how to use them. (especially in jquery).
How would I make an array of all section elements and associate the value of data-order to that list. Example:
first section - data-order:1
second section - data-order:2
etc and then use that info afterwards.
Thank you!
Since .attr just gets one attribute -- the first one found by the jQuery selector -- you need to build your array element by element. One way to do that is .each (you can also use .data to extract data attributes):
var position = new Array;
$('#ipadmenu > section').each(function() {
position.push($(this).data('order'));
});
alert(position[0]); // alerts "1"
This will be an indexed array, not an associative array. To build one of those (which in JavaScript is technically an object, not any kind of array) just change the inner part of your .each loop:
var position = {};
$('#ipadmenu > section').each(function(i) {
position["section"+i] = $(this).data('order');
});
The resulting object position can now be accessed like:
alert(position['section1']); // alerts "1"
A different approach involves using jQuery.map, but since that only works on arrays, not jQuery objects, you need to use jQuery.makeArray to convert your selection into a true array first:
var position = $.map($.makeArray($('#ipadmenu > section')), function() {
return $(this).data('order');
} ); // position is now an indexed array
This approach is technically shorter than using .each, but I find it less clear.
Javascript:
var orders = [];
$('#ipadmenu > section').each(function() {
orders.push($(this).data('order'))
});
HTML:
<div id="ipadmenu">
<section data-order="1">1</section>
<section data-order="2">2</section>
</div>
You will want to do something like this:
// Get the elements and put them in an array
var position = $('#ipadmenu section').toArray();
console.log(position);
// Loop through the array
for (var i = 0; i < position.length; i++){
// Display the attribute value for each one
console.log("Section " + i + ": " + $(position[i]).attr('data-order'));
}
Working example here: http://jsfiddle.net/U6n8E/3/

Removing a class from an HTML element using JavaScript

I am attempting to remove a class from an html tag using JavaScript but I have no idea where to start. I have searched but to no avail. While I am decently fluent in jQuery, I am not in JavaScript and I need to use JavaScript in this instance Anything I have found thus far would need to be adjusted for my own use, which I have not been successful at. Hopefully someone can explain it in a fool-proof way.
The element the class is attached to is the "ul" tag. The class is named "nojavaScript" and is only applied to this single instance of the "ul" tag. While as I said the class is only used once in the page, the "ul" tag is used in other instances with different classes or ids.
If it would make it easier for the JavaScript, I can change the class to an id.
I hope I have given you enough to go on. I will include an example of the html code below.
<ul id="lines_list" class="nojavaScript"></ul>
As I mentioned, if it's easier to remove an id than a class, I can make the current id a class, and the current class an id. But essentially it's the "nojavaScript" that needs to be removed.
Thanks!
Here's a pure js solution:
var ulArr = document.getElementsByClassName('nojavaScript');
for (var i = 0; i < ulArr.length; i++) {
ulArr[i].className = ulArr[i].className.replace('nojavaScript','');
}
First you select all elements with the given class name, then iterate over the result and replace the given class in the className attribute with an empty string.
UPDATE:
Here's a more robust solution that turns the removal into a parameterized function and handles stripping extra whitespaces from the beginning, end, and middle of the className attribute.
function removeClass(elem, className) {
//declare some regexes to help us strip the extra whitespace
var trimLeft = /^\s+/,
trimRight = /\s+$/,
stripDouble = /\s+/g;
//remove the class, strip extra whitespace, and reassign className
elem.className = elem.className.replace(className, '').replace(trimLeft, '').replace(trimRight, '').replace(stripDouble, ' ');
}
//declare name of class to remove and get an array of elements with that class
var toRemove = 'nojavaScript',
elArr = document.getElementsByClassName(toRemove);
//iterate over elements and remove the class
for (var i = 0; i < elArr.length; i++) {
removeClass(elArr[i], toRemove);
}
Here's a live demo ->
try this:
document.getElementById("lines_list").className = "";
function removeCSSClass(element, className) {
var cssClass = ' ' + element.className + ' ';
var index = cssClass.indexOf(' ' + className + ' ');
if (index >= 0) {
var newClass = cssClass.substr(0, index) + ' ' + cssClass.substr(index + className.length + 1);
element.className = newClass;
}
}
UPDATE: code now works in all occassions
function removeClassFromElement(el,className){
var classes = el.getAttribute('class').split(/[ ]+/g);
var class = "";
for(var i in classes)
if(classes[i] != className)
class += classes[i] + " ";
el.setAttribute('class',class);
}
removeClassFromElement(document.getElementById('lines_list'),'nojavaScript');
Here's a non regex method that is considerate of multiple classes on an element.
function removeClass(element, cssClass) {
var classes = element.className.split(' ');
var j = classes.length;
while (j--) {
if (classes[j] === cssClass) {
classes.splice(j, 1);
}
}
element.className = classes.join(' ');
}
var lines_list = document.getElementById('lines_list');
removeClass(lines_list, 'nojavaScript');
It splits on spaces to isolate whole class names whereas doing a simple search for the class name string and replacing with nothing might eat part of a longer class name.
Class name modification should be done on the className property with a RegExp replace to avoid clobbering other classNames which should stay:
var ele = document.getElementById( 'lines_list' );
ele.className = ele.className.replace( /(?:^|\s)nojavaScript(?:\s|$)/gm, ' ' );
http://jsfiddle.net/JAAulde/nWzaZ/3/
(genercized class names: http://jsfiddle.net/JAAulde/nWzaZ/2/ )
Without this regex, you either wipe the entire className, or you overkill and possibly take out a portion of foonojavaScript as well (you know, if you had such an odd class :P ). While this might not really be likely, it's good practice for when you run into code that might not be as specific.
This solution allows you to have as many classes on the element as you want, as similar as you desire, without worry of how you format them other than as specified by the W3C. No maintenance issues :).
(The RegExp specifically looks for your class preceded by start of string or white-space, and followed by white-space or end of string)
(This assumes you already have a handle on how to get the element(s) from the DOM in the first place.)

Get class list for element with jQuery

Is there a way in jQuery to loop through or assign to an array all of the classes that are assigned to an element?
ex.
<div class="Lorem ipsum dolor_spec sit amet">Hello World!</div>
I will be looking for a "special" class as in "dolor_spec" above. I know that I could use hasClass() but the actual class name may not necessarily be known at the time.
You can use document.getElementById('divId').className.split(/\s+/); to get you an array of class names.
Then you can iterate and find the one you want.
var classList = document.getElementById('divId').className.split(/\s+/);
for (var i = 0; i < classList.length; i++) {
if (classList[i] === 'someClass') {
//do something
}
}
jQuery does not really help you here...
var classList = $('#divId').attr('class').split(/\s+/);
$.each(classList, function(index, item) {
if (item === 'someClass') {
//do something
}
});
Why has no one simply listed.
$(element).attr("class").split(/\s+/);
EDIT: Split on /\s+/ instead of ' ' to fix #MarkAmery's objection. (Thanks #YashaOlatoto.)
On supporting browsers, you can use DOM elements' classList property.
$(element)[0].classList
It is an array-like object listing all of the classes the element has.
If you need to support old browser versions that don't support the classList property, the linked MDN page also includes a shim for it - although even the shim won't work on Internet Explorer versions below IE 8.
Here is a jQuery plugin which will return an array of all the classes the matched element(s) have
;!(function ($) {
$.fn.classes = function (callback) {
var classes = [];
$.each(this, function (i, v) {
var splitClassName = v.className.split(/\s+/);
for (var j = 0; j < splitClassName.length; j++) {
var className = splitClassName[j];
if (-1 === classes.indexOf(className)) {
classes.push(className);
}
}
});
if ('function' === typeof callback) {
for (var i in classes) {
callback(classes[i]);
}
}
return classes;
};
})(jQuery);
Use it like
$('div').classes();
In your case returns
["Lorem", "ipsum", "dolor_spec", "sit", "amet"]
You can also pass a function to the method to be called on each class
$('div').classes(
function(c) {
// do something with each class
}
);
Here is a jsFiddle I set up to demonstrate and test http://jsfiddle.net/GD8Qn/8/
Minified Javascript
;!function(e){e.fn.classes=function(t){var n=[];e.each(this,function(e,t){var r=t.className.split(/\s+/);for(var i in r){var s=r[i];if(-1===n.indexOf(s)){n.push(s)}}});if("function"===typeof t){for(var r in n){t(n[r])}}return n}}(jQuery);
You should try this one:
$("selector").prop("classList")
It returns a list of all current classes of the element.
var classList = $(element).attr('class').split(/\s+/);
$(classList).each(function(index){
//do something
});
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})
Update:
As #Ryan Leonard pointed out correctly, my answer doesn't really fix the point I made my self... You need to both trim and remove double spaces with (for example) string.replace(/ +/g, " ").. Or you could split the el.className and then remove empty values with (for example) arr.filter(Boolean).
const classes = element.className.split(' ').filter(Boolean);
or more modern
const classes = element.classList;
Old:
With all the given answers, you should never forget to user .trim() (or $.trim())
Because classes gets added and removed, it can happen that there are multiple spaces between class string.. e.g. 'class1 class2 class3'..
This would turn into ['class1', 'class2','','','', 'class3']..
When you use trim, all multiple spaces get removed..
Might this can help you too. I have used this function to get classes of childern element..
function getClickClicked(){
var clickedElement=null;
var classes = null;<--- this is array
ELEMENT.on("click",function(e){//<-- where element can div,p span, or any id also a class
clickedElement = $(e.target);
classes = clickedElement.attr("class").split(" ");
for(var i = 0; i<classes.length;i++){
console.log(classes[i]);
}
e.preventDefault();
});
}
In your case you want doler_ipsum class u can do like this now calsses[2];.
Thanks for this - I was having a similar issue, as I'm trying to programatically relate objects will hierarchical class names, even though those names might not necessarily be known to my script.
In my script, I want an <a> tag to turn help text on/off by giving the <a> tag [some_class] plus the class of toggle, and then giving it's help text the class of [some_class]_toggle. This code is successfully finding the related elements using jQuery:
$("a.toggle").toggle(function(){toggleHelp($(this), false);}, function(){toggleHelp($(this), true);});
function toggleHelp(obj, mode){
var classList = obj.attr('class').split(/\s+/);
$.each( classList, function(index, item){
if (item.indexOf("_toggle") > 0) {
var targetClass = "." + item.replace("_toggle", "");
if(mode===false){$(targetClass).removeClass("off");}
else{$(targetClass).addClass("off");}
}
});
}
Try This. This will get you the names of all the classes from all the elements of document.
$(document).ready(function() {
var currentHtml="";
$('*').each(function() {
if ($(this).hasClass('') === false) {
var class_name = $(this).attr('class');
if (class_name.match(/\s/g)){
var newClasses= class_name.split(' ');
for (var i = 0; i <= newClasses.length - 1; i++) {
if (currentHtml.indexOf(newClasses[i]) <0) {
currentHtml += "."+newClasses[i]+"<br>{<br><br>}<br>"
}
}
}
else
{
if (currentHtml.indexOf(class_name) <0) {
currentHtml += "."+class_name+"<br>{<br><br>}<br>"
}
}
}
else
{
console.log("none");
}
});
$("#Test").html(currentHtml);
});
Here is the working example: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/
For getting the list of classes applied to element we can use
$('#elementID').prop('classList')
For adding or removing any classes we can follow as below.
$('#elementID').prop('classList').add('yourClassName')
$('#elementID').prop('classList').remove('yourClassName')
And for simply checking if the class is present or not we can use hasClass
I had a similar issue, for an element of type image. I needed to check whether the element was of a certain class. First I tried with:
$('<img>').hasClass("nameOfMyClass");
but I got a nice "this function is not available for this element".
Then I inspected my element on the DOM explorer and I saw a very nice attribute that I could use: className. It contained the names of all the classes of my element separated by blank spaces.
$('img').className // it contains "class1 class2 class3"
Once you get this, just split the string as usual.
In my case this worked:
var listOfClassesOfMyElement= $('img').className.split(" ");
I am assuming this would work with other kinds of elements (besides img).
Hope it helps.
javascript provides a classList attribute for a node element in dom. Simply using
element.classList
will return a object of form
DOMTokenList {0: "class1", 1: "class2", 2: "class3", length: 3, item: function, contains: function, add: function, remove: function…}
The object has functions like contains, add, remove which you can use
A bit late, but using the extend() function lets you call "hasClass()" on any element, e.g.:
var hasClass = $('#divId').hasClass('someClass');
(function($) {
$.extend({
hasClass: new function(className) {
var classAttr = $J(this).attr('class');
if (classAttr != null && classAttr != undefined) {
var classList = classAttr.split(/\s+/);
for(var ix = 0, len = classList.length;ix < len;ix++) {
if (className === classList[ix]) {
return true;
}
}
}
return false;
}
}); })(jQuery);
The question is what Jquery is designed to do.
$('.dolor_spec').each(function(){ //do stuff
And why has no one given .find() as an answer?
$('div').find('.dolor_spec').each(function(){
..
});
There is also classList for non-IE browsers:
if element.classList.contains("dolor_spec") { //do stuff

Categories

Resources