Is there a generally accepted method to change the action of a JavaScript event?
The following seems clean, but doesn't work as the first event is bound to #link when the page is rendered, and nothing changes when the class changes. Does it sound like I understand this correctly?
$('#change-to-option-1').click(function(){$('#link').attr('class','option-1');});
$('#change-to-option-2').click(function(){$('#link').attr('class','option-2');});
$('.option-1').click(function(){alert('option 1');});
$('.option-2').click(function(){alert('option 2');});
Option 1
Option 2
Click Me
Or should I have one event, and put logic in it based on the element's class (or maybe data()) instead as shown?
$('#link').click(function(){
if( ('#link').attr('class')=='option-1') {alert('option 1');}
else{alert('option 2');}
});
Or is there a generally more accepted approach?
If you want to make an event trigger for an element after changing its class/any identity that you used to bind the event initially. Then you have to go for event delegation.
$(document).on("click", ".option-1", function(){ alert('option 1'); });
You can expect the code to be optimized if you use any closest static parent of .option-1 instead of document
I would not recommend and prefer hardcoding anything. So here's a solution which would take care of what you are trying to do.
$('#change-to-option-1,#change-to-option-2').click(function(){
$('#link').attr('class',this.id.split('-')[2] + '-' + this.id.split('-')[3]);
});
$('#link').on('click',$(this).attr("class"), function()
{
alert($(this).attr("class"));
});
Working example : https://jsfiddle.net/DinoMyte/39fvpstq/
If you plan to introduce more anchor links with a similar id structure :
$('[id^=change-to-option-]').click(function(){
$('#link').attr('class',this.id.split('-')[2] + '-' + this.id.split('-')[3]);
});
$('#link').on('click',$(this).attr("class"), function()
{
alert($(this).attr("class"));
});
Working example : https://jsfiddle.net/DinoMyte/39fvpstq/1/
If you wish to put everything in one event block :
$('#change-to-option-1,#change-to-option-2').click(function(){
$('#link').unbind('click');
$('#link').attr('class',this.id.split('-')[2] + '-' + this.id.split('-')[3]).on('click',$(this).attr("class"), function()
{ alert($(this).attr("class"));
});
});
Example : https://jsfiddle.net/DinoMyte/39fvpstq/2/
Related
On page load, I have a search box that, once used, populates a div with multiple images. The javascript from the search uses this function to append all images into the div
function appendSomeItems(url, id, name, style) {
return '<div><div class="md-card md-card-hover"> <div id="getImage" class="gallery_grid_item md-card-content"> <img class ="uk-align-center imageClick"></a> <div class="gallery_grid_image_caption"> <span class="gallery_image_title uk-text-truncate">' + name + '</span> <span>' + style + '</span> </div></div></div></div>';
}
This works perfectly. Now I'm trying to make it so that when I click any one of the images it triggers an action (in this case a console log)
$('.imageClick').click(function handleImage() {
console.log(good);
});
However, it does nothing. No error but no console log.
What am I doing wrong here?
You need to use event-delegation in order to bind an event to dynamically created elements:
This approach uses document as the parent element, however, a good practice is to use the closest parent element.
$(document).on('click', '.imageClick', function handleImage() {
console.log(good);
});
Try with .on() to attach event on dynamically created element. This will allow attaching the event to the elements that are added to the body at a later time:
$('body').on('click', '.imageClick' function handleImage() {
console.log(good);
});
The problem is that you are calling $(".imageClick").click() before you dynamically create the items.
This means that jQuery doesn't actually bind the click listener to the items, since when $(".imageClick").click() is run, the elements don't actually exist yet.
Try this:
$("body").on("click", ".imageClick", function handleImage() {
console.log("good");
});
Also see this post for more information: In jQuery, how to attach events to dynamic html elements?
I understand that you need to use ".on" to use code that you loaded with jquery after the page has loaded. (At least I think it works that way)
So I tried that but it somehow just doesn't do a thing at all. No errors in the console either.
$("#forgot_password").click(function(){
var forgot_password = '<div id="toLogin" style="cursor:pointer;">Prijava</div>'
$("#loginPopupForm").html(forgot_password);
});
$("#toLogin").on("click", function(){
alert("Hello");
});
So when I click on #forgot_password it does execute the first click function. But when I click on #toLogin it doesn't do anything and I think its because its loaded with jquery when I click on #forgot_password
Try this
$("#loginPopupForm").on("click", "#toLogin", function(){
alert("Hello");
});
You need to bind to an element that is present when the page loads, like body for example. Just change your code to what is shown below
$("body").on("click", "#forgot_password", function(){
var forgot_password = '<div id="toLogin" style="cursor:pointer;">Prijava</div>'
$("#loginPopupForm").html(forgot_password);
});
$("body").on("click", "#toLogin", function(){
alert("Hello");
});
You are setting the on to the wrong thing. You want it to be:
$(document).on('click', '#toLogin', function() {alert('hello') });
The id isn't there until you do the other click event, so jQuery is not finding any element to set the click event on. You need to have an element that has been rendered in the DOM to set the event on.
You are totally right about the problem : on() targets only elements that are already existing as it runs.
What you need in jQuery is called Delegated event and is well explained on the Jquery doc page.
The difference in the code is thin, but it's how you're supposed to do.
You have to specify the parent element
$("#toLogin").on("click","#loginPopupForm", function(){
alert("Hello");
});
in the 2nd argument of the on
I am currently working on a website and got stuck with the following problem:
On the website I have small dots (images) with the ids "dot0001", "dot0002", "dot0003", etc. . I also have hidden images (visibility:hidden) with the ids "info0001", "info00002", "info0003", etc.
I am looking for a jQuery solution. What I need is a code that allows the following events:
When users move the mouse over "dot0001" the image "info0001" becomes visible and when they leave "dot0001", "info0001" becomes invisible again. Same applies to "dot0002"-"info0002" , "dot0003"-"info0003" etc. So only the info-images with the corresponding 4 digit number become visible.
I gave it endless tries but got nowhere and there is not even a point in pasting my code.
Any help appreciated!
Something like this should work (though untested):
$('[id^="dot"]').on({
mouseenter: function(e) {
var infoId = this.id.replace('dot', 'info');
$('#' + infoId).show();
},
mouseleave: function(e) {
var infoId = this.id.replace('dot', 'info');
$('#' + infoId).hide();
}
});
That uses an attribute-starts-with selector to select all elements with an id beginning with "dot", then binds the event handlers to them. The event handler functions themselves simply replace the "dot" part of the id with "info" to form the correct new one, then show or hide the element as appropriate.
Don't forget to wrap that code in a DOM ready event handler so that it executes once the elements actually exist, otherwise it won't work.
Get all elements which id starts with "dot" and show/hide related "info" on mouseover/out:
$("[id^=dot]").hover(
function(){
$("#info" + this.id.substring(3)).css({"visibility":"visible"});
},
function(){
$("#info" + this.id.substring(3)).css({"visibility":"hidden"});
}
);
http://jsfiddle.net/EGBnR/
I'm trying to manipulate an id to use the same button to do more then 2 actions.
its something like:
var id;
if(something == 2){
id = "id";
}else{
id = "id2";
}
$(".myClass").attr("id", id);
but, its not good, because if i try to use the id that i set, won't work, maybe because the document was already loaded with no id in the button.
dont think this need a example, but i made it.
have another way to do this ?
If you need to bind actions to some future element, it's generally best to use delegation, meaning to listen for the events not on the elements themselves, but on one of their ancestors:
$("body").on("click", "#id2", function(){
alert( "Clicked!" );
});
At this point, you can set the ID dynamically:
$(".myClass").attr("id", function(){
return something === 2
? "id"
: "id2" ;
});
While I am listening for the click event on the body, it's generally best to use a closer parent element so the event doesn't have to bubble too much before being handled.
Use this:
$(document).on('click', '#alertMe', function(){
alert('Working');
});
Try like this
$("#alertMe").live("click",function(){
alert('Working');
});
Don't use 'click()' to bind the handler, use live:
$("#alertMe").live('click', function(){
alert('Working');
});
The reason is that the click method is a one time deal. It adds the click event to that id at the point it runs. To dynamically handle click event on that id use on like this:
$(".button1").click(function(){
$(".button2").attr("id", "alertMe");
});
$(document).on('click',"#alertMe", function(){
alert('Working');
});
Live example: http://jsfiddle.net/SWZMd/17/
You can also set the click after you set the id:
$(".button1").click(function(){
$(".button2").attr("id", "alertMe");
$("#alertMe").click(function(){
alert('Working');
});
});
Move second click event into the first click event, then it will work.
$(".button1").click(function(){
$(".button2").attr("id", "alertMe");
$("#alertMe").click(function(){
alert('Working');
});
});
http://jsfiddle.net/dcai/SWZMd/18/
I'm trying to make a notification area that will show alerts.
return this.each(function() {
jQuery('<div class="' + o['className'] + '">' + o.msg + ' +
'X' + '</div>')
.appendTo(this);
});
This just takes a message pulled from the database, and shows it to the user. If the user clicks the X then it will call dismiss() which will mark it as being read in the database.
The thing is, if the message itself contains a link to another page or external site, I also want to call dismiss() before the user leaves the page. Is there anyway to alter this javascript to take all a elements (the X and any links that would appear in the message) and change the onclick to call the function?
You can rearrange your code a bit and use .delegate(), like this:
return this.each(function() {
var id = o["id"];
jQuery('<div />', { 'class': o['className'], html: o.msg })
.append('X')
.delegate('a','click', function() { $(this).parent().remove(); dismiss(id); })
.appendTo(this);
});
This uses the new jQuery(html,props) added in jQuery 1.4 to make the creation a bit cleaner (and faster! document fragment caching!). What it's doing is instead of attaching an onclick to the X, it's listening for a click from any <a> in the div and when it bubbles, it executes the same code as it used to only on the X anchor.
The code example is a bit vague, where does this o come from? Is it global or something div-specific?
At any way, you may find jQuery.live() useful for this. Once initialized, it will be applied on all future new elements matching the selector. You only need to have some parent element which is going to contain all of those divs with the messages and the links.
$('#someDivId a').live('click', function() {
// Do your thing here as you did in `onclick` attribute.
};
Just execute it once during onload.