I currently have something like this code running:
function blah() {
jQuery(".class1").on("click", function() {
jQuery(this).text('Validate').addClass('class2').removeClass("class1");
//more stuff here
jQuery(".class2").on("click", function() {
jQuery(this).removeClass("class1");
//More stuff here
This is bad because the click events propagate, every click that occurs adds the click event multiple times. I tried closing off the first selector (like so) and having the click events seperately but the second click event never occurred(!):
function blah() {
jQuery(".class1").on("click", function() {
jQuery(this).text('Validate').addClass('class2').removeClass("class1");
});
jQuery(".class2").on("click", function() {
jQuery(this).removeClass("class1");
//More stuff here
How do I structure code so that on the first click one thing happens, and the second click another thing happens without click events doubling
you need
jQuery(document).on("click", ".class1", function() {
jQuery(this).text('Validate').addClass('class2').removeClass("class1");
});
jQuery(document).on("click", ".class2", function() {
jQuery(this).removeClass("class1");
//More stuff here
});
Demo: Fiddle
Related
I just started to learn js and need a little help: I have the following function:
//SET CHAT BEHAVIOR
function chatSettings() {
console.log('ChatSettings called')
function BtnAndScrollBar(texteditor) {
console.log('BTNAndScrollBar called');
const sendBtn = $('.cl.active').find('.sendBtn');
const attachBtn = $('.cl.active').find('.attachBtn');
console.log(sendBtn)
}
function sendAndDeleteMessage(send) {
console.log(send);
}
var sendBtn = $('.cl.active').find('.sendBtn');
sendBtn.mousedown(function () {
sendAndDeleteMessage(this);
});
var textEditor1 = $('.cl.active').find('.chatTextarea');
textEditor1.on('focus change mousedown mouseout keyup mouseup', function (){
console.log(this);
BtnAndScrollBar(this)
});
}
$('document').ready(function () {
console.log('hello');
$('.tabs').tabs();
chatSettings();
});
I prepared a js.fiddle - As you can see from console.log when clicking into the textarea, the eventListener always listens to #cl1, even if .cl.active switches along with the according TAB.
The events in the textarea are just relevant, if .cl is active. My target is to wrap all three eventListener into one and apply the event to the textarea in the active stream, but all I tried went wrong... Can anyone help? #Dontrepeatyourself #DRY
$(".chatTextarea").on(
'focus change mousedown mouseout keyup mouseup',
function (this) {
//this.id can contain the unique id
greatFunction(this);
});
This will bind event individually with unique id found with this keyword and also wraps all event listener into one function but this is better when you want to process each event with same functionality
please let me know if this helps.
Peace
$(".cl textarea").on('focus change mousedown mouseout keyup mouseup', function () {
greatFunction(this)
});
Tada!
P.S. Is there a reason greatFunction is defined inside window.onload?
Try using $(document).ready function to load code when the page loads.
Also use $('textarea #cl1').on to get the textarea with the #cl1 or whichever id you want to use and then call the function after using the .on.
Hope this helps!
Let me know if it works!
$(document).ready(function () {
function greatFunction(elem) {
//do stuff
}
$('textarea').on('focus change mousedown mouseout keyup mouseup', function () {
greatFunction(this)
});
}
First off, I changed the onload to bind with jQuery, so all your logic is doing jQuery bindings, rather than swapping back and forth between jQuery and vanilla javascript. Also, doing an actual binding removes an inline binding.
Next, the binding has been condensed into a single delegate event listener. Since you eluded in your comments that it wasn't working for the active element after the active was moved or added, this reflected that you were dealing with dynamic elements. Delegate event listeners are one way to handle such things.
Delegate event listeners bind on a parent element of the elements that will change, or be created. It then waits for an event to happen on one of it's children. When it gets an event it is listening for, it then checks to see if the element that it originated from matches the child selector (second argument) for the listener. If it does match, it will then process the event for the child element.
Lastly, I added some buttons to swap around the active class, so you could see in the snippet that the event handler will start working for any element that you make active, regardless of it starting out that way.
$(window).on('load', function () {
function greatFunction (elem) {
console.log(elem.value);
}
$(document.body).on(
'focus change mousedown mouseout keyup mouseup',
'.cl.active .chatTextarea',
function () {
greatFunction(this);
}
);
$('.makeActive').on('click', function () {
$('.active').removeClass('active');
$(this).closest('div').addClass('active');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cl1" class="cl active"><textarea class="chatTextarea">aa</textarea><button class="makeActive">Make Active</button></div>
<div id="cl2" class="cl"><textarea class="chatTextarea">bb</textarea><button class="makeActive">Make Active</button></div>
<div id="cl3" class="cl"><textarea class="chatTextarea">cc</textarea><button class="makeActive">Make Active</button></div>
I have the following script :-
$(document).ready(function () {
$("body").on('change', '#FilterSize1,#FilterSize2', function () {
where the related function will fire when the filterSize1 or FilerSize2 is changed. now I want to modify the above to allow the same function to fire when an button is clicked also ? so can anyone advice if $("body").on allow to define multiple events (when a list is changed or when a button is clicked ??) ?
Just name the function.
Although you can have .on("change click",function() - it looks strange when you have things that change and things that you click. For example if you click a select the function will be executed regardless of change. It does make it more readable too.
function something() {}
$(document).ready(function () {
$("body").on('change', '#FilterSize1,#FilterSize2', something);
$("body").on('click', '#button,#button1', something);
});
on neater:
$(document).ready(function () {
$("body").on('change', '#FilterSize1,#FilterSize2', something)
.on('click', '#button,#button1', something);
});
Use multiple events with space separated
$("body").on('change click', .......
In case you want different handlers for them then
$("body").on({'click': function(){ .... }, 'change' : function(){..........},'selector')
For binding events for separate elements, you should bind twice with different selectors
$("body").on('click','selector1',handler).on('change','selector2',handler)
i need to trigger only one click on specific element that can be on page load time or added dynamically in the future. Some code
This code work just fine for elements that are rendered on load time but wont bind the click event to new elements dynamically added
$(".message-actions .accept").one("click", function(e){
console.log("accept");
});
In the other hand if i do it this way, it will bind the event to new elements but don't unbind the event so if i click it again it will print the same console log
$("body").on("click", ".message-actions .accept", function(e){
console.log("decline");
$(this).unbind("click");
});
At last if i do it in this other way it will only fire the event in the first element i click even if there is more than one loaded or added after.
$("body").one("click", ".message-actions .accept", function(e){
console.log("decline");
});
How can i do this?
Thanks
You can add data to the element that remembers whether the handler has run before:
$("body").on("click", ".message-actions .accept", function() {
if (!$(this).data("run-once")) {
console.log("decline");
$(this).data("run-once", true); // Remember that we ran already on this element
}
});
I would do it this way:
var handleClick = function () {
// do your work
alert("decline");
// unbind
$("body").off("click", ".message-actions .accept", handleClick);
};
$("body").on("click", ".message-actions .accept", handleClick);
Check this fiddle
You can solve it like this, if it suits your situation : http://jsfiddle.net/hu4fp5qs/1/
$("body").on("click",".message-actions .accept",function(){
$(this).removeClass("accept").addClass("decline");
alert("Declined");
});
On click remove class accept and add class decline.
This will help you in styling both the cases differently so that you can distinguish between them.
.accept{
background-color:green;
}
.decline{
background-color:red;
}
$(function(){
$('#webs').mouseenter(function(){
$('#websitehov').fadeIn('slow');
});
$('#webs').mouseleave(function(){
$('#websitehov').fadeOut('slow');
});
});
I know there are a ton of questions on this but I've tried a number of them and still not working, I've tried different event handlers including .hover, .mouseover and .mouseenter.
The image hover/hover out effect fires multiple times when it enters and whenever I move the mouse inside the image the two events start firing.
I found one solution that stopped this :
(function(){
$('#webs').hover(function(){
$('#websitehov').fadeIn('slow')
}, function() { });
});
but this only worked for the hover in and not for hover out because the empty function was the mouseout event handler, idk if you can override this?
The only possible problem I can see is that of animation queuing, clear the animation queue before addition another one
$(function () {
$('#webs').hover(function () {
$('#websitehov').stop(true, true).fadeIn('slow');
}, function () {
$('#websitehov').stop(true, true).fadeOut('slow');
});
});
Demo: Fiddle
I have a drop down menu, and clicking the icon should add the class "Open" to its parent, and then clicking the menu anywhere should close it. But the function inside the bind fires when the icon is clicked. The effect being it adds the class Open, and then removes it straight away.
This is probably a simple issue, but I cannot seem to work out why the 'click' event fires straight away!?
This question may be similar but can't still can't work it out: jQuery bind event firing the event
$(function () {
$(".ui-dropdown-action").bind("click", function () {
$(this).parent()
.addClass("Open")
.bind("click", function () {
$(this).removeClass("Open");
});
});
});
I think you might have a problem with the click event bubbling up the DOM tree. Which is why click is also being fired on the parent.
if you pass in the event object as an argument for the first bind and call event.stopPropagation() as follows
$(function () {
$(".ui-dropdown-action").bind("click", function (event) {
event.stopPropagation();
$(this).parent()
.addClass("Open")
.bind("click", function () {
$(this).removeClass("Open");
});
});
});
should fix your issue.
You can pass the event argument and stop the bubbling of the event .. Try this
$(function () {
$(".ui-dropdown-action").bind("click", function () {
$(this).parent()
.addClass("Open")
.unbind().bind("click", function (e) {
$(this).removeClass("Open");
e.stopPropagation();
});
});
});
This will make sure the parent event will not fire when the icon is clicked..
Also every single time you click the icon the event for the parent is bound again which will create multiple click events .. Need to make sure you unbind and bind them again to avoid that..
It is firing right away because the click event is bubbling to the parent and then firing that selector. To fix this you could use a setTimeout() around the 2nd bind.
$(function () {
$(".ui-dropdown-action").bind("click", function () {
var parent = $(this).parent();
parent.addClass("Open");
setTimeout(function() {
parent.bind("click", function () {
$(this).removeClass("Open");
});
}, 0);
});
});
Another option would be to to a stopPropagation() on the event on your first bind, though that would prevent any other handlers from triggering on that event.
In my case, when I use something like this
$("#modal .button")[0].click(() => console.log('test'))
its doesnt work and seems like click firing immediately
Solution for me was:
const button = $("#modal .button")[0];
$(button).click(() => console.log('test'));