How can i check if multiple divs have been clicked in JS? - javascript

I'm trying to "track" if all divs have been clicked. If all divs have been clicked something should happen. This can only happen when all divs have been clicked.
http://jsbin.com/cawukapumi/1/
This is what i've gathered so far.
Any help is more then appreciated.
$(document).ready(function(){
$(".masterobject").click(function() {
$(this).data('clicked, true');
});
if ($('#obj1').data('clicked') && $('#obj2').data('clicked') && $('#obj3').data('clicked') && $('#obj4').data('clicked') && $('#obj5').data('clicked') ) {
console.log( "all has been clicked" );
}
});
.masterobject {
position: absolute;
background-color: red;
z-index: 2;
}
#obj1 {
width: 50px;
height: 60px;
top: 25%;
left: 19%;
}
#obj2 {
width: 150px;
height: 100px;
top: 12%;
left: 84%;
}
#obj3 {
width: 80px;
height: 80px;
top : 66%;
left : 73%;
}
#obj4 {
top: 54%;
left: 28%;
width: 60px;
height: 70px;
}
#obj5 {
width: 100px;
height: 100px;
top: 45%;
right: 13%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="masterobject" id="obj1"></div>
<div class="masterobject" id="obj2"></div>
<div class="masterobject" id="obj3"></div>
<div class="masterobject" id="obj4"></div>
<div class="masterobject" id="obj5"></div>

Add a class, see if its count matches the count of items:
$(document).ready(function(){
$(".masterobject").click(function() {
$(this).addClass("clicked");
if ($(".masterobject").length == $(".clicked").length)
alert("all clicked");
});
});

In general, you could do something like this:
var clickers = $(".clicker");
clickers.on("click", function() {
$(this).data("clicked", true);
$(this).addClass("clicked");
var all = true;
clickers.each(function() {
all &= $(this).data("clicked");
return all;
});
if (all) {
alert("all clicked!");
}
});
.clicker {
background-color: red;
width: 100px;
height: 100px;
position: absolute;
}
.clicked {
background-color: blue;
}
#div1 {
left: 10px;
top: 10px;
}
#div2 {
left: 10px;
top: 130px;
}
#div3 {
left: 130px;
top: 10px;
}
#div4 {
left: 130px;
top: 130px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clicker" id="div1"></div>
<div class="clicker" id="div2"></div>
<div class="clicker" id="div3"></div>
<div class="clicker" id="div4"></div>
What we are doing is for every div with the class clicker we bind a click handler that will get the clicked property of this div. Then we check to see if all divs with this class have been clicked and pop an alert if they have.
Note: I added a class so you can tell when you've clicked a div (in my example, they now turn blue). You could actually use that instead of a data property by using .hasClass.

1 approach: You'll need to check if all the divs are clicked each time one is clicked. So, I'd loop through each of your div's, see if the attribute is set... and if not, set a standard boolean var to false.
Something like the following...
var allClicked = true;
$('.masterobject').each(function(){
if(!$(this).data('clicked')){
allClicked=false;
return false;
}
});
if(allClicked){
alert('yay!');
}
http://jsbin.com/kokumohohe/2/edit?output

It is a bit ugly, but you can do something like:
div1 = "1";
div2 = "1";
div3 = "1";
divSum = div1 + div2 + div3;
console.log(divSum);
$("#div1").click(function() {
div1 = "2";
check();
});
$("#div2").click(function() {
div2 = "2";
check();
});
$("#div3").click(function() {
div3 = "2";
check();
});
function check () {
divSum = div1 + div2 + div3;
if (divSum = 222) {
alert("TAdaaahh!");
};
}
Here is a fiddle: http://jsfiddle.net/xdpyx3rx/1/

What about this approach using combination of jQuery and getElementsByClassName method, which allows you not to requery DOM on each click taking advantage of live NodeList:
$(document).ready(function() {
var clicked = document.getElementsByClassName('clicked');
var $masterObjects = $(".masterobject").click(function() {
$(this).addClass("clicked");
if ($masterObjects.length === clicked.length) {
alert("all clicked");
}
});
});
Demo: http://jsbin.com/wepoqumita/1/

Related

Add class only executes on last div in arrray

