finding elements with z-index - javascript

I was working on an issue in which I was looping through same controls placed on a single page and assigning a z-index to them.
I want to get a collection of all the elements which currently have the z index defined either directly in html or using css, and then iterate over them top to bottom and assign their z-index using JQuery.
What would the selector for this look like, and how performant would it be?

There is no specific selector to achieve this, so you would need to use filter() like this:
var zIndex = 5;
var $zElements = $('.selector').filter(function() {
return $(this).css('z-index') == zIndex;
});
$zElements.each(function() {
// loop through the elements with a matching z-index
});

Related

documents get elements by classname apply to all element

I am new to JS. I want to change css for all elements selected by className. I did some search and I found the solution below. But, it will only affect the first element. I am wondering if there is a easy to to change the css for all selected elements.
document.getElementsByClassName('ads')[0].style.display = 'none';
document.getElementsByClassName('class')[x]
may be x can be 0,1,2,... depends on elements with that class if there two div with ads
class you will count from 0 as the first div with that class because it returns in array
or you can use tag name while you are selecting
document.getElementsByTagName('div')[x]
this also returns in array because in html suppose to be many similar tags means that you have to index to them
document.getElementById('id')
this is selecting by using the tag's id and an id there a tag with an id should be the unique thats why this doesn't return in array means that you don't need to index on it
document.querySelectorAll('p .class')[x]
with selector you do it like you do in css but it returns in array to and also you can apply the pseudo classes and elements
document.querySelector('p .class')
this used like the above one but it didn't return in array so you don't have to index on it
NodeList.prototype.forEach = NodeList.prototype.forEach || Array.prototype.forEach;
document.querySelectorAll('.ads').forEach(ele => {ele.style.display = 'none'});
This should do it. The querySelectorAll-method returns you a Nodelist from a given css-selector. The first line checks if there is already a forEach method and if not it will inherit it from the Array Object.
You can also read about the from method of the Array object this could be a more cleaner version.
You need to use loop, please check snippet
NOTE: I added '.hide' class and set background color just to display result. you just add display:none in CSS
window.onload = function() {
var ads = document.getElementsByClassName("ads"),
len = ads !== null ? ads.length : 0,
i = 0;
for(i; i < len; i++) {
ads[i].className += " hide";
}
}
.hide {
background: skyblue;
}
<div class="ads">1</div>
<div class="ads">2</div>
Simple with jQuery method :
$('.ads:first').hide();
$('.ads:first').css("display":"none");
To using jQuery, you have to add jQuery plugin inside <body> tag before jQuery function call :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

Select the child[ren] of an element as one would select the descendant[s]

Say I have an HTMLElement:
var hoop = otherLibrary.getHoop()
I can select its descentant[s] that are .stripey:
var stripedOnes = hoop.querySelectorAll('.stripey')
This is like the CSS rule:
#hoop .stripey {
However, how do I do the same for child[ren], without using jQuery?
var stripedChildren = hoop.querySelectorAll('> .stripey')
Doesn't work, although in jQuery/Sizzle it does. What would be the JS equivalent of this CSS rule?
#hoop > .stripey {
Well, the most straightforward way would be to use the full selector inside querySelectorAll()
document.querySelectorAll("#hoop > .stripey");
But, if answering your specific question...
I believe the fanciest way to select an element's children based on a selector is:
turn the .children collection into an array
Filter each element testing it against a selector using .matches()
So:
var hoop = document.getElementById("hoop");
var stripedChildren = [].slice.call(hoop.children).filter(function(element) {
return element.matches(".stripey");
});
You can use following -
document.querySelectorAll("#hoop > .stripey");

Jquery each and Selector behaving differently

