jQuery 3.x .off() after .on() - javascript

I simply used .off() method after .on() method for .click() method.
I'm really confused why click() event fires!
$('span').on('click', function () { $('p').text("You Clicked!") });
$('span').off('click', function () {
$('p').text("Ha Ha Ha!") });
span{
background-color:#ac0;
padding:5px;
cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<span>Click Me!</span>
<p>*****</p>

You're trying to remove a different handler function than was originally assigned.
Instead, create a reference to the function and add/remove it by that reference:
var clickHandler = function () { $('p').text("You Clicked!") };
$('span').on('click', clickHandler);
$('span').off('click', clickHandler);

You've misunderstood what the function is for at the end of the off() method. It isn't a callback, it's an event handler.
That function is supposed to be the same event handler function as the one you set initially. This is done this way so that you can remove an individual click handler.
function handlerA(e) {
console.log('heard by A');
}
function handlerB(e) {
console.log('heard by B');
}
// add both handlers to click events
$('span').on('click', handlerA);
$('span').on('click', handlerB);
// remove the first click event only, leaving the second
$('span').off('click', handlerA);
The above would only log heard by B when clicked.
To remove all click handlers, you need to omit the function entirely.
$('span').off('click');

Related

How to modify clickable elements in jQuery?

Why doesn't the on click listener work after clicking on the first list-button?
JSFiddle link
$(".acceptTask").on("click", function(){
acceptTask(this);
});
$(".solveTask").on("click", function() {
solveTask(this);
});
function solveTask(e){
...
}
function acceptTask(e){
...
$(document).on("click", ".solveTask", solveTask);
}
$('.solveTask').on('click', /*...*/) only applies the event handler to anything that has a class "solveTask" at that time. So when you add the solveTask class in your acceptTask function, add an event listener.
$(e).addClass('btn-warning solveTask')
.click(function () { solveTask(this); });
See fiddle: https://jsfiddle.net/1203y34b/1/
I had this problem previously and used 'delegate' instead of 'on':
$(document).delegate('.solveTask', 'click', solveTask)

jquery .off(): how to remove a certain click handler only?

I've an element with two handler bound to it:
<button class="pippo pluto">
push me
</button>
$('.pippo').on('click', function () {
alert("pippo");
});
$('.pluto').on('click', function () {
alert("pluto");
});
I'm trying to .off() only one of them, but the syntax eludes me :-( I'm trying with something among the line of..
<button class="dai">
remove
</button>
$('.dai').on('click', function () {
$('.pippo').off('click');
alert("ok, removed");
});
but this removes both the handler. So I'm trying with...
$('.pippo').off('click .pippo');
but then nothing gets removed.
So I removed the middle space:
$('.pippo').off('click .pippo');
but back to square 1: both handler gets removed.
The right syntax would then be... ?
https://jsfiddle.net/6hm00xxv/
The .off(); method allows you to target multiple selectors as well as a specific event.
$('.pippo').off() would remove all events for the .pippo selector.
$('.pippo').off('click') would remove all click events for the .pippo selector.
$('.pippo').off('click', handler) would remove all click events with that handler for the .pippo selector.
In your case the handler used to add the event listener was an anonymous function so the handlercannot be used in the off() method to turn off that event.
That leaves you with three options, either use a variable, use a namespace or both.
Its quite simple to figure out which one to use.
if( "The same handler is needed more than once" ){
// you should assign it to a variable,
} else {
// use an anonymous function.
}
if ( "I intent to turn off the event" && ( "The handler is an anonymous function" || "I want to turn off multiple listeners for this selector at once" ) ){
// use a namespace
}
In your case
your handler is only used once so your handler should be an anonymous function.
you wish to turn off the event and your handler is anonymous so use a namespace.
So it would look like this
$('.pippo').on('click.group1', function () {
alert("pippo");
});
$('.dai').on('click', function () {
$('.pippo').off('click.group1');
alert("ok, removed");
});
It would work just as well to assign you handler to a variable if you prefer.
This allows you to specify which selector, eventType and handler to remove.
var pippo_click = function (e) {
alert("pippo");
});
$('.dai').on('click', function () {
$('.pippo').off('click', pippo_click);
alert("ok, removed");
});
But as a rule you shouldn't create variables if they're not needed.
One easier alternative with jQuery is to define a namespace for your click events:
$('.pippo').on('click.first', ...);
$('.pluto').on('click.second', ...);
// Remove only the pippo listener
$('.pippo').off('click.first');
Note that your classes pippo and pluto refer to the same element so using one or the other will not change anything.
https://jsfiddle.net/6hm00xxv/2/
Ok, solved. I just had to bind the handler to document:
function showMsg(text) {
alert("showMsg called with text: " + text);
};
$(document).on('click', '.pippo', function () {
showMsg("pippo");
});
$(document).on('click', '.pluto', function () {
showMsg("pluto");
});
$('.dai').on('click', function () {
$(document).off('click', '.pippo');
alert("ok, removed");
});
https://jsfiddle.net/6hm00xxv/1/
Because you are calling .off for click event. It is removing all possible click events on that selected element. The trick is to define a handler and remove that particular handler only.
function showPluto() {
showMsg("pluto");
};
function showPippo() {
showMsg("pippo");
};
function showMsg(text) {
alert("showMsg called with text: " + text);
};
$('.pippo').on('click', showPippo);
$('.pluto').on('click', showPluto);
$('.dai').on('click', function() {
$('.pippo').off('click', showPippo);
alert("ok, removed");
});