When the top property of each div .js-player is between 10 and 100 the word #muteshould have the class .active added. The code below only executes the adding of .active on the last .js-active div. Where am I going wrong? Any pointer would be greatly appreciated.
const players = Array.from(document.querySelectorAll('.js-player')),
mute = document.querySelector('#mute');
window.addEventListener('scroll', function(e) {
players.forEach(function(player) {
let distance = player.getBoundingClientRect().top;
if (10 < distance && distance < 100) {
mute.classList.add('active');
} else {
mute.classList.remove('active');
}
})
});
.js-player {
height: 150px;
width: 200px;
background-color: red;
margin: 8em 2em;
}
#mute {
position: fixed;
top: 10px;
left: 10px;
}
.active {
color: green;
}
.filler {
height: 400px;
}
<div class="js-player"></div>
<div class="js-player"></div>
<div class="js-player"></div>
<div class="filler"></div>
<div id="mute">mute</div>
I think what you are wondering is why only the last .js-player determines whether or not the div has the active class?
If so, each time a scroll event happens, it loops over the players, and either add or removes the active class. So, when it gets to the last .js-player, if this last .js-player is not within the distance, it will remove the active class if another one set it, and add it if is, it will set it even if another one removed it.
What you need to do is stop checking once you have found a player within the distance required, something like:
const players = Array.from(document.querySelectorAll('.js-player')),
mute = document.querySelector('#mute');
window.addEventListener('scroll', function(e) {
var matched = false;
players.forEach(function(player) {
if (matched) return;
let distance = player.getBoundingClientRect().top;
if (10 < distance && distance < 100) {
mute.classList.add('active');
matched = true;
} else {
mute.classList.remove('active');
}
})
});
.js-player {
height: 150px;
width: 200px;
background-color: red;
margin: 8em 2em;
}
#mute {
position: fixed;
top: 10px;
left: 10px;
}
.active {
color: green;
}
.filler {
height: 400px;
}
<div class="js-player"></div>
<div class="js-player"></div>
<div class="js-player"></div>
<div class="filler"></div>
<div id="mute">mute</div>
You are setting active class on mute element on each iteration, which means that only the last element of array will matter.
Here's a working verions:
const players = Array.from(document.querySelectorAll('.js-player'));
const mute = document.querySelector('#mute');
window.addEventListener('scroll', function(e) {
var active = false;
players.forEach(function (player) {
let distance = player.getBoundingClientRect().top;
if (10 < distance && distance < 100) {
active = true;
}
});
active ? mute.classList.add('active') : mute.classList.remove('active');
});
.js-player {
height: 150px;
width: 200px;
background-color: red;
margin: 8em 2em;
}
#mute {
position: fixed;
top: 10px;
left: 10px;
}
.active {
color: green;
}
.filler {
height: 400px;
}
<div class="js-player"></div>
<div class="js-player"></div>
<div class="js-player"></div>
<div class="filler"></div>
<div id="mute">mute</div>
Cheers!

How to make a popup disappear only when clicked anywhere outside of it

