Bind one click in jQuery mouseenter - javascript

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();
});
});

Related

Prevent click event for wrapper when inner link is click

Here is the example for UI element construct,
HTML
<div class='wrap'>
<a class='inner-link' href="#">Link</a>
</div>
CSS
.wrap
{
background:#CDD4E0;
width:300px;
height:100px;
padding:20px;
}
.wrap:hover
{
background:#868B93;
}
jQuery
$('.wrap').click(function () {
alert("Handler for wrap container click.");
});
$('.inner-link').click(function () {
alert("Handler for inner link click");
});
What I want to do is to prevent the container with the class .wrap click event when I click the link inside.
You can reference this fiddle example.
Current code fire $('.wrap').click when I do for $('.inner-link').click.
Add if to check if the target does not contain class inner-link.
UPDATE: Oh, the comment has a better way to solve it.
$(".wrap").click(function (e) {
if (e.target.className !== "inner-link") { // add this
alert("Handler for wrap container click.");
}
});
$(".inner-link").click(function (e) {
e.stopPropagation(); // or add this
alert("Handler for inner link click");
});
Try to use event.stopPropagation
Your jQuery codes should be modified as below:
$('.wrap').click(function () {
alert("Handler for wrap container click.");
});
$('.inner-link').click(function (event) {
event.stopPropogation();
alert("Handler for inner link click");
});
thanks #riceEater for the idea with the class. I solved it with this:
var elem = $('.parentElem');
elem.on("click",function(e) {
var hitElementClass = e.target.className;
if (hitElementClass.includes("my-wrapper-class")) {
elem.find("input").trigger("click");
}
});

jQuery event listener fires before selector applied

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">

event.stopPropagation() is not worknig?

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>

disable <a> tag for a period of time

To simplify my problem, I made a jsfiddle
When I click on "Click me" it displays a box, but when i click on it twice
at the same time, it displays two boxes at the same time, and for my case it should not be possible. The second box should be able to be displayed only if the first box is completly displayed and the user click again on 'Click me'.
How can I achieve that ?
$('#clickme').click(function() {
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
$div.show('clip', 3000);
});
#clickme {
cursor: pointer
}
.newDiv {
height: 40px;
width: 40px;
background-color: red;
margin: 5px;
display: none;
padding: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<a id="clickme">Click me</a>
<div id="container"></div>
A simple solution is to use a flag, to check the state whether action can be performed.
Here complete callback of .show() is used to reset the flag once effect is complete.
var disable = false;
$('#clickme').click(function() {
var elem = $(this);
if (disable == false) {
disable = !disable;
elem.toggleClass('none', disable);
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
$div.show('clip', 3000, function() {
disable = !disable;
elem.toggleClass('none', disable);
});
}
});
#clickme {
cursor: pointer
}
#clickme.none {
cursor: none
}
.newDiv {
height: 40px;
width: 40px;
background-color: red;
margin: 5px;
display: none;
padding: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<a id="clickme">Click me</a>
<div id="container"></div>
I think the cleanest solution is to bind and unbind your click handler. No need to use a flag or a timeout.
function clickHandler() {
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
// Unbind click handler until animation is completed
$("#clickme").off("click", clickHandler);
// Begin animation
$div.show('clip', 3000, function() {
// Animation completed. Bind click handler.
$("#clickme").on("click", clickHandler);
});
}
// Initial bind of click handler
$("#clickme").on("click", clickHandler);
Here's a working fiddle.
You can disable the button for the time when the box is being drawn. Like this:
$('#clickme').click(function() {
disabling the button for 3000 sec as the box takes 3000 sec to get rendered.
setTimeout(function(){
$(this).attr('disabled','disable');
},3000);
$(this).removeAttr('disabled');
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
$div.show('clip', 3000);
});
So you need to stop execution if the box is still being animated.
I am using the complete argument of jQuery.show method.
var inAnimation = false;
$('#clickme').click(function() {
if(inAnimation)
return;
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
inAnimation = true;
$div.show('clip', 3000, function() {inAnimation = false;});
});
i always use callback after end of animation:
let open = true;
$('#clickme').click(function(){
if ( open ) {
open = false;
$div = $('<div>',{"class" : "newDiv"});
$('#container').append($div);
$div.show('clip',3000, function(){
open = true;
});
}
});
fiddle
If you want a simple solution for your problem you can place an if statement before the assignment of the $div variable:
$('#clickme').click(function() {
if($('.newDiv').length == 0){
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
$div.show('clip', 3000);
}
});
$('.newDiv').click(function() {
$('.newDiv').destroy();
}

Mouse in-out events for Javascript

question from a beginner..
I want to show/hide an inner div when the mouse enter/out from the parent div. I tried first with onmouseover, onmouseout events, but the problem is that onmouseover keep firing while the mouse over the div, and I want it to fire one time only.
I found JQuery events that might help me, but I don't know where can I put this code because my divs exist in a template for a control, and there is no onload event for the div.
<script type="text/javascript" language="javascript">
// Where should I call this !!!
function Init(sender) {
$(sender).bind("mouseenter", function () {
$(sender.childNodes[1], this).show(500);
}).bind("mouseleave", function () {
$(sender.childNodes[1], this).hide(500);
});
}
</script>
Any help!
You can use mouseenter and mouseleave events.
You can put your code in the and bind your with these events.
<script type="text/javascript" language="javascript">
$(document).ready(function(){
Init('.your_div_class');
});
function Init(sender) {
$(sender).bind("mouseenter", function () {
$(sender.childNodes[1], this).show(500);
}).bind("mouseleave", function () {
$(sender.childNodes[1], this).hide(500);
});
}
</script>
Thanks for everybody. as YNhat said, I have to use classes instead of Ids. and this is the code that I used and it's work well.
$(document).ready(function () {
InitEntities();
});
function InitEntities() {
var parentDiv = $(".parentDivClass");
parentDiv.each(function (index) {
var childDiv = $(this).children(".childDivClass");
$(this).bind("mouseenter", function () {
$(childDiv, this).show(250);
}).bind("mouseleave", function () {
$(childDiv, this).hide(250);
});
});
}
css
.parent_div .inner_div
{
display:none;
}
.parent_div:hover .inner_div
{
display:block;
}
This is what I use in a script.
Once the document is fully loaded ($(document).ready) the mouseover event is bound.
I then unbind the event when I'm in it (to prevent it from spamming the event) and bind the mouseleave event.
$(document).ready(function() {
$("#loginformwrapper").bind("mouseover", showLoginForm);
});
function showLoginForm() {
$("#loginformwrapper").unbind("mouseover", showLoginForm);
$("#loginform").animate({
top: '+=80'
}, 1000, function() {
$("#loginform").bind("mouseleave", hideLoginForm);
});
}
function hideLoginForm() {
$("#loginform").unbind("mouseleave", hideLoginForm);
$("#loginform").animate({
top: '-=80'
}, 1000, function() {
$("#loginformwrapper").bind("mouseover", showLoginForm);
});
}
Use this:
<script type="text/javascript">
$(function(){
var mydiv = $("#parent_div_id");
$(mydiv).bind("mouseenter", function () {
$(mydiv.childNodes[1], this).show(500);
}).bind("mouseleave", function () {
$(mydiv.childNodes[1], this).hide(500);
});
});
</script>
replace the "parent_div_id" with the id of your parent div

Categories

Resources