I created a function in Jquery which is supposed to center elements vertically (I could not do it using css, got tired and just made it programically ^^). The problem now is that I initially created it using .each, and then, since it was already creator, I tried calling it using the selector ($('something').center), but it is behaving differently for some reason.
Using the selector, it seems to be doing just the same to every element. It does it with the first element, and then just applies all values to the remaining elements. So, for example, my function takes the element height and does some operations with it, but the selector just takes the first one and then applies its parameters to everyone..
I'll keep using each since it works best right now, but I still can't understand why they are doing that..
Centering Function:
$.fn.center = function (){
/*If this is the highest element, or
if this element has full use of the width,
then there's no need to align it.
*/
if(this.height() == this.parent().height() ||
this.width() == this.parent().width())
{
this.css({
position : "relative",
top : 0
});
}
else //Should be aligned.
{
this.css({
position : "relative",
top : (this.parent().height()/2)-(this.height()/2)
});
}
return this; //Used for chaining.
};
Here's an example of what I mean ^^
http://jsfiddle.net/lrojas94/pmbttrt2/1/
For simple things, like just changing the CSS in the same way for all elements with the same class, you can call it directly without using .each(). For example:
$('.elem').css('color', '#fff');
But if each of the divs needs to end up with an individual value, you should use .each(). For example (sorry it's a bit weird):
var border = 1;
$('.elem').each(function() {
$(this).css('border', border + 'px solid #000');
border += 1;
});
Basically, if you don't use .each(), it'll check what you want to change (just once!) and apply it to all elements with that class. If you do use .each(), it'll do it individually for each element.
Simply put, this within a jQuery plugin function is not a DOM node. It's the jQuery object that wraps around all the nodes that were matched by the selector.
Your function's body should rather look like:
return this.each(function () {
var $el = $(this);
//centering logic for $el goes here
});

JQuery Event Listeners in a For Loop

I am trying to create some basic button rollover functionality using Jquery and toggleClass. I am building a list of elements by cloning a DIV from my HTML and duplicating it multiple times (its populating a list of data from a database). To do this I am using a for loop. Here is the currently working code.
var displayNode = document.getElementById('phoneDisplayContainer');
for(var i=0; i<length; i++) {
//Clone the original container display.
var clonedDisplay = displayNode.cloneNode(true);
clonedDisplay.setAttribute('id', 'phoneDisplayContainer' + i);
//Remove hidden class from cloned Element. NOT CROSS BROWSER!
clonedDisplay.classList.remove('hidden');
var children = clonedDisplay.getElementsByTagName('div');
//Fill new nodes children containers with data.
children[1].innerHTML = contact.phone[i].type;
children[2].innerHTML = contact.phone[i].number;
children[3].setAttribute('onclick', 'PhoneUtility.edit(' + i + ');');
children[3].setAttribute('id', 'phoneEditDisplay' + i);
children[4].setAttribute('onclick', 'PhoneUtility.remove(' + i + ');');
//Hidden elements
var hidden = new Array(children[3], children[4]);
//Set rollover events.
clonedDisplay.setAttribute('onmouseover', '$("#' + children[3].id + '").toggleClass("hidden");');
clonedDisplay.setAttribute('onmouseout', '$("#' + children[3].id + '").toggleClass("hidden");');
//Append the new node to the display container
phoneContainer.appendChild(clonedDisplay);
}
}
Is there a way to use Jquery event listeners instead of having to set onmouseover and onmouseout directly on the element?
I tried this:
$(clonedDisplay).mouseover(function() {
$(children[3]).toggleClass('hidden');
});
With no luck. It just displays performs the rollover effect on the last element in the list. This is actually my first attempt at using jQuery so any other suggestions to ways I could jQuery inside the code would be helpful too.
EDIT: I'd also like to toggle multiple children from the arraylist mentioned in the for loop. How would I set this up? I can't seem to pass an array to the jquery command without getting errors.
The following code after your for loop should let you assign all the mouseover and mouseout handlers in one go to apply to all the clones:
$('div[id^="phoneDisplayContainer"]').mouseover(function() {
$(this).find("div").eq(3).toggleClass("hidden");
}).mouseout(function() {
$(this).find("div").eq(3).toggleClass("hidden");
});
// or, given that both handlers do the same thing:
$('div[id^="phoneDisplayContainer"]').on("mouseover mouseout", function() {
$(this).find("div").eq(3).toggleClass("hidden");
})
(If you're using jQuery older than 1.7 use .bind() instead of .on().)
The above says to find all the divs with an id beginning with "phoneDisplayContainer" and assign event handlers. Within the handler, find the fourth descendant div and toggle the class.
You don't show your HTML or CSS, but you could do this all in your CSS if you like. Assuming you can assign a common class ("parentDiv") to the divs that you want to trap the hover event on, and a common class ("childDiv") to their child div (the one to be hidden), you can do this:
.parentDiv .childDiv { visibility: hidden; }
.parentDiv:hover .childDiv { visibility: visible; }
(Obviously you can give more meaningful class names to fit your structure.)
Otherwise, again if you can assign those classes to the appropriate divs then after your loop you can do this with jQuery:
$(".parentDiv").on("mouseover mouseout", function() {
$(this).find(".childDiv").toggleClass('hidden');
});
Basically the same as what I said initially, but using classes for selectors. If you feel like I'm pushing a class-based solution on you that's because I am: it tends to make this sort of thing much easier.

Remove all classes except one

Well, I know that with some jQuery actions, we can add a lot of classes to a particular div:
<div class="cleanstate"></div>
Let's say that with some clicks and other things, the div gets a lot of classes
<div class="cleanstate bgred paddingleft allcaptions ..."></div>
So, how I can remove all the classes except one? The only idea I have come up is with this:
$('#container div.cleanstate').removeClass().addClass('cleanstate');
While removeClass() kills all the classes, the div get screwed up, but adding just after that addClass('cleanstate') it goes back to normal. The other solution is to put an ID attribute with the base CSS properties so they don't get deleted, what also improves performance, but i just want to know another solution to get rid of all except ".cleanstate"
I'm asking this because, in the real script, the div suffers various changes of classes.
Instead of doing it in 2 steps, you could just reset the entire value at once with attr by overwriting all of the class values with the class you want:
jQuery('#container div.cleanstate').attr('class', 'cleanstate');
Sample: http://jsfiddle.net/jtmKK/1/
Use attr to directly set the class attribute to the specific value you want:
$('#container div.cleanstate').attr('class','cleanstate');
With plain old JavaScript, not JQuery:
document.getElementById("container").className = "cleanstate";
Sometimes you need to keep some of the classes due to CSS animation, because as soon as you remove all classes, animation may not work. Instead, you can keep some classes and remove the rest like this:
$('#container div.cleanstate').removeClass('removethis removethat').addClass('cleanstate');
regarding to robs answer and for and for the sake of completeness you can also use querySelector with vanilla
document.querySelector('#container div.cleanstate').className = "cleanstate";
What if if you want to keep one or more than one classes and want classes except these. These solution would not work where you don't want to remove all classes add that perticular class again.
Using attr and removeClass() resets all classes in first instance and then attach that perticular class again. If you using some animation on classes which are being reset again, it will fail.
If you want to simply remove all classes except some class then this is for you.
My solution is for: removeAllExceptThese
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;});
};
$.fn.removeClassesExceptThese = function(classList) {
/* pass mutliple class name in array like ["first", "second"] */
var $elem = $(this);
if($elem.length > 0) {
var existingClassList = $elem.attr("class").split(' ');
var classListToRemove = existingClassList.diff(classList);
$elem
.removeClass(classListToRemove.join(" "))
.addClass(classList.join(" "));
}
return $elem;
};
This will not reset all classes, it will remove only necessary.
I needed it in my project where I needed to remove only not matching classes.
You can use it $(".third").removeClassesExceptThese(["first", "second"]);

Categories