How we can bind event inside jquery plugin

I need to bind click event for a anchor tag which is created dynamically.
Example:
$.fn.ccfn = function(){
$(".alreadyavailabledom").click(function(){
$("<a class="dynamicallycreated"></a>");
})
//i am trying like below, but not working
$(".dynamicallycreated").click(function(){
alert("not getting alert why?")
})
}
It is written as a plugin code, i tried with on, live etc. Not working.
you should use event delegation for that
$(document).on("click",".alreadyavailabledom",function(){
//some operation
});
It helps you to attach handlers for the future elements
Use event delegation
$(document).on('click','.dynamicallycreated',function(){
alert("not getting alert why?")
})
or bind the click when creating element
$.fn.ccfn = function () {
$(".alreadyavailabledom").click(function () {
$('<a>', {
html: "anchor",
class: "dynamicallycreated",
click: function () {
alert("clicked anchor");
}
}).appendTo('#myElement');
})
}

Prevent element from animating based on previous class

$('.example').hover(
function () {
$(this).css('background','red');
},
function () {
$(this).css('background','yellow');
}
);
$('.test').click(function(){
$(this).css('marginTop','+=20px').removeClass('example');
}
);
<div class="text example"></div>
Although the class example was seemingly removed, the hover actions for it are still being applied to the element that once had that class. How can I prevent this?
http://jsfiddle.net/gSfc3/
Here it is in jsFiddle. As you can see, after executing the click function to remove the class, the background still changes on hover.
Event handlers are bound to a Node, so it doesn't matter if that Node doesn't own a specific className anymore. You would need to .unbind() those events manually, or better, use jQuerys .off() method.
So, if you can be sure that there aren't any other event handlers bound to that node, just call
$(this).css('marginTop','+=20px').removeClass('example').off();
This will remove any event handler from that Node. If you need to be specific, you can use jQuerys Event namespacing, like so
$('.example').on( 'mouseenter.myNamespace'
function () {
$(this).css('background','red');
}
).on('mouseleave.myNamespace'
function() {
$(this).css('background','yellow');
}
);
and use this call to only unbind any event that is within the namespace .myNamespace
$(this).css('marginTop','+=20px').removeClass('example').off('.myNamespace');
$('.example').unbind('mouseenter').unbind('mouseleave')
In your code, $('.example').hover attaches a mouseenter and mouseleave directly to each element.
-or-
A better solution might be to use delegation with on
$(document.body).on('mouseenter', '.example', function() { ... });
$(document.body).on('mouseleave', '.example', function() { ... });
Using that code, removing the example class will work as expected, because the handlers are based on css selector, while .hover attaches directly to the elements.
$('.example').live({
mouseenter:function () {
$(this).css('background','red');
},
mouseleave:function () {
$(this).css('background','yellow');
}
});
demo: http://jsfiddle.net/gSfc3/1/
Try this:
$('.test').hover(
function () {
$('.example').css('background','red');
},
function () {
$('.example').css('background','yellow');
}
);

