jQuery prevent function to duplicate on click - javascript

I want to initiate a plugin only if clicked on its parent element (because that element is being appended with jQuery so it does not exist when page loads), So I am trying following code:
$(document).on('click', '.wrap', function(){
ColorPicker(
document.getElementById('slider'),
document.getElementById('picker'),
function(hex, hsv, rgb) {
});
});
This works fine, but every time I click on the .wrap, it duplicates (please check the demo to see the problem). Is there anyway to fix it?
Demo:
http://jsfiddle.net/rhzzG/
(Click in the box to see the problem)
Thanks.

Rather than using on() to trigger this event every time the element is clicked, simply use jQuery's one() method to only fire it once:
$(document).one('click', '.wrap', function(){ ... });
ColorPicker will then take over from there with handling its own events.
JSFiddle demo.

You may use one instead
$(document).one('click', '.wrap', function(){
//...
});

Related

jQuery remove scroll listener after reach certain point [duplicate]

I have an input type="image". This acts like the cell notes in Microsoft Excel. If someone enters a number into the text box that this input-image is paired with, I setup an event handler for the input-image. Then when the user clicks the image, they get a little popup to add some notes to the data.
My problem is that when a user enters a zero into the text box, I need to disable the input-image's event handler. I have tried the following, but to no avail.
$('#myimage').click(function { return false; });
jQuery ≥ 1.7
With jQuery 1.7 onward the event API has been updated, .bind()/.unbind() are still available for backwards compatibility, but the preferred method is using the on()/off() functions. The below would now be,
$('#myimage').click(function() { return false; }); // Adds another click event
$('#myimage').off('click');
$('#myimage').on('click.mynamespace', function() { /* Do stuff */ });
$('#myimage').off('click.mynamespace');
jQuery < 1.7
In your example code you are simply adding another click event to the image, not overriding the previous one:
$('#myimage').click(function() { return false; }); // Adds another click event
Both click events will then get fired.
As people have said you can use unbind to remove all click events:
$('#myimage').unbind('click');
If you want to add a single event and then remove it (without removing any others that might have been added) then you can use event namespacing:
$('#myimage').bind('click.mynamespace', function() { /* Do stuff */ });
and to remove just your event:
$('#myimage').unbind('click.mynamespace');
This wasn't available when this question was answered, but you can also use the live() method to enable/disable events.
$('#myimage:not(.disabled)').live('click', myclickevent);
$('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });
What will happen with this code is that when you click #mydisablebutton, it will add the class disabled to the #myimage element. This will make it so that the selector no longer matches the element and the event will not be fired until the 'disabled' class is removed making the .live() selector valid again.
This has other benefits by adding styling based on that class as well.
This can be done by using the unbind function.
$('#myimage').unbind('click');
You can add multiple event handlers to the same object and event in jquery. This means adding a new one doesn't replace the old ones.
There are several strategies for changing event handlers, such as event namespaces. There are some pages about this in the online docs.
Look at this question (that's how I learned of unbind). There is some useful description of these strategies in the answers.
How to read bound hover callback functions in jquery
If you want to respond to an event just one time, the following syntax should be really helpful:
$('.myLink').bind('click', function() {
//do some things
$(this).unbind('click', arguments.callee); //unbind *just this handler*
});
Using arguments.callee, we can ensure that the one specific anonymous-function handler is removed, and thus, have a single time handler for a given event. Hope this helps others.
maybe the unbind method will work for you
$("#myimage").unbind("click");
I had to set the event to null using the prop and the attr. I couldn't do it with one or the other. I also could not get .unbind to work. I am working on a TD element.
.prop("onclick", null).attr("onclick", null)
If event is attached this way, and the target is to be unattached:
$('#container').on('click','span',function(eo){
alert(1);
$(this).off(); //seams easy, but does not work
$('#container').off('click','span'); //clears click event for every span
$(this).on("click",function(){return false;}); //this works.
});​
You may be adding the onclick handler as inline markup:
<input id="addreport" type="button" value="Add New Report" onclick="openAdd()" />
If so, the jquery .off() or .unbind() won't work. You need to add the original event handler in jquery as well:
$("#addreport").on("click", "", function (e) {
openAdd();
});
Then the jquery has a reference to the event handler and can remove it:
$("#addreport").off("click")
VoidKing mentions this a little more obliquely in a comment above.
If you use $(document).on() to add a listener to a dynamically created element then you may have to use the following to remove it:
// add the listener
$(document).on('click','.element',function(){
// stuff
});
// remove the listener
$(document).off("click", ".element");
To remove ALL event-handlers, this is what worked for me:
To remove all event handlers mean to have the plain HTML structure without all the event handlers attached to the element and its child nodes. To do this, jQuery's clone() helped.
var original, clone;
// element with id my-div and its child nodes have some event-handlers
original = $('#my-div');
clone = original.clone();
//
original.replaceWith(clone);
With this, we'll have the clone in place of the original with no event-handlers on it.
Good Luck...
Updated for 2014
Using the latest version of jQuery, you're now able to unbind all events on a namespace by simply doing $( "#foo" ).off( ".myNamespace" );
Best way to remove inline onclick event is $(element).prop('onclick', null);
Thanks for the information. very helpful i used it for locking page interaction while in edit mode by another user. I used it in conjunction with ajaxComplete. Not necesarily the same behavior but somewhat similar.
function userPageLock(){
$("body").bind("ajaxComplete.lockpage", function(){
$("body").unbind("ajaxComplete.lockpage");
executePageLock();
});
};
function executePageLock(){
//do something
}
In case .on() method was previously used with particular selector, like in the following example:
$('body').on('click', '.dynamicTarget', function () {
// Code goes here
});
Both unbind() and .off() methods are not going to work.
However, .undelegate() method could be used to completely remove handler from the event for all elements which match the current selector:
$("body").undelegate(".dynamicTarget", "click")
I know this comes in late, but why not use plain JS to remove the event?
var myElement = document.getElementById("your_ID");
myElement.onclick = null;
or, if you use a named function as an event handler:
function eh(event){...}
var myElement = document.getElementById("your_ID");
myElement.addEventListener("click",eh); // add event handler
myElement.removeEventListener("click",eh); //remove it
This also works fine .Simple and easy.see http://jsfiddle.net/uZc8w/570/
$('#myimage').removeAttr("click");
if you set the onclick via html you need to removeAttr ($(this).removeAttr('onclick'))
if you set it via jquery (as the after the first click in my examples above) then you need to unbind($(this).unbind('click'))
All the approaches described did not work for me because I was adding the click event with on() to the document where the element was created at run-time:
$(document).on("click", ".button", function() {
doSomething();
});
My workaround:
As I could not unbind the ".button" class I just assigned another class to the button that had the same CSS styles. By doing so the live/on-event-handler ignored the click finally:
// prevent another click on the button by assigning another class
$(".button").attr("class","buttonOff");
Hope that helps.
Hope my below code explains all.
HTML:
(function($){
$("#btn_add").on("click",function(){
$("#btn_click").on("click",added_handler);
alert("Added new handler to button 1");
});
$("#btn_remove").on("click",function(){
$("#btn_click").off("click",added_handler);
alert("Removed new handler to button 1");
});
function fixed_handler(){
alert("Fixed handler");
}
function added_handler(){
alert("new handler");
}
$("#btn_click").on("click",fixed_handler);
$("#btn_fixed").on("click",fixed_handler);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn_click">Button 1</button>
<button id="btn_add">Add Handler</button>
<button id="btn_remove">Remove Handler</button>
<button id="btn_fixed">Fixed Handler</button>
I had an interesting case relevant to this come up at work today where there was a scroll event handler for $(window).
// TO ELIMINATE THE RE-SELECTION AND
// RE-CREATION OF THE SAME OBJECT REDUNDANTLY IN THE FOLLOWING SNIPPETS
let $window = $(window);
$window.on('scroll', function() { .... });
But, to revoke that event handler, we can't just use
$window.off('scroll');
because there are likely other scroll event handlers on this very common target, and I'm not interested in hosing that other functionality (known or unknown) by turning off all of the scroll handlers.
My solution was to first abstract the handler functionality into a named function, and use that in the event listener setup.
function handleScrollingForXYZ() { ...... }
$window.on('scroll', handleScrollingForXYZ);
And then, conditionally, when we need to revoke that, I did this:
$window.off('scroll', $window, handleScrollingForXYZ);
The janky part is the 2nd parameter, which is redundantly selecting the original selector. But, the jquery documentation for .off() only provides one method signature for specifying the handler to remove, which requires this middle parameter to be
A selector which should match the one originally passed to .on() when attaching event handlers.
I haven't ventured to test it out with a null or '' as the 2nd parameter, but perhaps the redundant $window isn't necessary.

Jquery .click() not work if HTML element not yet added

I tried method :
Attaching click event to a JQuery object not yet added to the DOM
but seems not working in my situation. After I created dom elements by jquery, the newly created elements are not accessible. What I want is to after clicking "click me" button, and the image will show up and I hope click the image and a div (#color-picker-box) to show up.
My code: https://codepen.io/MoMoWongHK/pen/ZXbWYb
add the number sign # when calling the id of your div,
from
$("myDiv").on("click" ,".color-picker-icon" , function(){
alert("hi");
$("#color-picker-box").removeClass("display-none");
});
to
$("#myDiv").on("click" ,".color-picker-icon" , function(){
alert("hi");
$("#color-picker-box").removeClass("display-none");
});
You just missed # while using myDiv as a selector!
Wrong:
$("myDiv").cl....
Corrected:
$("#myDiv").cl.....
You need to use event Delegation since the element is not added to dom yet. You need to capture the click on its parent.
$('#myDiv').on("click", "#color-picker-box", function(e){
console.log('color box clicked');
});
Read more about it on:
https://learn.jquery.com/events/event-delegation/
http://api.jquery.com/on/

How do I unbind events properly when using allowSamePageTransition in jQuery Mobile?

I'm using the jQuery Mobile option allowSamePageTransition, which enables me to go from
page A > page A > page A ...
I need this to allow browsing through a catalogue of items. My problem is, the items need some form of interaction and I used to attach the interaction binding to document, because it is set before the elements affected are generated.
However, reloading the same page over and over again will re-bind my event handlers every time I reload.
My first idea was to use .off when the page is being hidden, but reloading a page #foo, will trigger pagehide on the same page being shown, so all bindings set on
$(document).on("pagebeforeshow.foo_events", "#foo", function(e) {
// bind when shown
});
will be unbound again by the previous #foo being hidden
$(document).on("pagehide", "#foo", function (e) {
$(this).off(".foo_events");
// removes bindings on #foo being hidden AND shown
});
The only solution I have come up with is plastering the document with classes, which I don't like doing:
priv.setBindings = function (param) {
var doc = $(document);
doc
.filter(function() { return $(this).is(".e_gallery") !== true; })
.on("pagebeforeshow.gallery", param.pageId, function (e) {
doc.addClass(".e_gallery");
// run stuff
});
};
But I'm no fan of attaching classes to the dom.
Question:
Is there a way to prevent multiple event bindings set on $(document) when going to the same page over and over again WITHOUT toggling classes?
Solution 1
Best solution would be to use pageinit to bind events. If you take a look at an official documentation you will find out that pageinit will trigger ONLY once, just like document ready, so there's no way events will be bound again. This is best solution because you don't have processing overhead like when removing events with off method.
Working jsFiddle example: http://jsfiddle.net/Gajotres/AAFH8/
Of course this will fail in case multiple HTML solution is used.
Solution 2
Remove event before you bind it:
$(document).on('pagebeforeshow', '#index', function(){
$(document).off('click', '#test-button').on('click', '#test-button',function(e) {
alert('Button click');
});
});
Working jsFiddle example: http://jsfiddle.net/Gajotres/K8YmG/
Solution 3
Use a jQuery Filter selector, like this:
$('#carousel div:Event(!click)').each(function(){
//If click is not bind to #carousel div do something
});
Because event filter is not a part of official jQuery framework it can be found here: http://www.codenothing.com/archives/2009/event-filter/
This is probably best solution because event is going to be bound ONLY once.
Solution 4
Probably an easiest of them all.
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('click', '#test-button',function(e) {
if(e.handled !== true) // This will prevent event triggering more then once
{
alert('Clicked');
e.handled = true;
}
});
});
Working jsFiddle example: http://jsfiddle.net/Gajotres/Yerv9/
This is a 180 percent different solution then solution 3, in this case event is going to be bound numerous times but it will be allowed to execute only once.
More info
If you want to find more about this problem take a look at this article, working examples are included.

jQuery trigger('click') not working with Jasmine-jquery

This is my test code:
describe("Login", function(){
beforeEach(function(){
loadFixtures('login-fixture.html');
})
it("should enable the button when checking 'remember password'", function(){
$('#remember').trigger('click');
expect($('#keepIn')).not.toBeDisabled();
});
});
And this is my production code:
$(document).ready(function(){
$('#remember').click(function(e) {
if($('#remember').is(':checked'))
{
$('#keepIn').removeAttr('disabled');
}
});
});
This is not working, the production code never gets called. I have put alerts before and after the trigger event and after the trigger the checkbox is checked, but the .click function does not get called.
Any thoughts on why is this happening?
Without seeing the rest of the code, I'm assuming the "login-fixture.html" contains the "#remember" checkbox. If so, it's loading after the DOM loads. Meaning that the 'click' event you want assigned will only apply to previously loaded elements. The jQuery on() event will assign any event you want to newly loaded elements. You might want to try adding a on() event to that id. Something like:
$(function(){
$('#remember').on('click', function(){
if($('#remember').is(':checked')){
$('#keepIn').checkboxradio('enable');
}
});
});
Hope that helps.
See: http://api.jquery.com/on/

my hover function in jquery it's not working

i am trying to append p tag with some text and i trying to show alert message when hover that p tag content but here it's not working here is my code:code
Here you go: http://jsfiddle.net/Skooljester/37TUN/3/ Instead of click and hover, I used the live function.
Here's the code:
$('#addmore').live("click", function(){
$('<p id="text3">text3</p>').appendTo('#paragraph_div');
});
$('#text3').live("mouseover", function(){
alert('its done!');
});
You're calling hover() on an element that's not yet in the DOM. To work around this, use on():
$('#paragraph_div').on('mouseover','#text3',function(e){
if ($(e.target).is('#text3')){
alert("It's done!");
}
});
JS Fiddle demo.
As noted in the comments, by Alnitak, on() is only available with jQuery version 1.7 and above. To use a version of jQuery prior to version 1.7, you can use delegate() to much the same effect:
$('#paragraph_div').delegate('#text3','mouseover',function(e){
if ($(e.target).is('#text3')){
alert("It's done!");
}
});
JS Fiddle demo using jQuery 1.4.4 (just to demonstrate a different version).
You just need to move your code around a little bit. Here is what I changed:
$('#addmore').click(function() {
$('#paragraph_div').append("<p id='text3'>text3</p>");
$('#text3').hover(function() {
alert('its done!');
});
});
You were trying to bind the hover event before you had created the div to bind it to. I moved it inside the click event where you were actually creating the text3 div. You need to remember to always bind events after creating new dom elements.
Note that as mentioned in some other answers you can use live (deprecated), delegate or on (1.7+). However, I tend to err on the side of adding events to elements after creation whenever it is reasonable to do so.
Also, calling an alert during a hover event may not really make sense depending on your intent. You might want to use the hover to display a div or perform another action. If you want to popup the alert it would be better to use mouseover. See JavaScript/jQuery: event fired twice for more details.
$('#addmore').click(function() {
$('#paragraph_div').append("<p id='text3'>text3</p>");
$('#text3').mouseover(function() {
alert('its done!');
});
});
1st thing please remove document quotes.
2nt thing is change the hover to live with events mouseenter and mouseleave because hover implicitly invoke events mouseenter and mouseleave.
check the fiddle http://jsfiddle.net/37TUN/10/
$(document).ready(function () {
$('#addmore').click(function(){
$('#paragraph_div').append("<p id='text3'>text3</p>");
});
$('#text3').live('mouseenter mouseleave',function(){
alert('its done!');
});
});

Categories