jQuery rotating through list items in a gallery - javascript

This has probably been answered before and I already know how this should work, but for some reason it is not. I think it may be how I am looping through the elements.
$(document).ready(function() {
var element = '#gallery ul#gallery-container';
var idx=0;
var timeout = 3000;
var number = $(element + ' li').length;
function changeSlide() {
$(element + ' li:eq(' + idx + ')').fadeOut();
idx = idx + 1;
if (idx == number) {
idx=0;
}
$(element + ' li:eq(' + idx + ')').fadeIn().delay(timeout).delay(0, function() {
changeSlide();
});;
}
$(element + ' li').hide();
$(element + ' li:first').fadeIn().delay(timeout).delay(0, function() {
changeSlide();
});
});
Then the list is like this:
<div id="gallery">
<ul id="gallery-container">
<li><img src="media/images/screen-shot-02.jpg" width="173" height="258" alt=" "></li>
<li><img src="media/images/screen-shot-01.jpg" width="173" height="258" alt=" "></li>
</ul>
</div>
I was trying to get it to loop through the elements one by one, after a delay so the list item calls the function and hides itself, then the counter is incremented and then the current index is shown.
I suspect the culprit to be this as if I put an alert in the function it is called:
$(element + ' li:eq(' + idx + ')').fadeOut();

The main problem is, as the comment states, delay does not do what you think it does - you should be looking at the native setTimeout function instead. In addition to that, there are multiple places where this could be made more efficient. Have a look at this:
var element = $('#gallery-container li'),
length = element.length,
current = 0,
timeout = 3000;
function changeSlide() {
element.eq(current++).fadeOut(300, function(){
if(current === length){
current = 0;
}
element.eq(current).fadeIn(300);
});
setTimeout(changeSlide, timeout);
}
element.slice(1).hide();
setTimeout(changeSlide, timeout);
We try not to evoke the jQuery function with a dynamically generated selector, but instead manipulate a single instance of a jQuery object containing all the slides cached at the start. We also use the callback function provided by the fade functions to fade in the next slide after the current one has faded out.
See http://www.jsfiddle.net/b3Lf5/1/ for a simple demo

I would do it something like this:
$(document).ready(function() {
var element = '#gallery ul#gallery-container';
var idx = 0;
var timeout = 3000;
var number = $(element + ' li').length;
setInterval(function () {
idx = (idx + 1) % number;
$(element + ' li:visible').fadeOut();
$(element + ' li:eq(' + idx + ')').fadeIn();
},timeout);
$(element + ' li:not(:first)').hide();
});
Or better still, wrap it in a plugin:
(function ($) {
$.fn.customGallery = function (options) {
defaults = {
timeout : 3000
};
options = $.extend(defaults, options);
return this.each(function () {
var idx = 0, number = $(this).children('li').size(), element = this;
setInterval(function () {
idx = (idx + 1) % number;
$(element).children('li:visible').fadeOut();
$(element).children('li:eq(' + idx + ')').fadeIn();
},options.timeout);
$(element).children('li:not(:first)').hide();
});
};
}(jQuery));
jQuery(document).ready(function($) {
$('#gallery-container').customGallery()
});
edit: Edited the plugin code to bring it into line with good practice.

Related

FULLPAGE.JS Get .active slide and update the number on each new slide

I'm trying to get the
current slide / total slides
on Fullpage.js and get the current slide updated everytime the slide changes.
I'm a total newbie on Javascript and I'm trying to work around this code. The numbers appear but they do not update every slide change.
$(function() {
var sections = $('.section');
updateCurrentIndex(); //on document.ready and on each slidechange
function updateCurrentIndex() {
sections.each(function() {
var section = $(this),
sectionSlides = section.find('.slide'),
totalItems = sectionSlides.length,
currentIndex = sectionSlides.filter('.active').index() + 1,
numContainer = section.find('.num'); //assuming you have numContainers in every section
numContainer.html("0" + currentIndex + ' / ' + totalItems);
});
}
});
Any help would be greatly apprciated.
https://jsfiddle.net/0hLzxrea/66/
You should be makeing use of the fullPage.js callbacks, such as onSlideLeave or afterSlideLoad.
For example:
$('#fullpage').fullpage({
anchors: ['firstPage', 'secondPage', 'thirdPage', 'fourthPage', 'lastPage'],
afterSlideLoad: function( anchorLink, index, slideAnchor, slideIndex){
var loadedSlide = $(this);
var totalItems = loadedSlide.siblings().length;
var numContainer = loadedSlide.closest('.fp-section').find('.num');
numContainer.html("0" + slideIndex + ' / ' + totalItems);
}
});
Update Dec 2021 - fullpage.js v3
This is much easier now with the new methods getActiveSlide and getActiveSection that fullPage.js provides. See the docs for more info.
Codepen online
new fullpage("#fullpage", {
sectionsColor: ["yellow", "orange", "#C0C0C0", "#ADD8E6"],
anchors: ["firstPage", "secondPage", "thirdPage", "fourthPage", "lastPage"],
slidesNavigation: true,
afterSlideLoad: function (origin, destination, direction) {
setCounter();
},
afterRender: function(){
setCounter();
}
});
function setCounter(){
var sectionItem = fullpage_api.getActiveSection().item;
var numSlides = sectionItem.querySelectorAll(".fp-slide").length;
var currentSlideWrapper = document.querySelector(".counter");
var slideNumber = fullpage_api.getActiveSlide().index + 1;
currentSlideWrapper.innerHTML = "0" + slideNumber + " / " + numSlides;
}
I'm here at the moment and I'm sure very close to the solution.
The problem, still, is that if you go up to the previous .section the counter will always be 01 / XX instead of showing the number of the actual .active slide.
afterLoad: function(index, nextIndex, direction) {
var loadedSlide = $(this);
var slideIndex = find(".fp-slide .active") + 1;
var totalItems = loadedSlide.closest(".fp-section").find(".fp-slide").length;
var numContainer = loadedSlide.closest(document).find(".num");
numContainer.html("0" + slideIndex + " / " + "0" + totalItems);
},
onLeave: function(index, nextIndex, direction) {
var section = $(this),
sectionSlides = section.find(".slide"),
totalItems = sectionSlides.length,
currentIndex = sectionSlides.filter(".fp-slide .active").length + 1,
numContainer = section.closest(document).find(".num");
numContainer.html("0" + currentIndex + ' / ' + "0" + totalItems);
}
})
});
https://jsfiddle.net/0hLzxrea/71/

