Count hidden elements regardless of parent visibility - javascript

I need to count hidden elements regardless of parent visibility.
I have this code:
<div id="parent-1">
<div class="item" style="display: none;"></div>
<div class="item" style="display: none;"></div>
<div class="item"></div>
<div class="item" style="display: none;"></div>
</div>
<script>
var hidden_items = $('#parent-1').find('.item:hidden').length;
console.log (hidden_items);
</script>
In this example I get 3 items, so is correct.
But with this code:
<div id="parent-2" style="display: none;">
<div class="item" style="display: none;">
<div class="item" style="display: none;">
<div class="item">
<div class="item" style="display: none;">
</div>
<script>
var hidden_items = $('#parent-2').find('.item:hidden').length;
console.log (hidden_items);
</script>
I get 4 elements! because parent is a hidden element, but I need to get 3.
Any ideas?

You can use filter function to filter out elements that have display property set as none:
var hidden_items = $('#parent-2 .item').filter(function(){
return $(this).css('display') == "none"
}).length;
Working Snippet:
$(function(){
var hidden_items = $('#parent-2 .item').filter(function(){
return $(this).css('display') == "none"
}).length;
alert (hidden_items);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent-2" style="display: none;">
<div class="item" style="display: none;">
<div class="item" style="display: none;">
<div class="item">
<div class="item" style="display: none;">
</div>

That is because, When a parent element is hidden the children elements of it will also be hidden. That is the natural behavior. If you still want to get the elements regardless of its parent display property then use .filter with its callBack function.
var hidden_items = $('#parent-2 .item').filter(function(){
return this.style.display == "none"
}).length;
DEMO

Related

Take attribute value from where style display is not none

I have few divs:
<div clas="modal-body step step-1" data-step="1" style="display: block;"></div>
<div clas="modal-body step step-2" data-step="2" style="display: none;"></div>
<div clas="modal-body step step-3" data-step="3" style="display: none;"></div>
I would like to get the value of attribute "data-step" where style: display is not none.
Is it possible with JavaScript or JQuery?
You can use the :visible selector in jQuery. This will create a node list (like the querySelectorAll that will contain only the item /s that is not hidden. Then you can get the data-step value of that element.
let visibleStep =$(".step:visible");
console.log(visibleStep.attr('data-step')); // gives 1
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wathever">
<div class="modal-body step step-1" data-step="1" style="display: block;">A</div>
<div class="modal-body step step-2" data-step="2" style="display: none;">B</div>
<div class="modal-body step step-3" data-step="3" style="display: none;">C</div>
</div>
I just did some sketch on fiddle, try it and let me know if is what you need sir. This is a pure javascript solution.
let nodeList = document.getElementById("wathever").querySelectorAll(".step");
nodeList.forEach(function(div){
if(div.style.display!="none"){
//do something
let dataStep = div.dataset.step;
console.log(dataStep);
}
});
<div id="wathever">
<div class="modal-body step step-1" data-step="1" style="display: block;">A</div>
<div class="modal-body step step-2" data-step="2" style="display: none;">B</div>
<div class="modal-body step step-3" data-step="3" style="display: none;">C</div>
</div>

Targetting the last element that has a tabindex attribute?

How do I target the last element of a given parent, that has a tabindex attribute?
For instance:
<div id="popup">
<div id="some-element" tabindex="0">
<div id="some-other-element" tabindex="0">
<div id="yet-another-element" tabindex="0">
</div>
In this case it would target #yet-another-element
You can use the attribute selector [...] combined with jQuery .last() :
let target = $('#popup [tabindex]').last();
console.log(target.attr('id'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="popup">
<div id="some-element" tabindex="0">
<div id="some-other-element" tabindex="0">
<div id="yet-another-element" tabindex="0">
</div>
Another way is to use jQuery :last selector :
$('#popup [tabindex]:last');
let target = $('#popup [tabindex]:last');
console.log(target.attr('id'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="popup">
<div id="some-element" tabindex="0">
<div id="some-other-element" tabindex="0">
<div id="yet-another-element" tabindex="0">
</div>
If you need to select a specific tabindex value :
$('#popup [tabindex="0"]:last');
Using JavaScript:
Use Document.querySelectorAll() with Attribute selectors to get all the elements first in the form of an array-like object. Then use Spread syntax (...) and array.length - 1 to take the element from the last index:
var div = document.querySelectorAll('#popup > div[tabindex="0"]');
var lastEl = [...div][div.length - 1];
console.log(lastEl.id)
<div id="popup">
<div id="some-element" tabindex="0"></div>
<div id="some-other-element" tabindex="0"></div>
<div id="yet-another-element" tabindex="0"></div>
</div>
Using jQuery: You can use :last as part of the selector:
var lastEl = $('#popup > div[tabindex="0"]:last');
console.log($(lastEl).prop('id'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="popup">
<div id="some-element" tabindex="0"></div>
<div id="some-other-element" tabindex="0"></div>
<div id="yet-another-element" tabindex="0"></div>
</div>

Hidding/showing divs with javascript with timer

This site has saved me a milion times, but now i am trying to make something similar to the header section of this site, and can't quite get it to work. I would like someone to help me with the following:
Here is my example code :
<div class="container">
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<div id="first" class="cube color1"></div>
<div id="second" class="cube color3" style="display: none;"></div>
</div>
<div class="col-md-4">
<div id="first" class="cube color2"></div>
<div id="second" class="cube color1" style="display: none;"></div>
</div>
<div class="col-md-4">
<div id="first" class="cube color3"></div>
<div id="second" class="cube color2" style="display: none;"></div>
</div>
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<div id="first" class="cube color3"></div>
<div id="second" class="cube color2" style="display: none;"></div>
</div>
<div class="col-md-4">
<div id="first" class="cube color2"></div>
<div id="second" class="cube color1" style="display: none;"></div>
</div>
<div class="col-md-4">
<div id="first" class="cube color1"></div>
<div id="second" class="cube color3" style="display: none;"></div>
</div>
</div>
</div>
The javascript :
<script>
setInterval(hide, 2000);
function switchDivs()
{
var first = document.getElementById("first");
var second = document.getElementById("second");
}
function hide() {
document.getElementById("first").style.display="none";
document.getElementById("second").style.display="block";
}
function show() {
document.getElementById("first").style.display="block";
document.getElementById("second").style.display="none";
}
</script>
link to jsfiddle
I dont understand first why it doesnt change all the "first" divs into "second", it changes only the first div. Than the next question is how to make that action repeat over time, preferably more like random timer for each one of the 6 positions/boxes.
Shortly: I need divs with id="first" to be swapped with divs with id="second" , after like 5-10 seconds delay after loading the page. Than after the same delay, i need them to switch back to showing only divs with id="first" and so on... (something like setInterval function).
setInterval(function() { $(".color-blocks .col-md-4").each(function() { $(this).children().toggle(); }); }, 2000);
a simple line of code could be helpful, and in a simpler way.
working fiddle : https://jsfiddle.net/65k788u6/3/
while you use ids, those should be unique, so instead use toggle() in order to make it look simpler.
sorry, I don't have 50 rep to leave a comment. Is the problem is that you have multiple elements with the same ID? getElementById() seems to be returning the first instance that's true and not further with the same ID. I would recommend using getelementsbyclassname() and using classes instead of ID's to describe groups of elements. Updated the fiddle to show it done this way. version 4.
Your HTML is invalid. The ID attribute on any element should always be unique within the context of the entire page.
Instead of .getElementById, which selects only one item (and only by its ID attribute) you can use .querySelectorAll to get all elements that match a given CSS query selector (or .querySelector to get a single element).
I recommend using setTimeout instead of setInterval as a general best practice.
var rows = document.querySelectorAll(".col-md-4");
var indices = getIndices(rows);
setTimeout(flipRows, 5000);
function getIndices() {
var arr = [];
for (var i = 0, len = rows.length; i < len; i++) {
arr.push(i);
}
return arr;
}
function flipRows() {
if (indices.length == 0) {
indices = getIndices();
}
var index = Math.random() * indices.length >>> 0;
var randomRow = rows[indices[index]];
indices.splice(index, 1);
flipRow(randomRow);
setTimeout(flipRows, 5000); // run again in 5 seconds
}
function flipRow(row) {
var first = row.querySelector(".first");
var second = row.querySelector(".second");
if (first.style.display === "none") {
first.style.display = "block";
second.style.display = "none";
} else {
first.style.display = "none";
second.style.display = "block";
}
}
.color1 { background-color: pink;}
.color2 { background-color: lightblue;}
.color3 { background-color: lightgreen;}
<div class="container">
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<div class="first cube color1">first</div>
<div class="second cube color3" style="display: none;">second</div>
</div>
<div class="col-md-4">
<div class="first cube color2">first</div>
<div class="second cube color1" style="display: none;">second</div>
</div>
<div class="col-md-4">
<div class="first cube color3">first</div>
<div class="second cube color2" style="display: none;">second</div>
</div>
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<div class="first cube color3">first</div>
<div class="second cube color2" style="display: none;">second</div>
</div>
<div class="col-md-4">
<div class="first cube color2">first</div>
<div class="second cube color1" style="display: none;">second</div>
</div>
<div class="col-md-4">
<div class="first cube color1">first</div>
<div class="second cube color3" style="display: none;">second</div>
</div>
</div>
</div>

jquery: run script without affecting divs with same classes

Got a product loop, where I need to change images on click. Like in every product loop, there is a whole bunch of divs with same classes. Which in my case get affected. Can't isolated them. Initial image does disappear. But not a single one, that's intended, but all of them. And no new images appear
html of the single product
<div class="product">
<div class="galwrap displaytable">
<div class=" galitem galitem1"></div>
<div class=" galitem galitem2"></div>
</div>
<div class="displaytable galcolors">
<div class="displaytablecell galcolor galcolor1"></div>
<div class="displaytablecell galcolor galcolor2"></div>
</div>
</div>
and jquery
$(".product").each(function () {
$(this).find(".galcolor2").click(function () {
$(".galitem").hide();
$(this).parent().find(".galitem2").show();
});
});
http://jsfiddle.net/h1twaf1y/
http://jsfiddle.net/q72nw00t/2/
Javascript:
$(".galcolor2").click(function(){
$(".galitem").hide();
$(this).parent().parent().find(".galitem2").show();
});
HTML: (this is just a section repeated over and over again)
<div class="product">
<div class="galwrap displaytable">
<div class=" galitem galitem1">this will be hidden</div>
<div class=" galitem galitem2" style="display: none">this will be shown</div>
</div>
<div class="displaytable galcolors">
<div class="displaytablecell galcolor galcolor1"></div>
<div class="displaytablecell galcolor galcolor2">click this</div>
</div>
</div>
----------
<div class="product">
<div class="galwrap displaytable">
<div class=" galitem galitem1">this will be hidden</div>
<div class=" galitem galitem2" style="display: none">this will be shown</div>
</div>
<div class="displaytable galcolors">
<div class="displaytablecell galcolor galcolor1"></div>
<div class="displaytablecell galcolor galcolor2">click this</div>
</div>
</div>
----------
<div class="product">
<div class="galwrap displaytable">
<div class=" galitem galitem1">this will be hidden</div>
<div class=" galitem galitem2" style="display: none">this will be shown</div>
</div>
<div class="displaytable galcolors">
<div class="displaytablecell galcolor galcolor1"></div>
<div class="displaytablecell galcolor galcolor2">click this</div>
</div>
</div>
Basically you want to listen for any clicks on ALL .galcolor2, then when that is clicked, hide all .galitem, and then only show the RELATED .galitem2 by going up two levels to the div.product and finding the correct item
The problem in your initial code, is that you only went up ONE level with parent() to div.galcolors where you should have instead went up TWO levels with parent().parent(), up to div.product.
You want to find .galitem relative to the item clicked, the way you can find that is to use $.closest(). Closest will travel up the DOM tree (starting with the current node) until it finds a matching selector, which is much better than using parent because you're not dependent on the DOM structure making your code less brittle and easier to read. So your code would look like this instead:
$(".product").each(function(){
$(this).find(".galcolor2").click(function(){
$(".galitem").hide();
$(this).closest(".product").find(".galitem2").show();
});
});

how to show previous div of clicked div in angular.js

i have a html like this
<div class="main" ng-controller="firstcontroller">
<div class="submain">
<div class="first" ng-show="display">displayed</div>
<div class="second" my-directive>click</div>
</div>
<div class="submain">
<div class="first" ng-show="display">displayed</div>
<div class="second" my-directive>click</div>
</div>
<div class="submain">
<div class="first" ng-show="display">displayed</div>
<div class="second" my-directive>click</div>
</div>
</div>
I have controller like this
app.controller('firstcontroller',function($scope)
{
$scope.display=false;
});
my directive coding like this
app.directive('myDirective',function(scope, element, attrs)
{
return function()
{
element.bind('click',function()
{
element.prev().show();
//alert(element.prev().attr('class'));
// element.parent().find('.main').append('<div>Some text</div>')
});
}
});
here initially div will be hidden if div has class name fist , only div having class name second will be displayed . so when we click on click div we have to show only previous div of that clicked div..... how to show previous div of clicked div in angular.js ?
I get the feeling that the question is missing information. E.g. are the .submain divs hardcoded, or created by iteration?
If however this is indeed the case, the directive is redundant. Change the HTML as:
<div class="main" ng-controller="firstcontroller">
<div class="submain">
<div class="first" ng-show="display[0]">displayed</div>
<div class="second" ng-click="display[0] = !display[0]">click</div>
</div>
<div class="submain">
<div class="first" ng-show="display[1]">displayed</div>
<div class="second" ng-click="display[1] = !display[1]">click</div>
</div>
<div class="submain">
<div class="first" ng-show="display[2]">displayed</div>
<div class="second" ng-click="display[2] = !display[2]">click</div>
</div>
</div>
And the controller:
app.controller('firstcontroller',function($scope) {
$scope.display=[false, false, false];
});

Categories

Resources