I'm writing my first jquery code and I've to write a random slider that will get images through a php function and will show them in a sequence with some decoration. Random thing is done in php. My jquery is as follows.
function bannerSlide(){
$.ajax({
type: "GET",
url: "test.php",
dataType: 'json',
success: function(images) {
$.each(images, function (index, value) {
$('#banner').slideUp(500).delay(2000).fadeIn(500).css('background', 'url(ItemPictures/'+value+')');
});
}
});
}
I get images in images array and loop through it.
The problem I'm facing is that my this code only shows the last image in array. other images are not shown and it keeps sliding the last image of array.
But if I put an alert statement inside $.each function then image changes after I click on ok of alert box and it goes on.
Any help will be highly appreciated.
Please don't suggest to use some already built slider.
The each loop will run in microseconds and set the css value immediately on each pass with your code. Thus you only see the last image
Here's a solution using setTimeout and changing the css within the callback of the first animation so the css only gets changed at appropriate time. You may need to adjust the timeout interval index*3000
$.each(images, function(index, value) {
setTimeout(function() {
$('#banner').slideUp(500, function() {
/* use callback of animation to change element properties */
$(this).delay(2000).fadeIn(500).css('background', 'url(ItemPictures/'+value+')');
})
}, index * 3000);
});
DEMO using text change of element http://jsfiddle.net/RrPu6/
Following code is solution to the posted problem.
function bannerSlide(){
$.ajax({
type: "GET",
url: "test.php",
dataType: 'json',
success: function(imgs) {
var cnt = imgs.length;
$(function() {
setInterval(Slider, 3000);
});
function Slider() {
$('#imageSlide').fadeOut("slow", function() {
$(this).attr('src', 'ItemPictures/'+imgs[(imgs.length++) % cnt]).fadeIn("slow");
});
}
}
});
}
where imageSlide is id of an img tag inside 'banner' 'div'
The problem is that you are iterating over the array of images, and for each one you're setting the background of the same DOM element... $('#banner'). This is going to happen so fast that you'll only see the last image, at the end of the iteration. This is also why you can see it changing if you alert() in between, because execution is paused during alert().
You'll have to figure out a way to delay the changing of the background. One thing you can try is adding an increasing delay() before your slideUp(). Something like:
function bannerSlide(){
$.ajax({
type: "GET",
url: "test.php",
dataType: 'json',
success: function(images) {
var duration = 2000;
var element = $('#banner');
$.each(images, function (index, value) {
element.delay(index * duration).slideUp(500).delay(duration).fadeIn(500).css('background', 'url(ItemPictures/'+value+')');
initialDelay += duration;
});
}
});
}
It's an ugly hack, but that's why those already built sliders exist :)
Related
So, I have a jQuery AJAX call that gets data from the server (some text, some links).
Inside AJAX success callback function I got a .on that is bind to <a> that load for me next page and get me the text of the clicked link (let's say stackoverflow.com).
The problem starts here because in the newly loaded page I got anchors...
After every click on anchor links I got new .text() value.
$.ajax({
url: url,
type: type,
dataType: dataType,
success: function(data){
$('.container').append(data);
$('.container').on('click', 'a', function(e){
e.preventDefault();
var clickLinkName = $(this).text();
console.log(clickLinkName);
$('.container').load($(this).attr('href'));
});
}
});
I would like to know how to lock clickLinkName variable. OR any other way to save only first hit.
I think this would do the trick:
$.ajax({
url: url,
type: type,
dataType: dataType,
success: function(data) {
$(".container").append(data);
var clickLinkName; // Declared here.
$(".container").on("click", "a", function(e) {
e.preventDefault();
// If not initialized, initialize.
if(!clickLinkName) {
clickLinkName = $(this).text();
}
console.log(clickLinkName);
$(".container").load($(this).attr("href"));
});
}
});
That would save only the first value in the variable clickLinkName. This answers your question, but I'm sure there are better ways of doing this.
I have this function already, which checks for change, and if true only updates this div.
jQuery(document).ready( function($) {
var auto_refresh = setInterval(function() {
$.ajax({
success: function(data) {
var result = $('<div />').append(data).find('div#vs').html();
$('div#vs').html(result);
}
})
}, 5000); // refreshing after every 5000 milliseconds
})
This works great, but now I want to add another function, I have made this javascript http://jsfiddle.net/jockebq/ocLh1rLd/
What it does is that if the height of the div #vs exceeds 300px it will add class .vscroll to #vs.
I have managed to make this work great in JSFiddle, but I cannot figure out how to merge this together with my javascript above.
I'm very much stuck, and I cannot find any information on how to do this. All help and tips are much appreciated!
I am sure i am missing something here but why not just
add it inside the function passed to setInterval and run it alongside the ajax call
var auto_refresh = setInterval(function() {
$.ajax({
success: function(data) {
var result = $('<div />').append(data).find('div#vs').html();
$('div#vs').html(result);
if (document.getElementById('vs').clientHeight > 300 )
$('div#vs').addClass('vscroll');
}
});
}, 5000); // refreshing after every 5000 milliseconds
})
PS: Your ajax better not be as you pasted it here!
EDIT: added the code in the success callback, since you probably want to resize when the new content is appended,as said by Pierre
I've been trying to figure out this semi-specific problem for the past couple days, and I could really use another pair of eyes on it.
My goal is to have an image on the page. It starts out as a static png, and when it's clicked, it swaps out with a .gif and plays an animation. When it's click on again, it swaps again and plays a second .gif animation. It does the same thing a third time. When the 3rd .gif is clicked on, it plays the 1st gif animation again, and the process starts all over again.
My issue is that multiple images are loaded on the page, and some have 3 total gif animations, some have 2, and some have one.
So what I'm trying to do is check if the .gifs exist before I load the next one.
Here's an excerpt with some of my notation...
$('#postContainer img').click(function () {
imgSrc = $(this).attr('src');
if(imgSrc.indexOf('_B.png') != -1){
imgSrcToUse = imgSrc.replace('_B.png', '_pt1.gif');
$(this).attr('src', imgSrcToUse);
return false;
}
That code above runs when the image is clicked. It finds the image src, and replace the static png with the first animated gif. all the images have an animated gif, so this isn't a problem.
if (imgSrc.indexOf('_pt1.gif') != -1) {
var POS2 = imgSrc.replace('_pt1.gif', '_pt2.gif');
$.ajax({
url: POS2,
type: 'HEAD',
error: function() {
alert('error');
imgSrcToUse = imgSrc.replace('_pt1.gif', '_pt1.gif');
},
success: function() {
alert('success');
imgSrcToUse = imgSrc.replace('_pt1.gif', '_pt2.gif');
}
});
$(this).attr('src', imgSrcToUse);
return false;
}
After _pt1 is loaded, then this function runs the next time you click. it is supposed to check if a _pt2 exists, and if it does, then swap out the pt1 with pt2. HOWEVER, it only seems to be working on the second click. if i click it once, it loads _pt1 again, and then the second time through it will load _pt2 properly. this is where my major problem lies...
i apologize if this is convoluted but i'm really stumped here. i'll try to do my best to clear things up if you guys are way too confused.
Here is your issue:
$.ajax({
url:POS2,
type:'HEAD',
error: function()
{
alert('error');
imgSrcToUse = imgSrc.replace('_pt1.gif','_pt1.gif');
},
success: function()
{
alert('success');
imgSrcToUse = imgSrc.replace('_pt1.gif','_pt2.gif');
}
});
$(this).attr('src',imgSrcToUse);
That last line of code is trying to use your variable imgSrcToUse, which doesn't contain the result of your AJAX query yet. AJAX is asynchronous, so your $.ajax call returns and moves onto the next line before the success (or error) callbacks are called. You can resolve this by moving the code using the data from the callbacks into the callbacks:
var $that = $(this);
$.ajax({
url: POS2,
type: 'HEAD',
error: function () {
alert('error');
var imgSrcToUse = imgSrc.replace('_pt1.gif', '_pt1.gif');
$that.attr('src', imgSrcToUse);
},
success: function () {
alert('success');
var imgSrcToUse = imgSrc.replace('_pt1.gif', '_pt2.gif');
$that.attr('src', imgSrcToUse);
}
});
You were seeing sucess on the second call because you were assigning the next image name to a global variable. You should use var to avoid this.
On changing the select option i am displaying the image and on success of ajax call hiding that image .. but this happens very fast .. i want to display the image for some time say 2 seconds. how to do it
my code
var div_id = $(this).closest('tr').find('.display_image').attr("id");
$("#"+div_id).empty().html('<img src="${resource(dir:'images',file:'spinner.gif')}"/>');
$("#"+div_id).show();
$.ajax({
type: "POST",
url:"${createLink(controller:'s2PublicLifecycle',action:'UpdateField')}",
data: dataString,
success: function() {
$("#"+div_id).hide();
}
});
use jquery delay:
$("#"+div_id).delay(2000).hide(1);
Here's a jsfiddle
try setTimeout(function() { $("#"+div_id).hide(); }, 2000 );
I have a collapsed list.
On Ajax success, list auto-expands.
I'm trying to get height of that expanded list ... and failing.
Ajax adds dynamically elements to list, so height changes.
Here is stripped code:
$('form').submit(function() {
$.ajax({
type: "POST",
url: "ajax/ajax.php",
data: {data:JSON.stringify(data)},
dataType: "json",
success: function(x) {
$('#slider' + x.id).children('ul,li').slideDown("slow");
//this does not return expected height (outerHeight() also tried)
var t = $('#slider_' + x.id).height();
}
});
return false;
});
I'm assuming the slideDown animation takes it time and when you've tried to get the height it has already changed.
You could use a callback for your animation, and get the height after the animation is over:
$('#slider' + x.id).children('ul,li').slideDown("slow", function()
{
//this executes AFTER the animation is complete.
var t = $('#slider_' + x.id).height();
}