How to select elements by CSS property value using JavaScript - javascript

I need to get the count of all elements on the page which have display property set to block.
But I don't have to use JQuery I need to do it in pure JavaScript

In a comment you've said:
I have a list of items(li elements) on the html and I need to get the count of all li elements which have display property block
and
the elements are styled from an external css file
This means you'll have to individually check each element with getComputedStyle (or on obsolete versions of IE, currentStyle).
You said you have a list, so if I assume you have a NodeList or HTMLCollection, we can use Array.prototype.reduce:
var count = Array.prototype.reduce.call(yourList, function(count, element) {
return count + (getComputedStyle(element).display === "block" ? 1 : 0);
}, 0);
If you have to support obsolete versions of IE, you'll want to check for currentStyle:
var getStyle = window.getComputedStyle || function getStyle(element) {
return element.currentStyle;
};
var count = Array.prototype.reduce.call(yourList, function(count, element) {
return count + (getStyle(element).display === "block" ? 1 : 0);
}, 0);
If you need a list of them rather than just the count (you've said "count," but...), use filter instead:
var getStyle = window.getComputedStyle || function getStyle(element) {
return element.currentStyle;
};
var filtered = Array.prototype.filter.call(yourList, function(element) {
return getStyle(element).display === "block";
});

Please try it:
const elementsWithDisplayBlockProperty = []
document.querySelectorAll("body *").forEach(element => {
window.getComputedStyle(element).getPropertyValue("display") === "block" && elementsWithDisplayBlockProperty.push(element)
})
console.log(elementsWithDisplayBlockProperty) // result

Related

how to obtain the list of internal browser css for button in jquery [duplicate]

Here's how you get one css attribute using jQuery:
$('someObject').css('attribute')
How do you get them all? (without specifying and preferably in the following format so it can be reapplied with jQuery later):
cssObj = {
'overflow':'hidden',
'height':'100%',
'position':'absolute',
}
Thanks!!
EDIT
The methods I'm trying to get are declared in a style sheet (they are not inline). Sorry for not specifying.
See this live example using the jQuery attribute selector
$(document).ready(function() {
alert($("#stylediv").attr('style'));
});​
What about something like this:
jQuery CSS plugin that returns computed style of element to pseudo clone that element?
It is ugly, but it appeared to work for the poster...
This also may be of interest:
https://developer.mozilla.org/en/DOM:window.getComputedStyle
Not sure how cross-browser this one is, but it works in Chrome -
https://gist.github.com/carymrobbins/223de0b98504ac9bd654
var getCss = function(el) {
var style = window.getComputedStyle(el);
return Object.keys(style).reduce(function(acc, k) {
var name = style[k],
value = style.getPropertyValue(name);
if (value !== null) {
acc[name] = value;
}
return acc;
}, {});
};
window.getComputedStyle(element);
// For example
var element = document.getElementById('header');
window.getComputedStyle(element);
For a platform (the name is subject to nondisclosure) where the Chrome or Safari DevTools/WebInspector are not available, and you need to dump the styles to the log.
dumpCssFromId (id) {
const el = document.getElementById(id);
const styles = window.getComputedStyle(el);
return Object.keys(styles).forEach((index) => {
const value = styles.getPropertyValue(index);
if (value !== null && value.length > 0) {
console.log(`style dump for ${id} - ${index}: ${value}`);
}
}, {});
}

How to check for attribute value

Please advise me if I am using correct syntax here for checking if “aria-expanded” is true for a particular set of elements with css class “classname”:
if ($(‘.classname’).hasAttribute('aria-expanded','true')) {
 output here
}
jQuery doesn't have a hasAttribute method, so I'm assuming $ = docuument.querySelector. (Note: not document.querySelectorAll; so, you're only considering a single element).
The hasAttribute method takes a single parameter: the name of the attribute you are checking for. To check that attribute's value, you'll need to use getAttribute and then compare that. So you might do:
if( $('.classname').getAttribute('aria-expanded') === 'true') {}
If you are using jQuery, then you can just use the attr method:
if ($('.classname').attr('aria-expanded') === 'true') {}
See also the MDN docs for hasAttribute.
If you're trying to check a set of elements, you could do something like this:
function allHaveAttribute(elements, attrName, attrValue) {
// First, check that all elements have the attribute
for (var i = 0; i < elements.length; i++) {
if (!elements[i].hasAttribute(attrName)) return false;
}
if (attrValue) { // if we're checking their value...
for (var i = 0; i < elements.length; i++) {
if (elements[i].getAttribute(attrName) !== attrValue)
return false;
}
return true;
} else { // we know all elements have the attribute
return true;
}
}
var els = document.querySelectorAll('.classname');
if (allHaveAttribute(els, 'aria-expanded', 'true') {
// action here
}
JSBin Example: http://jsbin.com/payaqijeqa/edit?js,console
jQuery doesn't have a .hasAttribute function
If it did, it would most likely only work on the first of the set
The following uses native JavaScript (ES5) to check that .every element in the set document.querySelectorAll('.classname') has that attribute set to true.
let allSet = [].every.call(document.querySelectorAll('.classname'), function(el) {
return el.getAttribute('aria-expanded') === 'true';
});
NB: the above test is case sensitive. It also ignore any elements that don't have that attribute at all. If the latter is an issue:
let allSet = [].every.call(document.querySelectorAll('.classname'), function(el) {
return el.hasAttribute('aria-expanded') && el.getAttribute('aria-expanded') === 'true';
});
You can check to see if every element with class "className" has the attribute "aria-expanded='true'" with:
if( $(".className").length === $(".className").filter("[aria-expanded='true']").length) {
//output here
}
CSS has attribute selectors that allow selection of elements with certain attributes. If you negate the selector (which is unique to jQuery), you can test if there are any elements that have the class but don't have the attribute value by using:
$(".className[aria-expanded!='true']").length == 0

Find maximum z index on a page or in a container [duplicate]

I have a number of div elements with different z-index. And I want to find the highest z-index among these divs - how can I achieve it?
CSS:
#layer-1 { z-index: 1 }
#layer-2 { z-index: 2 }
#layer-3 { z-index: 3 }
#layer-4 { z-index: 4 }
HTML:
<div id="layer-1">layer-1</div>
<div id="layer-2">layer-2</div>
<div id="layer-3">layer-3</div>
<div id="layer-4">layer-4</div>
I don't think this line can find the highest z-index though.
var index_highest = parseInt($("div").css("zIndex"));
// returns 10000
Note that z-index only affects positioned elements. Therefore, any element with position: static will not have a z-index, even if you assign it a value. This is especially true in browsers like Google Chrome.
var index_highest = 0;
// more effective to have a class for the div you want to search and
// pass that to your selector
$("#layer-1,#layer-2,#layer-3,#layer-4").each(function() {
// always use a radix when using parseInt
var index_current = parseInt($(this).css("zIndex"), 10);
if(index_current > index_highest) {
index_highest = index_current;
}
});
JSFiddle demo
A general jQuery selector like that when used with an option that returns one value will merely return the first So your result is simply the z-index of the first div that jQuery grabs. To grab only the divs you want, use a class on them. If you want all divs, stick with div.
Here is a very concise method:
var getMaxZ = function(selector){
return Math.max.apply(null, $(selector).map(function(){
var z;
return isNaN(z = parseInt($(this).css("z-index"), 10)) ? 0 : z;
}));
};
Usage:
getMaxZ($("#layer-1,#layer-2,#layer-3,#layer-4"));
Or, as a jQuery extension:
jQuery.fn.extend({
getMaxZ : function(){
return Math.max.apply(null, jQuery(this).map(function(){
var z;
return isNaN(z = parseInt(jQuery(this).css("z-index"), 10)) ? 0 : z;
}));
}
});
Usage:
$("#layer-1,#layer-2,#layer-3,#layer-4").getMaxZ();
Besides #justkt's native solution above, there is a nice plugin to do what you want.
Take a look at TopZIndex.
$.topZIndex("div");
Try this :
var index_highest = 0;
$('div').each(function(){
var index_current = parseInt($(this).css("z-index"), 10);
if(index_current > index_highest) {
index_highest = index_current;
}
});
This would do it:
$(document).ready(function() {
var array = [];
$("div").each(function() {
array.push($(this).css("z-index"));
});
var index_highest = Math.max.apply(Math, array);
alert(index_highest);
});
Try this
This is taken directly from jquery-ui, it works really well:
(function ($) {
$.fn.zIndex = function (zIndex) {
if (zIndex !== undefined) {
return this.css("zIndex", zIndex);
}
if (this.length) {
var elem = $(this[ 0 ]), position, value;
while (elem.length && elem[ 0 ] !== document) {
// Ignore z-index if position is set to a value where z-index is ignored by the browser
// This makes behavior of this function consistent across browsers
// WebKit always returns auto if the element is positioned
position = elem.css("position");
if (position === "absolute" || position === "relative" || position === "fixed") {
// IE returns 0 when zIndex is not specified
// other browsers return a string
// we ignore the case of nested elements with an explicit value of 0
// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
value = parseInt(elem.css("zIndex"), 10);
if (!isNaN(value) && value !== 0) {
return value;
}
}
elem = elem.parent();
}
}
return 0;
}
})(jQuery);
I don't know how efficient this is, but you can use $.map to get all the z-indices:
var $divs = $('div'),
mapper = function (elem) {
return parseFloat($(elem).css('zIndex'));
},
indices = $.map($divs, mapper);
The indices variable is now an array of all the z-indices for all the divs. All you'd have to do now is apply them to Math.max:
var highest = Math.max.apply(whatevs, indices);
Here how I got both lowest/highest z-indexes. If you only want to get the highest z-index and nothing more, then this function may not efficient, but if you want to get all z-indexes and the ids associated with it (i.e. for use with bring 'layer' to front/send to back, bring forward, send backward, etc), this is one way to do it. The function returns an array of objects containing ids and their z-indexes.
function getZindex (id) {
var _l = [];
$(id).each(function (e) {
// skip if z-index isn't set
if ( $(this).css('z-index') == 'auto' ) {
return true
}
_l.push({ id: $(this), zindex: $(this).css('z-index') });
});
_l.sort(function(a, b) { return a.zindex - b.zindex });
return _l;
}
// You'll need to add a class 'layer' to each of your layer
var _zindexes = getZindex('.layer');
var _length = _zindexes.length;
// Highest z-index is simply the last element in the array
var _highest = _zindexes[_length - 1].zindex
// Lowest z-index is simply the first element in the array
var _lowest = _zindex[0].zindex;
alert(_highest);
alert(_lowest);
Vanilla JS, not 100% cross-browser. Including as reference for future readers/alternative method.
function getHighIndex (selector) {
// No granularity by default; look at everything
if (!selector) { selector = '*' };
var elements = document.querySelectorAll(selector) ||
oXmlDom.documentElement.selectNodes(selector),
i = 0,
e, s,
max = elements.length,
found = [];
for (; i < max; i += 1) {
e = window.getComputedStyle(elements[i], null).zIndex || elements[i].currentStyle.zIndex;
s = window.getComputedStyle(elements[i], null).position || elements[i].currentStyle.position;
// Statically positioned elements are not affected by zIndex
if (e && s !== "static") {
found.push(parseInt(e, 10));
}
}
return found.length ? Math.max.apply(null, found) : 0;
}
Try my fiddle:
http://planitize.tumblr.com/post/23541747264/get-highest-z-index-with-descendants-included
This combines three advantages I haven't seen combined elsewhere:
Gets either the highest explicitly defined z-index (default) or the highest computed one.
Will look at all descendants of your selector, or all descendants of the document if none is supplied.
Will return either the value of the highest z, or the element that has the highest z.
One disadvantage: no cross-browser guarantees.
If you are doing what I think you're doing, there is no need. Just do this:
$('div[id^=layer-]').css('z-index', 0);
$(this).css('z-index', 1000);

How to get an element's left/top attribute in RAW JavaScript?

I created a codePen here (http://codepen.io/anon/pen/pwoEJ)
document.querySelector('#box').style.left
This line of code doesn't seem return the right value? It gives me "" empty string.
Use getComputedStyle:
document.defaultView.getComputedStyle(document.querySelector('#box')).left
try something like this,http://codepen.io/anon/pen/BjfGu
window.getComputedStyle(document.getElementById('box'),null).getPropertyValue('left');
It depends how cross-browser you want your code to be.
getComputedStyle is not available in IE8- (not sure if it works on IE9 either)
Also, the style might have been already set programmatically, in which case you will find the value inside the element.style object.
Finally, while getComputedStyle accepts CSS-like identifiers (e.g. z-index), the other ways of accessing style elements use camelized names (e.g. zIndex).
In the end, a more general solution is far from trivial:
getStyle = function getStyle (el, property)
{
var style;
if(document.defaultView && document.defaultView.getComputedStyle)
{
style = document.defaultView.getComputedStyle(el, "")
.getPropertyValue (property);
if (style) return style;
}
property = Camelize (property); // this is for older IE versions
if (el.currentStyle) style = el.currentStyle[property];
return style || el.style[property]
}
function Camelize (string)
{
var oStringList = string.split('-');
if (oStringList.length == 1) return oStringList[0];
var camelizedString = string.indexOf('-') == 0
? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
: oStringList[0];
for (var i = 1, len = oStringList.length; i < len; i++)
{
var s = oStringList[i];
camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
}
return camelizedString;
}
(this code adapted for readability from Bernard Sumption's excellent Animator.js library)

removing all the DOM Elements with a specific className

How I can remove all DOM Elements with specific classname or element width ID's that start with a specific pattern. like (without any framework!)
id="selectbox1"
id="selectbox2"
id="selectbox3"
id="selectbox4"
Thanks
You'd have to use getElementsByTagName(*) iterate over the entire collection, check the .className property with a regex /\bYourClasName\b/ (className can have more than one class, seperated by a space) and then also check the element's .id property with another regex: /^IDStartsWithThis/ finally on any matches you would have to call element.parentNode.removeChild(element);
(On my way to work and in a rush, if you need more code I can supply it once I get there around 630 est)
Edit: here's the code:
usage: removeElemIf(idStartsWith,containsClass). you can pass null, only the id (second param is undefined), blanks (blanks are ignored, both parameters are trimmed first). Case is insensitive for both parameters.
function removeElemIf(theID, theClass) { /* class => full match, id => startswith */
checkID = !(theID === undefined || theID === null || (theID = theID.replace(/^\s*|\s*$/g, '')).length == 0);
checkClass = !(theClass === undefined || theClass === null || (theClass = theClass.replace(/^\s*|\s*$/g, '')).length == 0);
if (!(checkID || checkClass)) return;
var oBody = document.getElementsByTagName('body')[0]; // only search the body
var oElems = oBody.getElementsByTagName('*'); // get all the elements within body
for (i = oElems.length - 1; i >= 0; i--) { // loop through backwards in case of delete
el = oElems[i]; // set current element
found = false; // reset flag
if (checkID) { /* check the ID for starting with "theID", originally used indexOf but its case sensitive*/
re = new RegExp('^'+theID,'i');
if (el.id.match(re)) found = true;
}
if (!found && checkClass) { /* only test class if the id doesn't match,
save the regex in instances where the
class names are long or many*/
re = new RegExp('\\b' + theClass + '\\b', 'i');
if (el.className.match(re)) found = true;
}
if (found) el.parentNode.removeChild(el); /* if found, remove from parent */
}
}
Traverse through the dom tree and compare against the className property of each element found. Yes it's tedious, but that's how it's done. You can either traverse in a recursive fashion or an iterative one. The first is the easiest to write, but the second has much better performance.
see this SO thread:
jQuery matching pattern
and check out getElementsByTagName() function

Categories