I have an inherited jQuery code where the scroll event has been set:
$(window).on('scroll', function(event) {
// Whatever
});
Now I need to add some more functionality to the previous code when a click event is fired, but this new code must be removed when another element is clicked, something similar to the below code:
$('#element1').on('click', function(){
$(window).on('scroll', function(event) {
// Add my code to the inherited one
});
});
$('#element2').on('click', function(){
$(window).on('scroll', function(event) {
// Unbind my code and leave the original behaviour
});
});
However, I cannot rewrite the inherited code. Is there any way to achieve this?
Thank you very much in advance
You can use event.namespace to bind the event. then you can use .off() to remove an event handler using namespace
$('#element1').on('click', function(){
$(window).off('scroll.element').on('scroll.element', function(event) {
// Add my code to the inherited one
});
});
$('#element2').on('click', function(){
$(window).off('scroll.element');
});
Using the above approach, default scroll event handler will have no impact.
Instead of binding scroll event to body you can bind it to body specific class. Clicking button will swap classes.
$(document).ready(function() {
$('.btn').click(function() {
$('.body')
.removeClass($(this).data('passive-class'))
.addClass($(this).data('active-class'));
});
});
.origin {
color: red;
}
.custom {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="body">
Some content
<button class="btn" data-active-class="origin" data-passive-class="custom">Scroll origin</button>
<button class="btn" data-active-class="custom" data-passive-class="origin">Scroll custom</button>
</div>
Place all code inside function and use flag to execute as needed.
var additionalCode = false;
function usefulCode(event) {
// here is your default code
if (additionalCode) {
// here is additional code
}
}
$(window).on('scroll', usefulCode);
$('#element1').on('click', function(){
additionalCode = true;
});
$('#element2').on('click', function(){
additionalCode = false;
});
Related
I have the following event:
$(document).on('scroll', function() {
// do stuff
});
At the completion of this event, I want to disconnect it. I can do $(document).off('scroll');, but that will disconnect all the scroll events (there are several) on the page.
How do I disconnect just this one event?
How do I disconnect just this one event?
by .namespacing it!
$(document).on({
"scroll.myNamespace" : function() {
// do stuff
}
});
than at some point you can either
$(document).off("scroll.myNamespace");
or all your namespaced events (if you have more of them, like i.e: scroll.myNamespace, click.myNamespace etc...)
$(document).off(".myNamespace");
Example: how to off a namespaced event
$(document).on({
"scroll.teapot": function() {
console.log("TEAPOT!")
},
scroll: function() {
console.log("scroll")
}
});
$("#offTeapot").on({
click: function() {
$(document).off(".teapot"); // off every ".teapot" namespaced event
}
})
body {
height: 400vh;
}
button {
position: fixed;
top: 0;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="offTeapot">OFF TEAPOTS</button>
<h1>SCROLL!!!!!</h1>
In order to remove a specific handler using off(), you'll need to pass a reference to the handler, so simply declare your handler function and pass the reference to both on() and off():
function scrollHandler() {
// do stuff
}
$(document).on('scroll', scrollHandler);
$(document).off('scroll', scrollHandler);
The .off() method removes event handlers that were attached with .on(). See the discussion of delegated and directly bound events on that page for more information. Calling .off() with no arguments removes all handlers attached to the elements. Specific event handlers can be removed on elements by providing combinations of event names, namespaces, selectors, or handler function names.
http://api.jquery.com/off/
You can separate the call back and put it into its own function, then you can remove it.
function doScroll(){
// Do stuff
}
// Add the function
$(document).on('scroll', doScroll);
// Remove the function
$(document).off('scroll', doScroll);
Did you try setting it specifically?
$(document).on('scroll', '#yourId', function(){
}).off('scroll', '#yourId', function(){
});
How about setup a global flag for one time usage:
var doThis = true;
$(document).on('scroll', function() {
if(doThis){
// do stuff
doThis = false;
}
});
I am able to bind click event to element with class name keybox. And this element is generated dynamically.
$('body').on('click','.keybox', function(){
// some code here
});
But for same element I tried binding hover and load event using following code:
$('body').on('hover','.keybox', function(){
// some code here
});
$('body').on('load','.keybox', function(){
// some code here
});
....and its not working as expected.
Can someone help with this problem? I want to bind hover and load event to my element with class name keybox and this element is generated dynamically.
Instead of hover, use mouseenter and mouseleave event. Instead of body.load use
$(document).ready(function() {
You can use following approach to bind multiple events and get object information via event object.
$('body').bind('click hover load', '.keybox', function(e){
if ( e.type === 'hover') {
// do something
}
else if(e.type === 'click') {
// do something
}
....
});
Make sure you bind events in $(document).ready(function() {} or load javascript just in bottom of html document body.
Since hover is deprecated you should use mouseenter and mouseleave for load you can write using event using on(load is equivalent to ready).
$(function(){
$(document).on('mouseenter', '.keybox', function () {
$(this).css('color','red');
});
$(document).on('mouseleave', '.keybox', function () {
$(this).css('color','black');
});
$(document).on('click', '.keybox', function () {// click on dynamically loaded events.
$(this).css('color','green');
});
$('#btn').click(function() {
$('#parent').append("<div class='keybox'>sample1</div>");
$('#parent').append("<div class='keybox'>sample2</div>");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
zdhsdhsau
</div>
<input type="button" id="btn" value="create"/>
When i click on a class i want to remove the class and add a new class to the element. Now when i release the mouse from the class i want to remove the new class added and replace with the old class.
This is only adding the new class but is not reversing the change when i take the mouse of.
<i class="fa fa-arrows"></i>
$('.fa-arrows').mousedown(function(){
$(this).removeClass('fa-arrows').addClass('fa-random');
});
$('.fa-random').on('mouseup',function(){
$(this).removeClass('fa-random').addClass('fa-arrows');
});
https://jsfiddle.net/873k5pgg/
You can use event delegation:
$(document).on('mousedown', '.fa-arrows', function () {
$(this).removeClass('fa-arrows').addClass('fa-random');
});
$(document).on('mouseup', '.fa-random', function () {
$(this).removeClass('fa-random').addClass('fa-arrows');
});
jsFiddle example
What your jQuery does when this code is executed is: it looks for all .fa-arrows and binds the function to mousedown and it looks for all .fa-random and binds the other function to mouseup. This happens once, it is not magically re-evaluated everytime any class/the DOM changes. (That is where React/AngularJS/... come into play.)
You either have to re-evaluate the binds manually whenever the classes change (in the bound functions), or bind both to the same elements (I'd go with the latter):
$('.fa-arrows')
.on('mousedown', function() {
$(this).removeClass('fa-arrows').addClass('fa-random');
})
.on('mouseup', function() {
$(this).removeClass('fa-random').addClass('fa-arrows');
});
.fa-arrows { text-decoration: underline; }
.fa-random { color: red; text-decoration: line-through; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="fa-arrows">mousedown me</p>
Edit: that said, why not just use css?
p { text-decoration: underline }
p:active { color: red; text-decoration: line-through; }
<p>mousedown me</p>
You could set a variable to be true/false if it is clicked or not. Script will need to be altered if you're doing this multiple times on the same page.
var clicked = false;
$(document).on('mousedown', '.fa-arrows', function(){
$(this).removeClass('fa-arrows').addClass('fa-random');
clicked = true;
});
$(document).on('mouseup', function(){
if (clicked) {
clicked = false;
$('.fa-random').removeClass('fa-random').addClass('fa-arrows');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<i class="fa fa-arrows"></i>
The reason this doesn't work is because the events are set at the start, and the mouseup event is set to .fa-random which doesn't exist at that moment.
Like j08691 said you can use event delegation from the document, or you could put the event ons .fa and it should work too:
$('.fa').mousedown(function(){
$(this).removeClass('fa-arrows').addClass('fa-random');
});
$('.fa').mouseup(function(){
$(this).removeClass('fa-random').addClass('fa-arrows');
});
Having a small problem with a popup window I am trying to create.
When a button(anything with a certain ID) is clicked it should open(this seems to work) but then when it is open I want it so if you click on anything but the main popup window it should close.
But it does not seem to close when I click on the .overeverythingCover which has width: 100% and height: 100%;
http://jsfiddle.net/mnW7U/
$('#activatePopOver, .overeverythingCover').click(function() {
popUpOverEverything();
});
function popUpOverEverything(data) {
// if exists | remove it
if ($('.overeverythingCover').length) {
$('.overeverythingCover').empty();
$('.overeverythingCover').removeClass();
$('body').css('overflow', 'scroll');
console.log("hehe");
} else {
$('body').append('<div class="overeverythingCover"</div>');
$('.overeverythingCover').append('<div class="overEverything"</div>');
$('body').css('overflow', 'hidden');
$('.overEverything').html(data);
};
}
Thank you!
You can't use "click" handler to an element which not exist yet. You can use .live :
$(function() {
$('#activatePopOver, .overeverythingCover').live('click', function() {
popUpOverEverything();
});
function popUpOverEverything(data) {
if ($('.overeverythingCover').length > 0) {
$('.overeverythingCover').remove();
$('body').css('overflow', 'scroll');
} else {
$('body').append('<div class="overeverythingCover"</div>');
$('.overeverythingCover').append('<div class="overEverything"</div>');
$('body').css('overflow', 'hidden');
$('.overEverything').html(data);
// Just close when you click outside the popup
$('.overEverything').click(function(event){
event.stopPropagation();
});
};
}
});
See the Fiddle : http://jsfiddle.net/mnW7U/3/
use a delegate event listener such as:
$(document).on("click", '#activatePopOver, .overeverythingCover', function() {
popUpOverEverything();
});
Like The Wobbuffet mentioned, the issue is that the .overerverythingCover div isn't on the page at the time you're binding your event.
NOTE: This will only work with jQuery 1.7+
for older versions you can use .delegate()
The problem was that you are binding a click event to an element that not yet exists on the page.
I have updated your fiddle with a simple to understand example: http://jsfiddle.net/mnW7U/2/
I created a popDown() function that gets bound with the following function when the button is clicked:
$('.overeverythingCover').click(function() {
popDown();
});
The problem is this:
$('body').append('<div class="overeverythingCover"</div>');
It is being appended after the click event is added to it. Try adding it to the dom (none-js in the html) then messing with it's display property.
I'm having troubles with the .bind() and .unbind() features. When the button is clicked, it's supposed to change the color of the box. During this time, the button is disabled by unbinding the click function. However, I'm having issues rebinding the click when the css transition completes.
What I have so far is:
$('button').on('click', function(){
$('button').unbind('click');
$('.box').toggleClass('color');
$('.box').one('webkitTransitionEnd transitionend', function(e){
console.log('transition ended')
$('button').bind('click')
});
});
http://jsfiddle.net/t6xEf/
You need to pass the click handler when binding it. So create a function reference then use it while binding the handler.
function click() {
$('button').off('click.transition');
$('.box').toggleClass('color');
}
$('.box').on('webkitTransitionEnd transitionend', function (e) {
console.log('transition ended')
$('button').on('click.transition', click)
});
$('button').on('click.transition', click);
Demo: Fiddle
Also look at the usage of namespaces while registering/removing the handler because if there if some other click handler added to the button we don't want to disturb it
Also do not add a event handler inside another one
Also have a look at .one()
function click() {
$('.box').toggleClass('color');
}
$('.box').on('webkitTransitionEnd transitionend', function (e) {
console.log('transition ended')
$('button').one('click.transition', click)
});
$('button').one('click.transition', click);
Demo: Fiddle
I would use a flag instead of binding/rebinding the event handler:
var animating = false;
$('button').on('click', function() {
if (animating) return;
animating = true;
$('.box').toggleClass('color')
.on('webkitTransitionEnd transitionend', function(e) {
animating = false;
});
});
http://jsfiddle.net/t6xEf/1/
Do not unbind. Use a boolean:
var onTrans = false;
$('button').on('click', toggle);
function toggle() {
if (!onTrans){
$('.box').toggleClass('color');
onTrans = true;
$('.box').on('webkitTransitionEnd transitionend', function (e) {
onTrans = false;
});
}
}
http://jsfiddle.net/jp8Vy/
This is surely not what you want to do. It seems overly complex, and I can't imagine a good use case scenario.
That being said, you need to reattach the functionality to be performed in the final bind statement. You call the function to bind to the click event, but don't tell the function what to attach.
You need something like this:
$('button').bind('click', function() { ... });
However, that probably isn't what you really want. It sounds like you just want to set the button's "disabled" attribute to false, then to true after the animation.