jQuery fadeOut() Only Works Once - javascript

I am using jQuery to fade out a "notification" bubble I built. The first time the function is called it fades out just fine, but the second time the "notification" is appended to the body, but just sits there and doesn't fade out. Any help would be greatly appreciated.
Here is the Javascript that is being called.
if (pointsCalculated = 1) {
$('body').append('<div id="progress">' + pointsCalculated + ' point added to current points...</div>');
}
else {
$('body').append('<div id="progress">' + pointsCalculated + ' points added to current points...</div>');
}
//Reset calculator after adding to tracker
calcReset();
$("#progress").fadeOut(2000);

Try removing the element after the fadeOut:
$("#progress").fadeOut(2000, function() { $(this).remove(); });
More info:
.remove()
.fadeOut()

Javascript canĀ“t find more then one element with an ID, and its already faded out when you want to run it again.
you can change the id to an class and then find all .progress that is visible and not animated to start the fadout on that item, and when its done you can remove it so you dont have to many .progress
$('body').append('<div class="progress">' + pointsCalculated + ' ' + (pointsCalculated === 1 ? 'point' : 'points') + ' added to current points...</div>');
//Reset calculator after adding to tracker
calcReset();
$(".progress:visible:not(:animated)").fadeOut(2000, function() { $(this).remove(); });
remember in javascript if you want to look if a variable is a value you will need to use at least two "=" else you will set the value to that variable.

You need to rebind the fadeOut event to the #progress element each time it is appended.

You must recreating your appended elements fadeOut binding when you add the element back to the DOM. You can create this binding immediately after the append and this should now work.

You code doesn't show you REMOVING "progress", so you're likely adding a new one each time. Since IDs much be unique, your code finds two and fails.

Related

onClick function used on dynamic content not working properly

I hit a problem with the onclick function when i add divs with ids like "n_block"+(1-~). When I use the jquery zoom function on the objects to make them smaller or bigger onClick doesn't work anymore. I'm not really good at programming so the code might be kind of confusing.
Heres the code i use for the onClick of items:
$(document).on("click",function (e, ui){
//When the document gets clicked, check if one of the items was clicked.
if($(e.target).is($("#n_block" + cloneCount1)) || $(e.target).is($("#n_block" + cloneCount1+ " span"))){
//Set current item.
var item = $("#n_block" + cloneCount1);
//Set style to current item.
item.css("border-color", "Black");
item.css("border-width","2px");
item.css("background-color", "floralwhite");
jsPlumb.repaintEverything();
//Check if key Delete was pressed while item selected & delete that item with his children.
$('html').keydown(function(e){
if(item.css("border-width")=="2px"){
if(e.keyCode == 46) {
/* Prevents line bugging*/
jsPlumb.detachEveryConnection();
jsPlumb.deleteEveryEndpoint();
var razred = getClass(item, "b_"),
id = item.prop("id");
item.remove();
if(razred == "b_2"){
$(".ovoj."+id).remove();
}
else if (razred == "b_4"){
$(".ovojLoop."+id).remove();
$(".empty_block_c."+id).remove();
}
if ( $('.objects').find('div').length == 2) {
$(".objects").empty();
$(".objects").append('<div class="b_s" id="start_block">START</div><p id="start_text">Insert symbols here!</p><div class="b_s" id="end_block">STOP</div> ');
}else{
/* Connects objects together with line. ****/
povezi(cloneCount, tip_crte, ".objects");
}
}
jsPlumb.repaintEverything();
}
});
}
// If item is not clicked set this css to the current item.
else{
$("#n_block" + cloneCount1).css("border-width","1px");
jsPlumb.repaintEverything();
}
});
And heres the zoom code for zooming in when button is clicked:
var currentZoom = 1.0;
$(".zoomin").click(function (){
//Detaches the connections from item to item.
jsPlumb.detachEveryConnection();
jsPlumb.deleteEveryEndpoint();
//Prevents spamming of button, animates the objects
$(".project").stop().animate({ "zoom": currentZoom += .1}, "slow", function() {
if(!$(".objects").children().is($("p"))){
povezi(cloneCount, tip_crte, ".objects");
}
});
});
Use event delegation for binding events to dynamically added elements.
$(document).on('click', ".zoomin", function (){
//Your code.
});
When you use normal .click() to bind event to an element, then that even gets bound to only those elements which exist in the DOM at the moment of the execution of code. Using event delegation, you can tell jQuery that we need to add the handler to every '.zoomin' element which comes inside a particular element no matter when it is added.
The solution depends when exactly is the script which tries to bind the events are executed.
For Eg: Lets assume this script is in document ready function of jquery
$(document).ready(function(){
$(".zoomin").click(function (){
//your logic here
});
});
Here this script is executed when the page HTML is completed loading into the browser. Now when the script executes it tries to find a element with the class zoomin and if found it will add a event to that element and move on. If the element is not found the script just moves on. So we should actually take care of when the script is executed and is the intended element available at that particular instant of time. If the element is not yet available in the HTML (element might come in later dynamically using jquery) we have 2 options to bind event to the element.
1) Execute the script when the element is being added into the HTML: Lets say I have a event which brings up a pop up with some image. Now I want to zoomin and zoomout the image. Since the image in the popup is added dynamically and I have control of when its being added, I can do this.
$(document).ready(function(){
$('.ViewImage').on('click',function(){
// some code is executed which brings up the popup
// now we know that the image is added into html we can now run the script
$(".zoomin").click(function (){
//your logic here
});
});
});
2) We have no Clue/ Control when the element is added into HTML but still want to bind a event to it: This is scenario where we have no control on when the element is being added or not sure where it is being added from (might be from some external plugin used etc) or not having control at all on the element which is added. Thats when we use this syntax as suggested by #Rejith R Krishnan
$(document).on('click', ".zoomin", function (){
//Your code.
});
This will work on all the elements which are in the HTML at the time of execution of the script and on the elements which will be added in the future with the class name zoomin. So this script can be placed inside/ outside of jquery document ready event

Change event action based on other event

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/

L.DomEvent.addListener() vs on(): why does one NOT work?

I created the following jquery script to cycle through each div in my HTML using a for loop. In this for loop, I define the the div and add a listener to it:
for (var i = 0; i < 3; i++) {
// Define listing
var listing = $('div[data-rid="' + i + '"]');
// Add listener to each listing div
// See below...
}
I have tried two different ways to add a listener. The first uses L.DomEvent.addListener() as such:
L.DomEvent.addListener(listing, 'mouseover', function(e) {
// Do stuff to listing div
}
The second uses the action mouseover():
listing.mouseover(function(e) {
// Do stuff to listing div
}
The L.DomEvent.addListener approach does not work. The mouseover approach works (i.e., it triggers for each div mouseover), but the "Do stuff to listing div" code only happens to the last listing div in the for loop. For example, I might mouseover div #1, but it "does stuff" div #3.
Does anyone have an idea how I might fix this issue?
Thanks!
Jesse
Try
L.DomEvent.addListener(listing[0], 'mouseover', function(e) {
// Do stuff to listing div
}
The case is, that the element jquery returns, is an array of the elements it found. listing[0] gets the first element in said array.

jQuery: mouseover makes image visible that has the same last 4 numbers in their id as the trigger

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/

Making all links inside of a div call the same function?

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.

Categories

Resources