Detect elements' visibility after adding Display:none using javascript - javascript

I have four divs in a main container.
<div id="boxes">
<div class="inner-box"></div>
<div class="inner-box"></div>
<div class="inner-box"></div>
<div class="inner-box"></div>
</div>
After a javascript click event, display: none is added to them to hide. So I want to do something when no elements are visible.
if ($('#boxes').children(':visible').length == 0)
The above code does not seem to be working because it counts the number of visible elements before the click event (even if all the classes have display: none it gives the count 4).
I'm using change(); function for select to toggle the display property.
Demo: http://jsfiddle.net/wnzavyom/1/

Basically every time you process the onclick event you have to then check each item to see if it exhibits the css setting display: none
(Demo)
JAVASCRIPT
$('.inner-box').on("click",function(){
$(this).css("display","none");
var visible = false;
$('.inner-box',$(this).parent()).each(function(){
if($(this).css("display") !== "none") visible = true;
});
if(!visible) alert("All gone");
});

The issue you have is because your boxes are being hidden using fadeOut() which runs asynchronously. This means that when you check the number of :visible elements the animation has not yet finished, so they are still technically visible.
To achieve what you need you should run your code in the callback of the fadeOut() method. Try this:
$('#filter select').change(function () {
$('.inner-box').fadeOut(function() {
if ($('#boxes').children(':visible').length == 0) {
alert('all boxes hidden');
}
});
});
Updated fiddle

HTML
<select id="showhide">
<option>hide</option>
<option>show</option>
</select>
<div id="boxes">
<div class="inner-box">one</div>
<div class="inner-box">two</div>
<div class="inner-box">three</div>
<div class="inner-box">four</div>
</div>
Script
$('.inner-box').hide();
$('#showhide').on('change',function(){
$('.inner-box').toggle();
alert($('#boxes').children(':visible').length);
});
alert($('#boxes').children(':visible').length);
Demo

Related

Testing if a click is in a div and all its children

I am facing an issue about this.
<div id="1">
<div id="2">
</div>
<div id="3">
<div id="4">
</div>
</div>
</div>
<div id="others_div">
</div>
I want to add the class "hidden" to "1" when I click on something which is not "1" nor one of its children.
Now I am using this but I have a lack of imagination for solving this issue...
document.onclick = function(e)
{
if(e.target.id!="1")
{
$("#1").addClass("hidden");
}
}
Well, to avoid e.stopPropagation() (maybe you want that event to bubble up to some other ancestor) You can check if it is not clicked on #1 nor on it's children like this:
$('body').on('click', function(e) {
if (!((e.target.id== "1") || $(e.target).closest('#1').length)) {
$("#1").addClass("hidden");
}
});
You could use a jQuery check like the following one to check if the current element is your 1 element or traverse the DOM to see if the current target is contained within an element with an ID of 1 :
<script>
$(function(){
// Trigger this when something is clicked
$(document).click(function(e){
// Toggle the hidden class based on if the current element is 1
// or if it is contained in an element with ID of 1
$("#1").toggleClass('hidden',!((e.target.id== "1") || $(e.target).closest('#1').length))
});
});
</script>
Generally, you should avoid using ID attributes that only consists of numbers as they are not valid (ID attributes must begin with a letter). Ignoring this could result in some issues with regards to CSS or jQuery selection.
JQuery
$('body').on( "click", function(e) {
if(e.target.id !== "1")
{
$("#1").addClass("hidden");
}
});
I think you want this
// taken from http://stackoverflow.com/questions/152975/how-to-detect-a-click-outside-an-element
$('html').click(function() {
//Hide the menus if visible
alert('hide');
});
$('#one').click(function(event){
event.stopPropagation();
});
div#one {
background: yellow;
}
div#others_div {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="one">
div one
<div id="2">
div two
</div>
<div id="3">
div three
<div id="4">
div four
</div>
</div>
</div>
<div id="others_div">
other div
</div>

jQuery AddClass and RemoveClass function for multiple element throughout web page