jQuery unbind click event function and re-attach depending on situation

The code below I use to create a sliding menu. I need to know how to unbind the function attached to the click event and re-attach it some other time. (using jQuery 1.7.2)
$(document).ready(function(){
$('.section').hide();
$('.header').click(function(){
if($(this).next('.section').is(':visible'))
{
$('.section:visible').slideUp()
$('.arrows:visible').attr("src","right.gif")
}
else
{
$('.section').slideUp();
$(this).next('.section').slideToggle();
$(this).find('.arrows').attr("src","down.gif")
});
});
The code below is what I have so far
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').unbind('click');
}
else
{
//else re-attach functionality?
}
});
Thanks
Simply make a named function. You can go low tech here and back to basics to unbind and reattach specific events.
function doStuff()
{
if($(this).,next('.section').is(':visible'))
...
}
$('.header').on('click', doStuff);
$('.header').off('click', doStuff);
Instead of unbind and re-bind, I suggest you to add a simple class to .header and check for the class in the click handler. See below,
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').addClass('dontClick');
} else {
$('.header').removeClass('dontClick');
}
});
And in your .header click handler,
$('.header').click(function(){
if ($(this).hasClass('dontClick')) {
return false;
}
//rest of your code
If you insist on having a unbind and bind, then you can move the handler to a function and unbind/bind the function any number of time..
You can try something like this.
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').addClass('clickDisabled');
}
else
{
$('.header').removeClass('clickDisabled');
}
});
And then in the click handler check for this class.
$(document).ready(function(){
$('.section').hide();
$('.header').click(function(){
if(!$(this).hasClass('clickDisabled')){
...
...
}
});
});
Why not make that top section a function, and then call it in your else statement?
You could try setting a variable as a flag. var canClick = ($('#formVersion').val() != 'Print'); Then in the click handler for your .header elements check to see if canClick is true before executing your code.
If you still want to remove the handler you can assign the events object to a variable. var eventObj = #('.header').data('events'); That will give you an object with all the handlers assigned to that object. To reassign the click event it would be like $('.header').bind('click', eventObj.click[0]);
After trying so hard with bind, unbind, on, off, click, attr, removeAttr, prop I made it work.
So, I have the following scenario: In my html i have NOT attached any inline onclick handlers.
Then in my Javascript i used the following to add an inline onclick handler:
$(element).attr('onclick','myFunction()');
To remove this at a later point from Javascript I used the following:
$(element).prop('onclick',null);
This is the way it worked for me to bind and unbind click events dinamically in Javascript. Remember NOT to insert any inline onclick handler in your elements.
You could put all the code under the .click in a separated function
function headerClick(){
if($(this).next('.section').is(':visible'))
{
$('.section:visible').slideUp()
$('.arrows:visible').attr("src","right.gif")
}
else
{
$('.section').slideUp();
$(this).next('.section').slideToggle();
$(this).find('.arrows').attr("src","down.gif")
}
}
and then bind it like this:
$(document).ready(function(){
$('.section').hide();
$('.header').click(headerClick);
});
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').unbind('click');
}
else
{
$('.header').click(headerClick);
}
});

Categories

Resources