I have implemented click event on window and on specific element. I want to stop window click event propagation on particular element click as mentioned below but it is not working. I am not sure what wrong I am doing here.
$('.dropdown-container').click(function(event){
event.stopPropagation()
var selectElement = '.dropdown-container > select';
if($(selectElement).hasClass('actionDD')){
$(selectElement+'.actionDD').toggleClass('special');
}
else if($(selectElement).hasClass('countryDD')) {
$(selectElement+'.countryDD').toggleClass('special');
}
$('.fa-chevron-down.importC, .fa-chevron-down.exportC ').removeClass('special');
});
$(window).click(function(event){
console.log('window event clicked');
$('.dropdown-container, .fa-chevron-down.importC, .fa-chevron-down.exportC').removeClass('special');
});
Apart from the typos, if your selects are not nested just do this
$('.dropdown-container').on("click", "select", function(e){
e.stopPropagation()
if($(this).is('.actionDD') || $(this).is('.countryDD')) {
$(this).toggleClass('special');
}
$('.fa-chevron-down.importC, .fa-chevron-down.exportC ').removeClass('special');
});
$(window).on("click", function(e){
console.log('window event clicked');
$('.dropdown-container, .fa-chevron-down.importC, .fa-chevron-down.exportC').removeClass('special');
});
Please post your HTML since this works:
$('.dropdown-container').on("click", "select", function(e) {
e.stopPropagation()
if ($(this).is('.actionDD') || $(this).is('.countryDD')) {
$(this).toggleClass('special');
}
});
$(window).on("click", function(e) {
console.log('window event clicked');
});
.special {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown-container">
<select class="actionDD">
<option>Click</option>
</select>
</div>
Related
I am trying to make a system that would require an admin to click a delete button twice before it fires the action. if he focusout of the button, it resets.
$(".unarmed").css("filter", "grayscale(1)").removeClass("armed").click(function(e) {
$(this).css("filter", "").removeClass("unarmed").addClass("armed");
}).mouseout(function() {
$(this).css("filter", "grayscale(1)").removeClass("armed").addClass("unarmed");
});
$("body").on("click", ".armed", function() {
alert("boom");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img class="unwait unarmed" src="plus.png">
I've seen jQuery event listener fires before selector applied? but adding e.stopPropagation() causes the second click to not fire.
when e.stopPropagation() is not in the code, it does fire the second click, but together with the first click (i think this means the problem is not with the second click selector)
here is a fiddle with e.stopPropagation():
https://jsfiddle.net/3jyr72t6/
also, if you have suggestion for making it prettier, i'm open for suggestions :D
#icecub answer as snippet:
$(document).ready(function() {
$(".unarmed").css("filter", "grayscale(1)");
$(".unarmed").click(function(e) {
if ($(this).hasClass("armed")) {
console.log("boom");
}
$(this).css("filter", "").removeClass("unarmed").addClass("armed");
}).mouseout(function() {
$(this).css("filter", "grayscale(1)").removeClass("armed").addClass("unarmed");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img class="unwait unarmed" src="https://kns.im/include/img/plus.png" style="width:50px">
You can always just use the jquery dblclick event. Jquery dblclick
$(document).on("dblclick",".btn-delete",function(){
console.log("DELETE");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btn-delete">DELETE</button>
You can use a simple function to detect click outside the element .. See the next example
$("img.unwait").on("click" , function(e){
let $this = $(this);
if($this.hasClass("unarmed")){
$this.removeClass("unarmed").addClass("armed");
}else if($this.hasClass("armed")){
alert("BOOM");
$this.removeClass("armed").addClass("unarmed");
}
});
detect_click_out(".armed" , function(){
$(".armed").removeClass("armed").addClass("unarmed");
});
function detect_click_out(element_selector , action){
$(document).on('click',function(e){
if (!$(element_selector).is(e.target) // if the target of the click isn't the container...
&& $(element_selector).has(e.target).length === 0) // ... nor a descendant of the container
{action();} // run the action as a function
});
}
img{
width : 50px;
}
.unarmed{
filter : grayscale(1);
}
.armed{
filter : grayscale(0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img class="unwait unarmed" src="https://png.pngtree.com/element_our/sm/20180515/sm_5afb099d307d3.jpg">
When I click it is bind more than 5 click action.
This jQuery block are in mouseenter jquery function.
It bind more than on click.
Below is whole function.
$('.parent').mouseover(function () {
$('#elem').show();
$('#elem').on('click', function (event) {
alert('edit');
});
$(this).mouseleave(function () {
$('#elem').hide();
});
});
Your problem is that every time you put your mouse over the .parent element - you attach a new click event listener to the #elem element. If you hover that element several times (and you don't click), the click event is already attached and therefor you will get several "alerts".
Another thing to note is that with mouseover - every time you "switch" between elements that are one-inside-another (like your example) - that event is fire.
$('.parent').mouseover(function () {
console.log('mouseover fired for .parent');
$('#elem').show();
$('#elem').on('click', function (event) {
console.log('#elem clicked');
});
$(this).mouseleave(function () {
$('#elem').hide();
});
});
$('.parent1').click('#elem1', function(event) {
console.log('#elem1 clicked');
});
$('.parent1').mouseover(function () {
$('#elem1').show();
});
$('.parent1').mouseleave(function () {
$('#elem1').hide();
});
.parent, .parent1 { border: 1px solid red; width: 50px; height: 50px; margin: 25px; padding: 25px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div id="elem">
123
</div>
</div>
<div class="parent1">
<div id="elem1">
123
</div>
</div>
I had make solution from
Dekel answer
I changed this code:
$('.parent').mouseenter(function () {
$('#elem').show();
$('#elem').on('click', function (event) {
alert('edit');
setTimeout(function () {
$('#elem').unbind( "click" );
}, 100);
});
$(this).mouseleave(function () {
$('#elem').hide();
});
});
To this one: Where I bind one click per mouseenter and still can show or hide buttons
$('.parent').one('mouseenter', function () {
$('#elem').click(function (event) {
alert('edit');
});
});
$('.parent').mouseenter(function () {
$('#elem').show();
$(this).mouseleave(function () {
$('#elem').hide();
});
});
This is my jsfiddle : https://jsfiddle.net/2ajo5jdx/
If you click on link-b a div fade-in,now if you click on link-c another div fadeIn too.I don't want more than one div at the same time.I want to disable click on link-c if link-b has been clicked already.
Is there a simple way?Thank you.
$('.b').on("click", function(e) {
e.preventDefault();
$('.a-div').fadeOut( 400, function(){
$('.b-div').addClass('active');
$('.b-div').fadeIn(400);
});
});
$('.c').on("click", function(e) {
e.preventDefault();
$('.a-div').fadeOut( 400, function(){
$('.c-div').addClass('active');
$('.c-div').fadeIn(400);
});
});
To add almost nothing to your code, you could use a flag, set it to true on each click in a link and to false on close
var some_link_opened = false;
$('.b').on("click", function(e) {
if (some_link_opened) return;
some_link_opened = true;
e.preventDefault();
$('.a-div').fadeOut( 400, function(){
$('.b-div').addClass('active');
$('.b-div').fadeIn(400);
});
});
$('.x').on("click", function(e) {
some_link_opened = false;
e.preventDefault();
$('.active').fadeOut( 400, function(){
$('this').removeClass('active');
$('.a-div').fadeIn(400);
});
});
I'm not sure if that what you mean, but if you want to show just one div every time you can use the following solutio based on active class.
Hope this helps.
$('.b').on("click", function(e) {
e.preventDefault();
$('.active').fadeOut( 400, function(){
$('.active').removeClass('active');
$('.b-div').addClass('active');
$('.b-div').fadeIn(400);
});
});
$('.c').on("click", function(e) {
e.preventDefault();
$('.active').fadeOut( 400, function(){
$('.active').removeClass('active');
$('.c-div').addClass('active');
$('.c-div').fadeIn(400);
});
});
$('.x').on("click", function(e) {
e.preventDefault();
$('.active').fadeOut( 400, function(){
$('this').removeClass('active');
$('.a-div').fadeIn(400);
});
});
.b-div,.c-div{
display:none;
}
.x {
color:red;
}
.b,.c,.x{
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="b">link-b</a>
<a class="c">link-c</a>
<a class="x">x</a>
<div class="a-div active">aaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div class="b-div">bbbbbbbbbbbbbbbbbbbbbbbbbbb</div>
<div class="c-div">ccccccccccccccccccccccccccc</div>
Here's a simplified example of the problem I'm having. Say I have this HTML:
<div id="test">Hello</div>
I have the following event handler attached to this div:
$("#test").on("click", function() {
console.log("Clicked test!");
$(document).one("click", function() {
console.log("Clicked on document!");
});
});
Here's a jsFiddle of this example.
If I click on Hello, ideally I would only want "Clicked test!" to appear in my console, and for "Clicked on document!" to appear after I click a second time. However, both log messages appear, as the click event bubbles up to the document object and runs this new click event. Is there a way to prevent this from happening without using stopPropagation, which may have other unintended side effects?
My solution is kind of hacky, but it does work. If you set the document click handler asynchonously, the event doesn't bubble up:
$("#test").on("click", function(e) {
console.log("Clicked test!");
setTimeout(function(){
$(document).one("click", function() {
console.log("Clicked on document!");
});
}, 10);
return true;
});
See the modified fiddle: https://jsfiddle.net/voveson/qm5fw3ok/2/
Or using on and off with selectors:
$(document).on("click", "#test", add_doc_click)
function add_doc_click() {
console.log("Clicked test!");
$(document).on("click", function (e) {
console.log("Clicked on document!");
})
$(document).off("click", "#test", add_doc_click)
}
https://jsfiddle.net/y2q1gocu/
EDIT: to have test and clicked each time:
$(document).on("click", "#test", add_doc_click)
function add_doc_click() {
console.log("Clicked test!");
$(document).on("click", function (e) {
console.log("Clicked on document!");
})
$(document).on("click", "#test", function (e) {
console.log("Clicked test!");
})
$(document).off("click", "#test", add_doc_click)
}
https://jsfiddle.net/y2q1gocu/1/
Assuming nothing should happen on the third click, add these two lines at the end of the click handler:
$(this).off('click');
return false;
Fiddle
Incase you want to click Hello once and then remaining on document.
$( "div" ).one( "click", function() {
console.log("Clicked test!");
event.stopPropagation();
});
$(document).on("click", function() {
console.log("Clicked on document!");
});
https://jsfiddle.net/qm5fw3ok/3/
You can use a class that flags whether or not the element has been clicked on or not.
$("#test").on("click", function(e) {
console.log("Clicked test!");
if($(this).hasClass('clicked')){
$(document).one("click", function(e) {
console.log("Clicked on document!");
});
}else{
$(this).addClass('clicked');
}
});
I have this code in my script:
$(document).ready(function() {
$('*').not('div#user').click(function() {
$('div#userSettings').hide();
});
$('div#user').click(function() {
$('div#userSettings').toggle();
$('div#profileSettings').toggleClass('rotate');
});
});
I need the div#userSettings to be hidden whenever anything but it's button or itself is clicked, and I want it to appear only when I click on the div#user.
the toggleclass does still work in this, just that the div#userSettings does not appear at all
You can stop the event propagation
$(document).ready(function () {
$(document).click(function (e) {
$('#userSettings').hide();
})
$('#user').click(function (e) {
e.stopPropagation();
$('#userSettings').toggle();
$('#profileSettings').toggleClass('rotate');
});
$('#userSettings').click(function (e) {
e.stopPropagation();
});
});
Demo: Fiddle