I submitted my code on a code review site and it highlighted that have duplicate functions within my script which can be seen below.
$(document).ready(function () {
$('#search-btn').click(function () {
$('.search-bar-wrap').toggleClass('searchActive');
$('.more-menu').removeClass('moreMenuActive');
$('account-menu').removeClass('acMenuActive');
});
$('.more-btn').click(function () {
$('.more-menu').toggleClass('moreMenuActive');
$('.account-menu').removeClass('acMenuActive');
$('.nav-bar-wrap').removeClass('searchActive');
});
$('.ac-btn').click(function () {
$('.account-menu').toggleClass('acMenuActive');
$('.nav-bar-wrap').removeClass('searchActive');
$('.more-menu').removeClass('moreMenuActive');
});
// MOBILE
$('#mobile-menu').click(function () {
$('.mobile-menu').toggleClass('mobileMenuActive');
$('.m-accord-dwn').removeClass('accordionActive');
});
$('.active-mobile-menu').click(function () {
$('.mobile-menu').toggleClass('mobileMenuActive');
$('.m-accord-dwn').removeClass('accordionActive');
});
$('.mobile-accordion').click(function () {
$('.m-accord-dwn').toggleClass('accordionActive');
});
});
The click functions demonstrated above are adding and removing classes to show can hidden element on the web page and to also give the click but an active state etc. I am trying to follow best practices for me code. Based on my code above is there a way create a global active function? Jsfiddle
The way to eliminate redundant code is to use classes and structure in your markup. By structuring the markup, the same class should be able to be applied to multiple elements, not just one element like you currently have.
You only need one style in your CSS:
.inactive {
visibility: hidden;
}
Then change your markup so each element to be hidden/shown has a "container" element around it and its button. The buttons that toggle the visibility should all have the "toggle-btn" class. And the elements to be hidden/shown all have the "pane" and "inactive" classes.
<header ...>
<div class="container">
<a class="toggle-btn ...">more</a>
<div class="pane inactive ...">
...
</div>
</div>
<div class="container">
<a class="toggle-btn ...">account</a>
<div class="pane inactive ...">
...
</div>
</div>
<div class="container">
<a class="toggle-btn ...">search</a>
<article class="pane inactive ...">
...
</article>
</div>
</header>
Now your JavaScript can be:
$(document).ready(function() {
$('.toggle-btn').click(function() {
var $pane = $(this).closest('.container').find('.pane');
if ($pane.hasClass('inactive')) {
$('.container .pane').addClass('inactive');
$pane.removeClass('inactive');
} else {
$pane.addClass('inactive');
}
});
});
Notice how you only need one event handler registered. Inside the event handler this references the button that was clicked. The "pane" element is found by first using .closest() to get the container element and then .find().
jsfiddle

Jquery show/hide divs - fix overlapping animations

