JQuery click function order - javascript

I would like to know how can I change the background-image of another div element, when I click on it. I would like to see images one after another in order but what I get is the last one. Here is some code:
$(document).ready(function () {
// console.log('ready!');
$('.right').click(function () {
$('.zur-gda-img').css('background','url(images/sail-boat.jpg)');
}).click(function() {
$('.zur-gda-img').css('background','url(images/sad_ostateczny.jpg)');
}) }).click(function() {
$('.zur-gda-img').css('background','url(images/twierdza_wisloujscie.jpg)');
});

Instead of adding multiple event handler use single. Inside handler change images from the array with help of a counter variable.
$(document).ready(function() {
// store images in an array
var images = ['url(images/sail-boat.jpg)', 'url(images/sad_ostateczny.jpg)', 'url(images/twierdza_wisloujscie.jpg)'],
// variable to store index
i = 0;
$('.right').click(function() {
// update index based on array length
i = i % images.length;
// update background from array using the index value
$('.zur-gda-img').css('background', images[i++]);
})
});

You don't need three event handlers for this (they will just fire one after another and you'll only see the last image). If you want to see images changing, try the following:
$(document).ready(function () {
// document has loaded
$('.right').click(function () {
// 1st image:
$('.zur-gda-img').css('background','url(images/sail-boat.jpg)');
// 2nd image, appears in a second:
setTimeout(function() {
$('.zur-gda-img').css('background','url(images/sad_ostateczny.jpg)');
// 3rd image, appears in another second:
setTimeout(function() {
$('.zur-gda-img').css('background','url(images/twierdza_wisloujscie.jpg)');
},
1000);
},
1000);
});
});

Related

Remove dynamically added div on timer

I'd like a div to appear for a short duration of time and then go away.
So, I dynamically create the div on the click of a button, and then after some work is done, I'd like it to be removed from the DOM.
So, I set up a timer like so:
var contentJoinTab = $("#...");
var divIdSubscribePleaseWait = "div-subscribe-pleasewait";
btnSubscribe.on("click", function (event) {
displaySubscriptionWait();
postMailingListSubscription();
});
function displaySubscriptionWait() {
var s = `<div id = ${divIdSubscribePleaseWait} class = "${classMailingListPleaseWait}">Please wait...</div>`;
contentJoinTab.append(s);
};
function postMailingListSubscription() {
// fake for now
window.setTimeout(function() {
removeSubscriptionWait();
}, 4000);
};
function removeSubscriptionWait() {
contentJoinTab.parent(`${divIdSubscribePleaseWait}`).remove();
// I've even tried the following to no avail
// $(`${divIdSubscribePleaseWait}`).remove();
// contentJoinTab.find(`${divIdSubscribePleaseWait}`).remove();
};
However, even though there is no error in the call to the remove() method, the div I am trying to remove remains in the DOM and is visible.
I do understand event propagation but my understanding is that that's not relevant here. That would have been relevant if I wanted to attach an event to the click (or any other event) of the dynamically created div or any of its parent.
You may be missing # when calling removeSubscriptionWait And also need "" for id = ${divIdSubscribePleaseWait}.
Please see changes below in case it isn't clear:
function displaySubscriptionWait() {
var s = `<div id = "${divIdSubscribePleaseWait}" class = "${classMailingListPleaseWait}">Please wait...</div>`;
contentJoinTab.append(s);
};
function postMailingListSubscription() {
// fake for now
window.setTimeout(function() {
removeSubscriptionWait();
}, 4000);
};
function removeSubscriptionWait() {
contentJoinTab.parent(`#${divIdSubscribePleaseWait}`).remove();
// I've even tried the following to no avail
$(`#${divIdSubscribePleaseWait}`).remove();
};
You can do that by setting outerHTML of that div to null
function addDiv() {
let s = "<div id='tempDiv'>Temporary Div</div>"
let root = document.getElementById("root")
root.innerHTML += s;
}
function removeDiv() {
let theDiv = document.getElementById("tempDiv");
theDiv.outerHTML=""
}
addDiv()
setTimeout(removeDiv,2000)
<div id=root>
</div>
You have appended that div as a child of contentJoinTab but when you go to remove it you are looking for it as being parent of contentJoinTab
You also need to add the ID prefix in selector
try changing
contentJoinTab.parent(`${divIdSubscribePleaseWait}`).remove();
To
contentJoinTab.find(`#${divIdSubscribePleaseWait}`).remove();
update removeSubscriptionWait function :
function removeSubscriptionWait() {
contentJoinTab.find('#'+`${divIdSubscribePleaseWait}`).remove();
};