How to get html of large div

I have a div which has lots of content. And i want to display an alert when content of that div changes(the div is refreshed every 60 sec). I tried $("div#divName").html() but it is not working as the div has a large content. So what an i do?
var $container = $("#load-scores");
$container.load("/include/home.php?ust=" + url_site + "&tz=" + tz);
var s= $("#load-scores").html();
var refreshId = setInterval(function()
{
$container.load("/include/home.php?ust=" + url_site + "&tz=" + tz);
var p = $('#load-scores').html();
if(p.is(s))
alert("changed");
}, refresh_time);
PS:
console.log(p) and console.log(s) is returns empty
You can use jquery's load() as a function.
var $container = $("#load-scores");
$container.load("/include/home.php?ust=" + url_site + "&tz=" + tz, function(){
alert("Changed");
});
var refreshId = setInterval(function()
{
$container.load("/include/home.php?ust=" + url_site + "&tz=" + tz, function(){
alert("Changed");
});
}, refresh_time);

How to iterate elements over time in jquery

I'm working on this automated, non-endless slideshow, with dynamically loaded content. Each image has to be acompanied by sound. So far I got dynamic loading of both images and sounds down. But it all happens at once, which it shouldn't. I figured, that setTimeout can come in handy here, to set the interval between each pair, but all I got is either last image multiplied by the iteration count or script not working at all. delay also didn't prove to be of any help.
Here's whot I got so far:
function displayImages(data){
var count = data;
var pixBox = $('#picture-box');
var imgPre = 'resources/exhibit-';
var imgExt = '.png';
var sndExt = '.wav';
for(i = 1; i < count; i++) {
var imgSrc = '<img src="' + imgPre + i + imgExt + '">';
var sndSrc = new Audio(imgPre + i + sndExt);
sndSrc.play();
pixBox.append(imgSrc);
}
}
My question is: how to set the setTimeout (or whatever function is the best here), for it to iterate over time. Say, to set the change of img/sound pairs every 2 seconds?
You can use setTimeout like this:
function displayImages(cur, total){
var pixBox = $('#picture-box');
var imgPre = 'resources/exhibit-';
var imgExt = '.png';
var sndExt = '.wav';
var imgSrc = '<img src="' + imgPre + cur + imgExt + '">';
var sndSrc = new Audio(imgPre + cur + sndExt);
sndSrc.play();
pixBox.append(imgSrc);
return setTimeout( 'displayImages(' + ((cur+1)%total) + ',' + total + ')', 2000 );
}
And start it off like this: displayImages(0,total) where total corresponds to your data variable.
The reason I like to use setTimeout and not setInterval in these situations is that setTimeout is only called after the previous function has completed. setInterval can get back-logged and freeze up your page.
Note that the function returns a handle for the timeout. If you should want to stop the animation, you can do this:
var animation = displayImages(0,total);
...some code...
clearTimeout(animation);
and the animation will stop.
You can use a setInterval, this does the same code at every interval.
var myInterval = window.setInterval(displayImages, 2000);
This will make sure your function gets called every 2000 milliseconds.
More information on MDN setInterval
You can try something like this
$(function() {
var count = 100;
var i = 0;
var repeat = setInterval(function() {
if (i <= count) {
var imgSrc = '<img src="' + imgPre + i + imgExt + '">';
var sndSrc = new Audio(imgPre + i + sndExt);
sndSrc.play();
pixBox.append(imgSrc);
i++;
}
else{
i = 0; //reset count if reaches threshold.
}
}, 5000); //5 secs
});
With this, if you want to reset the interval on any event you can simple call
clearInterval(repeat);
See a setInterval example here: JSFiddle
var i = 0;
setInterval(fadeDivs, 3000);
function fadeDivs() {
i = i < images.length ? i : 0;
$('#my-img').fadeOut(200, function(){
$(this).attr('src', images[i]).fadeIn(200);
})
i++;
}