I am using JS to show/hide divs via clicking on the side nav with jquery functions fadeIn() and fadeOut(). The problem I run into is as one div fades out, the next is fading in simultaneously. Also, if I click the link for the div that is already shown, it fades out and fades in again. I'm not sure if an IF statement would be the best approach to do two fixes:
1. Let shown div fully fadeOut before next starts to fadeIn.
2. Currently shown div will not fadeOut/In if same link is clicked.
Here is what I have thus far (without my broken attempt at an IF statement):
http://jsfiddle.net/k55Cw/1/
HTML:
<div class="container">
<header>
<ul class="sidenav">
<li><h2><a data-region="nav-1" href="#">About</a></h2></li>
<li><h2><a data-region="nav-2" href="#">Services</a></h2></li>
<li><h2><a data-region="nav-3" href="#">Team</a></h2></li>
<li><h2><a data-region="nav-4" href="#">News</a></h2></li>
<li><h2><a data-region="nav-5" href="#">Contact</a></h2></li>
</ul>
</header>
<div id="nav-1" class="infozone"><p>Hello I'm box 1.</p></div>
<div id="nav-2" class="infozone"><p>Hello I'm box 2.</p></div>
<div id="nav-3" class="infozone"><p>Hello I'm box 3.</p></div>
<div id="nav-4" class="infozone"><p>Hello I'm box 4.</p></div>
<div id="nav-5" class="infozone"><p>Hello I'm box 5.</p></div>
</div>
CSS:
.infozone{
float:left;
height:400px;
width:800px;
background-color: #000;
display:none;
}
JS:
$(document).ready(function() {
$('.sidenav a').click(function(){
$('.infozone').fadeOut(850);
var region = $(this).attr('data-region');
$('#' + region).fadeIn(850);
});
});
to chain the animations put the fadeIn inside the callback for fadeOut, and to cancel the function if it's currently shown, check if the div is already visible.
I've also had to add a check to see if the current .infozone div is visible - or else the fadeOut applies to hidden elements too, and the callback fires multiple times:
$(document).ready(function() {
$('.sidenav a').click(function(){
var region = $(this).attr('data-region');
var $region = $('#' + region);
if ($region.is(':visible')) return;
var $infozone = $('.infozone:visible');
if ($infozone.length === 0) {
$region.fadeIn(850);
} else {
$infozone.fadeOut(850, function() {
$region.fadeIn(850);
});
}
});
});
You could something like that:
html
This make you page works when javascript is disabled:
<header>
<ul class="sidenav">
<li><h2>About</h2></li>
<li><h2>Services</h2></li>
<li><h2>Team</h2></li>
<li><h2>News</h2></li>
<li><h2>Contact</h2></li>
</ul>
</header>
note that the href point to the id you want to show. This will works also for screen reader if you want to make your page accessible.
javascript. I have not tested it, you might have to fix few things, but the idea is there
$(document).ready(function() {
$('.sidenav a').click(function(e){
var href = $(this).attr('href');
// prevent default
e.preventDefault();
// prevent clicked twice
if(!$(this).hasClass('active'){
$('.sidenav a').removeClass('active');
$(this).addClass('active'){
$('.infozone').fadeOut(850);
$(href.substring(1)).fadeIn(850);
}
});
You should also consider adding some ARIA attributes and roles attributes.

jQuery - If DIV class equals X, hide all other DIVs with a different class

I'm new with jQuery and fairly new to JS (a little knowledge) and I'm wanting to create a jQuery code.
Firstly, here is my HTML code:
<div id="user-controls">
<div class="choice" id="choice-all" onclick="showAll();">All</div>
<div class="choice" id="choice-asus" onclick="justASUS();">ASUS</div>
<div class="choice" id="choice-htc" onclick="justHTC();">HTC</div>
</div>
<div id="devices">
<div class="android asus">Nexus 7</div>
<div class="android htc">One S</div>
<div class="android htc">One X+</div>
<div class="android asus">Transformer Prime</div>
<div class="winph htc">Windows Phone 8X</div>
</div>
I'm wanting a jQuery code that would do the following:
If I click on the #choice-asus DIV, then all DIVs with the class .htc would be set to display="none"
If I click on the #choice-htc DIV, then all DIVs with the class .asus would be set to display="none"
If I click on the #choice-all DIV, then all DIVs would be set to display="inline-block" (this is also the default setting when the page first loads)
I've already tried the following code, but it doesn't do anything.
$(document).ready(function(){
$("#choice-htc").click(function(){
$(".htc").hide();
})
});
Thank you for any help,
Dylan.
So many choices :) http://jsfiddle.net/9RtUE/
$(function(){
$("#user-controls").on('click','div',function(){
var classToShow = this.id.split('-')[1],
filter = classToShow === "all" ? 'div': '.' + classToShow;
$("#devices").children().show().not(filter).hide();
});
});
try using jquery
Demo
$('#choice-all').click(function(){
$('.htc, .asus').show();
});
$('#choice-asus').click(function(){
$('.asus').show();
$('.htc').hide();
});
$('#choice-htc').click(function(){
$('.htc').show();
$('.asus').hide();
});
Demo here
$(document).ready(function(){
$(".choice").click(function(){
$(".android,.winph").hide();
if($(this).attr("id")=="choice-all"){
$(".android,.winph").show();
}else if($(this).attr("id")=="choice-asus"){
$(".asus").show();
}else if($(this).attr("id")=="choice-htc"){
$(".htc").show();
}
});
});
to keep it easy and clean you should use a solution such as this one
$(function(){
$('#choice-asus').on('click', function(){
$('#devices > div:not(.asus)').hide();
});
});
it basically says, if you click on #choice-asus, hide all divs in #devices which have no class asus.
you can extend / modify this for your own needs.
besides, its recommend to use jquerys .on() method instead click/bind or what ever handler you'd apply.
$(document).ready(function(){
if($('div').attr('class')=='X')
{
$('div').not($(this)).css('display','none');
}
});
You can try the following code-
function showAll(){
$("#devices div").show();
}
function justASUS(){
$("#devices div").hide();
$("#devices .asus").show();
}
function justHTC(){
$("#devices div").hide();
$("#devices .htc").show();
}
demo here.

How to add slide animation when showing elements

I would like to add animation effect to following code when showing tree items.
I know that jquery has slide functions, and css has "transition", but not sure how to apply these to my code. Any ideas?
<head>
<script language="JavaScript">
function show(){
var elements = document.getElementsByClassName("label");
for(var i = 0, length = elements.length; i < length; i++) {
elements[i].style.display = 'block';
}
}
</script>
<style>
.label {
-webkit-padding-start: 20px;
display: none;
}
</style>
</head>
<body>
<div>
<div onclick="show()">1st Row</div>
<div>
<div class="label">First</div>
<div class="label">Second</div>
<div class="label">Third</div>
</div>
<div>2nd Row</div>
</div>
</body>
If you are planning to use jQuery then you can use slideDown and slideUp method to show/hide elements with animation. There is slideToggle method which alternatively show/hides the element with animcation. You can modify your show method as below
Working demo
function show(obj){
var $this = $(obj);//Here obj points to the element clicked
//Now you have to show/hide the next sibling of the element clicked
//We will use next() method which gives the next sibling of element
//And then call slideToggle on it to show/hide alternatively
$this.next().slideToggle();
}
Change in the markup
<div onclick="show(this)">1st Row</div>
function show() {
$('.label').slideDown();
}
This selects all elements with the .label class and slides them into view. There is also a .fadeIn() function.
Also, you can attach click handlers by selectors (like an id or class):
<div>
<div class="row">1st Row</div>
<div>
<div class="label">First</div>
<div class="label">Second</div>
<div class="label">Third</div>
</div>
<div class="row">2nd Row</div>
</div>
Notice I removed the onClick="" statement and added a class to the row div. Then you can select the element you want to attach the click event to and keep all the code in one place:
$('.row').bind('click', function () {
$(this).next().find('.label').slideToggle();
});
This JavaScript above adds a click handler to all elements with the row class and toggles the display of all of the elements with the label class in the next element.
Here is a jsfiddle: http://jsfiddle.net/L34g3/.

Categories