Add or Delete jQuery sortable element and remember order

I'm implementing something similar to this in one of my Wordpress metabox. User should be able to add and remove jquery-ui sortable elements and remember the position(order) of the elements exists.
I already know how to remember the position(order) when the elements are resorted by dragging and dropping.
jQuery(document).ready(function () {
jQuery('ul').sortable({
stop: function (event, ui) {
var data = jQuery(this).sortable('toArray');
jQuery('#elements-order').val(data);
}
});
});
This will output an array which contains the order like 1,2,3,5,4 But, when new elements are added or elements are deleted, how to make this code run to remember the order of the new elements.
This is the code I use to Add elements
jQuery(document).ready(function () {;
var wrapperSize = jQuery("#element-area-top").width();
(function () {
jQuery(".add-element").on("click", ".add-item", function () {
var start = jQuery("#sortable"),
selectBoxVal = jQuery("#element-list").val();
var element = null;
element = ('<li></li>');
var newRow = jQuery(element);
jQuery(start).append(newRow);
jQuery("#elements-order").val(jQuery('#elements-order').val() + i+',');
});
})();
This is the code I use to delete elements
jQuery("#sortable").on("click", ".delete", function () {
jQuery(this).parents(/*someelement*/).remove();
});
So, could anyone know how to do this ?
You can get sort order with same logic in add/delete functions as well (just replace this with '#ul').
var data = jQuery('#ul').sortable('toArray');
jQuery("#elements-order").val(data);
Or even better, put above code in a common function and just call common function. Here is updated fiddle demonstrating same.

jQuery .load on image fires once

Context
A user page with HR information.
I have a menu under the user picture which has an unfixed size.
I update the menu margin-top when the picture is loaded:
_setMenuMarginTop: function () {
var that = this;
$('#picture > img').load(function () {
that.$el.css('margin-top', $(this).height() + 'px');
});
}
When the current user is changing, I update the page (user info, user picture img) then I recall the method _setMenuMarginTop as the picture size isn't the same:
initialize: function () {
this.listenTo(app.curUser, 'sync', this._updateView);
},
...
_updateView: function () {
this._setMenuMarginTop();
// Other stuffs...
},
But this time jQuery doesn't fire the .load method.
Questions
Any idea why?
Does it work only once?
Workaround?
More info
The img update into an other view:
initialize: function () {
this.listenTo(app.curUser, 'sync', this._updateCurUserInfo);
}
...
_updateCurUserInfo: function () {
this.$el.find('#picture').html( this.templatePicture({ 'url' : getPictureUrl(app.curUser.get('picture')) }) );
// Other stuffs...
}
How about triggering the onload handler again ?
_setMenuMarginTop: function () {
var that = this;
$('#picture > img').on('load', function () {
that.$el.css('margin-top', $(this).height() + 'px');
}).each(function() {
if (this.complete) $(this).trigger('load');
});
}
And note that's it's an event handler, calling the function again just applies another event handler.
This happens because the new image doesn't have the load function on it. Replacing the image breaks the event. You can use the jQuery on function to always fire the event on all images that are in the #picture div:
$('#picture').on('load', 'img', function() {
that.$el.css('margin-top', $(this).height() + 'px');
})
That should do it. This would replace your $('#picture > img').load(function () { line
What this does is attach the event to the '#picture' div, but actually fire when an 'img' inside the #picture div is loaded.
This way, if the picture is removed, the event isn't removed as well.
I believe assigned image src should be different each time for load to fire. Consider following demo: http://jsfiddle.net/j4tP8/1/
I am using basic image and button
<button id="one">One</button>
<img id="img" />
Which connected via
$('#one').click(function() {
$('#img').attr('src','https://site/image.jpg')
})
$('#img').load(function() {
alert('loaded');
})
When you click the button - image is assigned source. As it is load event will fire only once. But f you modify the code by adding random string to the source:
$('#one').click(function() {
$('#img').attr('src','https://site/image.jpg?' + Math.random() )
})
load will fire every time.

Temporary creation of html div using Jquery

I am trying to create div's on demand which then timeout and are then hidden and removed from the dom.
The display property of "load_bar" is set to none so that I can use the last selector to get a reference to the instance I have just created.
It is important that this solution can create several div's which are running on their own timeout clock
$(document).ready(function () {
$('#add').click(function () {
var t = Math.random()*20;
alert(t);
var destination = $('input').val();
$('#holding_pen').append('<div class="load_bar">'+destination+'</div>');
$('.load_bar:last').show().delay(t).hide().remove();
});
});
Every thing works to create divs when I remove .delay().hide().remove();
However when I add this the div is not shown at all
Create proper elements, that way you'll have a reference to the element within the function:
$(document).ready(function () {
$('#add').click(function () {
var t = (Math.random()*20)*1000,
destination = $('input').val(),
div = $('<div />', {'class':'load_bar', text: destination});
$('#holding_pen').append(div);
div.show(1).delay(t).hide(1, function() {
$(this).remove();
});
});
});
Also, hide() and show() does not work with the animation queue and subsequently not with delay() unless a duration is given, and that's why the element is never shown, delay() doesn't work and the element is hidden right away.
EDIT:
Also, remove() is not an animated method, so it doesn't work with delay(), but hide() a useful callback for that, see edited code above.
FIDDLE
The problem is because delay is used to stop jQuery animation queue, which both show and hide do not use. Therefore your div is being shown and them immediately hidden. Use setTimeout instead:
$('#add').click(function () {
var destination = $('input').val();
$('#holding_pen').append('<div class="load_bar">'+destination+'</div>');
$('.load_bar:last').show();
setTimeout(function() {
$('.load_bar:last').hide();
}, Math.random() * 20 * 1000); // * 1000 = seconds
});
Example fiddle
The delay() function only applies to actions queued on the element.
$(document).ready(function () {
$('#add').click(function () {
var t = Math.random()*20;
alert(t);
var destination = $('input').val();
$('#holding_pen').append('<div class="load_bar">'+destination+'</div>');
$('.load_bar:last').show().delay(t).queue(function( nxt ) {
$(this).hide().remove();
nxt(); // continue the queue
});
});
});
$(document).ready(function () {
$('#add').click(function () {
var t = Math.random()*20;
alert(t);
var destination = $('input').val();
$('#holding_pen').innerHTML='<div class="load_bar">'+destination+'</div>';
});
});

Loading GIF to match with the loading time of a DIV. Jquery

I have a javascript that retrieves the values checked from a set of checkboxes and loads a DIV passing those values.
Currently I show a "loading" .gif before the load of the DIV. However, it has time fixed.
I would like to set the time of this GIF until the DIV has loaded its contents completely, so the user knows that data is loading in case sometimes is slower than others.
Any idea?
Thanks!
$(function() {
$("input[type='checkbox']").on('change', function() {
var colors = [];
$("input[type='checkbox']:checked").each(function() {
colors.push(this.value);
});
if (colors.length) {
$(".loadingItems").fadeIn(300);
$(".indexMain").load('indexMain.php?color=' + colors.join("+"), function() {
$(".indexMain").fadeIn(slow);
});
$(".loadingItems").fadeOut(300);
} else {
$(".loadingItems").fadeIn(300);
$(".indexMain").load('indexMain.php', function() {
$(".loadingItems").fadeOut(300);
});
}
});
});
As suggested by #Fabricio Matte, the solution was to put the first Fade Out inside the load
inside the function launched with the load:
$(".indexMain").load('indexMain.php?color=' + colors.join("+"), function() {
$(".indexMain").fadeIn(slow);
$(".loadingItems").fadeOut(300);
});

Categories

Resources