How to Iterate with fade out?

I wanna to improve this chunk of code to make each image appears independently and doing the fade out.
This one face a problem , which is iterating quickly , so only the last image is appeared and doing the fade out.
jQuery.each(
slidesArray, function (index, value) {
var linkHref = value[1];
var imageSource = value[0];;
$("#slider").html("<a href='" + linkHref + "'><img src='" +
imageSource + "'></a>").fadeOut(5000);
});
Can you help me ? note that images should be animated respectively.
Here's a little jQuery plugin that will help:
jQuery.slowEach = function( array, interval, callback ) {
if( ! array.length ) return;
var i = 0;
next();
function next() {
if( callback.call( array[i], i, array[i] ) !== false )
if( ++i < array.length )
setTimeout( next, interval );
}
};
jQuery.fn.slowEach = function( interval, callback ) {
jQuery.slowEach( this, interval, callback );
};
Include the plugin above. It adds a slowEach method and function: $(...).slowEach(interval,callback) and $.slowEach(interval,delay,callback). It iterates over an object or jQuery selection, waiting for delay milliseconds after each iteration.
Edit your code from above to use slowEach:
jQuery.slowEach(
slidesArray, 5000, function (index, value) {
var linkHref = value[1];
var imageSource = value[0];
$("#slider").html("<a href='" + linkHref + "'><img src='" + imageSource + "'></a>").fadeOut(5000);
});
I haven't tested this, but in theory should work
function fader(i){
$("#slider").css('display', '');
if (i == slidesArray.length){
return;
}
var linkHref = slidesArray[i][1];
var imageSource = slidesArray[i][0];
i++;
$("#slider").html("<a href='" + linkHref + "'><img src='" +
imageSource + "'></a>").fadeOut(5000, fader(i));
}
fader(0);
Edit: I've tested it, seems to be working. Here's a similar use demo
Notice that there's no need to use setTimeout
Every time you call $("#slider").html() you replace the content of #slider.
what you want to do isn't delay the actual loop, you want to delay the placement [and fading] of the image. You can use setTimeout to do that like this:
jQuery.each
(
slidesArray,function(index,value)
{
var linkHref = value[1];
var imageSource = value[0];;
setTimeout(function() {
$("#slider").html
(
"<a href='" + linkHref + "'><img src='"+ imageSource + "'></a>"
).fadeOut(5000);
}, 2000 * index);
}
);

retrieving the twitter search feeds dynamically using ajax

Long back I used JSON and was successful to get the hash tag feeds from twitter and facebook. But presently I am just able to get the feeds but its not being updated constantly that means it not been update dynamically. I guess I need to ajaxify it, but I am not able to do that since I am not aware of ajax. Here is the code which I have used to get the twitter search feeds.
$(document).ready(function()
{
$("#Enter").click(function(event){
var searchTerm = $("#search").val() ;
var baseUrl = "http://search.twitter.com/search.json?q=%23";
$.getJSON(baseUrl + searchTerm + "&rpp=1500&callback=?", function(data)
{
$("#tweets").empty();
if(data.results.length < 1)
$('#tweets').html("No results JOINEVENTUS");
$.each(data.results, function()
{
$('<div align="justify"></div>')
.hide()
.append('<hr> <img src="' + this.profile_image_url + '" width="40px" /> ')
.append('<span><a href="http://www.twitter.com/'
+ this.from_user + '">' + this.from_user
+ '</a> ' + makeLink(this.text) + '</span>')
.appendTo('#tweets')
.fadeIn(800);
});
});
});
});
function makeLink(text)
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
return text.replace(exp,"<a href='$1'>$1</a>");
}
The code below should help you. What I've done is moved the code which fetches the tweets into a function. This function is then called every X seconds to update the box. When the user enters a new search term and clicks "Enter", it will reset the timer.
var fetchSeconds = 30; //Number of seconds between each update
var timeout; //The variable which holds the timeout
$(document).ready(function() {
$("#Enter").click(function(event){
//Clear old timeout
clearTimeout(timeout);
//Fetch initial tweets
fetchTweets();
});
});
function fetchTweets() {
//Setup to fetch every X seconds
timeout = setTimeout('fetchTweets()',(fetchSeconds * 1000));
var searchTerm = $("#search").val();
var baseUrl = "http://search.twitter.com/search.json?q=%23";
$.getJSON(baseUrl + searchTerm + "&rpp=1500&callback=?", function(data) {
$("#tweets").empty();
if (data.results.length < 1) {
$('#tweets').html("No results JOINEVENTUS");
}
$.each(data.results, function() {
$('<div align="justify"></div>').hide()
.append('<hr> <img src="' + this.profile_image_url + '" width="40px" /> ')
.append('<span>' + this.from_user + ' ' + makeLink(this.text) + '</span>')
.appendTo('#tweets')
.fadeIn(800);
});
});
}
function makeLink(text) {
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
return text.replace(exp,"<a href='$1'>$1</a>");
}
Hope this helps

Categories