I'm trying to toggle a popup when click on a specific link and then remove class ".open" from it when clicked anywhere other than the popup box.
Using below methods I was able to get the popup disappear when clicked outside of it but it's now also getting disappear when clicked inside the popup area.
$(".onclick-dropdown-link, .user-message-center-link").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
var id = $this.attr('href');
$('.onclick-dropdown').not(id).removeClass('open');
$(id).toggleClass('open');
});
$('body:not(.onclick-dropdown.open)').click(function(e) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
});
.onclick-dropdown {
opacity: 0;
visibility: hidden;
background: #f3f3f3;
width: 390px;
height: 390px;
position: absolute;
top: 128px;
right: 28px;
height: auto;
padding: 0;
z-index: 999;
}
.onclick-dropdown.open {
opacity: 1;
visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="alert-center-link">
<a class="onclick-dropdown-link" href="#alert-center">The Link</a>
</li>
</ul>
<div id="alert-center" class="onclick-dropdown">
<p>Lorem Ipusm</p>
</div>
Change your .click() function to the following:
$(document).click(function(e) {
if( !$('.onclick-dropdown').is(e.target) && !$('.onclick-dropdown').children().is(e.target)) {
if( $('.onclick-dropdown').hasClass('open') ) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
}
}
});
Change your Popup HTML to :
<div id="alert-center-outer" class="onclick-dropdown">
<div id="alert-center">
//CONTENT HERE...
<p>Lorem Ipusm</p>
</div>
</div>
#alert-center-outer{
position: fixed;
left; 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0.5;
background-color: black;
}
#alert-center{
width: 200px;
height: 300px;
margin: 0 auto;/*This will center align it.*/
}
Clicking the #alert-center-outer should hide the popup.
Clicking the #alert-center should stopPropagation so that it doesn't bubble to its parent.
try below code
$(document).ready(function(){
$(".onclick-dropdown-link, .user-message-center-link").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
var id = $this.attr('href');
$('.onclick-dropdown').not(id).removeClass('open');
$(id).toggleClass('open');
});
$(document).click(function(e) {
if (!$(e.target).closest('.onclick-dropdown').length)
$("#alert-center, #message-center, #user-message-center").removeClass('open');
});
})
.onclick-dropdown {
opacity: 0;
visibility: hidden;
background: #f3f3f3;
width: 390px;
height: 390px;
position: absolute;
top: 128px;
right: 28px;
height: auto;
padding: 0;
z-index: 999;
}
.onclick-dropdown.open {
opacity: 1;
visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="alert-center" class="onclick-dropdown">
<p>Lorem Ipusm</p>
</div>
<li class="alert-center-link"><a class="onclick-dropdown-link" href="#alert-center">asdfsdfsdfds</a></li>
// only trigger once
$('body').one('click', function(e) {
var $target = $(e.target);
// the $target which trigger click event is not the popup dom itself
// and also is not the children dom of the popup
if (!$target.is('#alert-center') && $target.parents('#alert-center').length === 0) {
$("#alert-center, #message-center, #user-message-center").removeClass('open');
}
})
Is that what you want?
Now you can add any tags in the popup, and click inside the popup area where not hide it.

A CSS class is added to an element by JS at runtime, but its properties are not applied. Why?

I have been monitoring what CSS classes properties are applied to .header when the window is scrolled down enough that .view is no longer visible. The class scroll-header IS added to .header, but the associated CSS properties ARE NOT applied. They question is why and how do I fix this?
$(document).ready(function() {
console.log("script.js is detected"); //check
$(window).scroll(function() {
console.log("window onscroll being called."); //check
if ($("div.view").visible(true)) {
console.log("YES if ( $(\"div.view\").visible(true) )"); //check
$(".header").removeClass(".scroll-header");
} else {
console.log("NO if ( $(\"div.view\").visible(true) )"); //check
$(".header").addClass(".scroll-header");
}
});
});
.view {
height: 500px;
width: 100%;
background-color: crimson;
}
.second {
height: 2500px;
width: 100%;
background-color: purple;
}
.header {
position: absolute;
width: 100%;
height: 100px;
background-color: cyan;
top: 0px;
left: 0px;
}
.scroll-header {
background-color: yellow;
position: fixed;
width: 100%;
height: 70px;
background-color: yellow;
}
* {
border: 0px;
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.jsdelivr.net/jquery.visible/1.1.0/jquery.visible.min.js"></script>
<div class="view">.</div>
<div class="header">.</div>
<div class="second">.</div>
<div class="scroll-header" style="bottom:0px;">.</div>
as mentioned in comment, .visible is not a function of jquery. Although you can use below code to detect your dom element is visible or not:
if ($("#yourElem").is(":visible") == true) {
//do something
}
else {
//do something else
}
As you are using jquery.visible plugin. Your code is wrong in javascript. Correct code:
$(document).ready(function() {
console.log("script.js is detected"); //check
$(window).scroll(function() {
console.log("window onscroll being called."); //check
if ($("div.view").visible(true)) {
console.log("YES if ( $(\"div.view\").visible(true) )"); //check
$(".header").removeClass("scroll-header");
} else {
console.log("NO if ( $(\"div.view\").visible(true) )"); //check
$(".header").addClass("scroll-header");
}
});
});
You were adding .scroll-header instead of scroll-header

each , functions and arrays

I have several elements and I want a function to get the width and offset of each element when I do click. I want to save both values of each element so I can access to it from outside the function and do stuffs. I tried this code but im stuck. thx.
$(document).ready(function() {
$("div>div").off("click").click(function() {
var checkWidth ;
var checkLeft ;
function checkPosition() {
$("div>div").each(function() {
checkWidth = $(this).width();
checkLeft = $(this).offset().left;
});
return [checkWidth, checkLeft];
}
var test = checkPosition()
alert(test);
});
// if( width of second element is # && offset of third element is # ) {
// do some thing ;
ยจ // }
})
div div{
position: relative;
height: 100px;
width: 100px;
margin-top: 20px;
}
.rectangle1{
background-color: black;
width: 100px;
left: 10px;
}
.rectangle2{
background-color: red;
width: 200px;
left: 30px;
}
.rectangle3{
background-color: black;
left: 60px;
width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<head>
</head>
<body>
<div>
<div class="rectangle1"></div>
<div class="rectangle2"></div>
<div class="rectangle3"></div>
</div>
</body>
define array out of function to make it global and also use each(index) to properly set the values of array:
$(document).ready(function() {
var myarray=[];
$("div>div").off("click").click(function() {
var checkWidth ;
var checkLeft ;
function checkPosition() {
$("div>div").each(function(index) {
checkWidth = $(this).width();
checkLeft = $(this).offset().left;
myarray[index]=[checkWidth,checkLeft];
});
return myarray;
}
var test = checkPosition()
alert(test);
});
//if( width of second element is # && offset of third element is # ) {}
// if (myarray[1][0]==130 && myarray[2][1]==120){}
// as you have a two dimensional array and javascript array starts from 0:
// myarray[n][0] will return the width of n+1(th) element
// myarray[n][1] will return the offset of n+1(th) element
})
div div{
position: relative;
height: 100px;
width: 100px;
margin-top: 20px;
}
.rectangle1{
background-color: black;
width: 100px;
left: 10px;
}
.rectangle2{
background-color: red;
width: 200px;
left: 30px;
}
.rectangle3{
background-color: black;
left: 60px;
width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div>
<div class="rectangle1"></div>
<div class="rectangle2"></div>
<div class="rectangle3"></div>
</div>
</body>
I have created a jsfiddle for the answer. Check it here https://jsfiddle.net/dj2jdzrp/
var divProperties;
$("#outerDiv > div").click(function(e) {
divProperties = {"offset" : $(this).offset() , "width" : $(this).width() }
alert('anchor clicked!'+ divProperties.offset.left + 'width'+ divProperties.width);
});

Detect Hover for two intersecting Circular elements

i did an example on jsFiddle ( http://jsfiddle.net/aRWhm/ ) , the idea is to know when i'm over lets say the intersection between the red and the blue circle.
but the problem is that every time i reach the intersection, the class "is-over" of the red circle is removed.
Html:
<div>
<span id="Div1"></span>
<span id="Div2"></span>
<span id="Div3"></span>
<span id="Div4"></span>
</div>
CSS:
div {
display: block;
margin: 0 auto;
overflow: hidden;
width: 950px;
}
span {
display: block;
position: absolute;
opacity: 0.5;
border-radius: 999px;
z-index: 1;
}
#Div1 {
background-color: #FF0000;
height: 200px;
left: 50px;
top: 80px;
width: 200px;
}
#Div2 {
background-color: #0000FF;
height: 150px;
left: 40px;
top: 230px;
width: 150px;
}
#Div3 {
background-color: #008000;
height: 250px;
left: 100px;
top: 190px;
width: 250px;
}
#Div4 {
background-color: #FFFF00;
height: 100px;
left: 200px;
top: 130px;
width: 100px;
}
JavaScript:
$(document).ready(function () {
$("#Div1").hover(
function () {
$(this).addClass("is-over");
},
function () {
$(this).removeClass("is-over");
}
);
$("#Div2").hover(
function () {
$(this).addClass("is-over");
},
function () {
$(this).removeClass("is-over");
}
);
$("#Div3").hover(
function () {
$(this).addClass("is-over");
},
function () {
$(this).removeClass("is-over");
}
);
$("#Div4").hover(
function () {
$(this).addClass("is-over");
},
function () {
$(this).removeClass("is-over");
}
);
});
Here you go.
First, the Code:
(function($){
$.mlp = {x:0,y:0}; // Mouse Last Position
function documentHandler(){
var $current = this === document ? $(this) : $(this).contents();
$current.mousemove(function(e){jQuery.mlp = {x:e.pageX,y:e.pageY}});
$current.find("iframe").load(documentHandler);
}
$(documentHandler);
$.fn.ismouseover = function(overThis) {
var result = false;
this.eq(0).each(function() {
var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
var offset = $current.offset();
result = offset.left<=$.mlp.x && offset.left + $current.outerWidth() > $.mlp.x &&
offset.top<=$.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
});
return result;
};
})(jQuery);
$(document).ready(function () {
$("#myDiv").mousemove(
function() {
$("#myDiv").children("span").each(function(){
if($(this).ismouseover())
$(this).addClass("is-over");
else
$(this).removeClass("is-over");
});
});
});
Now an explanation:
I stole the .ismouseover() code shamelessly from this answer by Ivan Castellanos and repurposed it to your needs. Form there I used a .mousemove() event to fire every time you're in the parent container, which you can see in this fiddle needed to be given height and width parameters to ensure that it had a bounding box.
Lastly I simply check to see which circles you're over, and add the is-over class to them. The Fiddle is based off Anton's work, although it provides intersection support instead of moving one to the top.
Hope this helps.

Categories