JQuery-Javascript looping issue - javascript

I'm working on a banner for a website and I need it to loop through the images. My problem is that it plays through the images once and then stops. I've tried everything that I can think of with no luck. I'm sure this is simpler than I'm making it, but some help would be greatly appreciated. The latest version is below.
$(document).ready(function(){
// Variables required by script
var currentimage;
// Load Gallery XML file
$.ajax({
url: 'banner.xml',
type: 'GET',
dataType: 'xml',
error: function(){
alert('Error loading XML document');
},
success: function(xmlData){
// do something with xml
setupImages(xmlData);
}
});
// Display images
function setupImages(xmlData) {
// read xml and use it to populate page
//get first image
currentimage = $(xmlData).find("image:first");
// Fade in image after countdown
var t = setTimeout(function(){showNewImage()}, 1000);
}
// Display the image, caption, rating and label
function showNewImage() {
var image = $(currentimage).find("path").text();
var caption = $(currentimage).find("caption").text();
$("#imagelabel").removeClass("active");
// Fade out current image and fade in new image
$("#bannerimgholder").animate({opacity:0},500,
function(){
$(this).css({"backgroundImage":"url("+image+")"}).animate({opacity:1},1000,
function(){
$("#imagelabel").addClass("active");
});
});
// Add caption
$("#imagelabel").text(caption);
var to = setTimeout(function(){getNextImage()}, 5000);
}
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="") {
currentimage = $(xmlData).find("image:first");
} else {
currentimage = tmp;
}
showNewImage();
}
});

Your code is using next(), which will return nothing once you reach the last image.
You need to use a different test to close the loop, for example:
tmp.length==0
Note that tmp is already a jQuery object, so you don't need to wrap it in $().
This page offers an example of nextOrFirst() function that does what you want.

Here is a solution that I came up with.
First I added an element to the end of my xml file with just a 'path' attribute of "last".
Next, I add the following variable to save the path name of the first element:
var imagepathtext;
Then, in the setupImages(xmlData) function I added the following:
imagepathtext = $(currentimage).find("path").text();
Lastly, I changed the getNextImage() function from
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="") {
currentimage = $(xmlData).find("image:first");
} else {
currentimage = tmp;
}
showNewImage();
}
to
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="last") {
while ($(tmp).find("path").text()!=firstimagepath)
{
var tmp1 = $(tmp).prev();
tmp = tmp1;
}
currentimage = tmp;
} else {
currentimage = tmp;
}
showNewImage();
}
And just like magic it loops correctly now!

Related

How to make a thumbnail created by a function clickable in html?

I am trying to make clickable thumbnails in my html code but I cannot figure out how to do it. I know <a href = ""> won't work. How can I make each thumbnail clickable so that it directs to another page?
Here are the functions I used to get data from the database and to create the thumbnail
`
<script>
$(function(){
$.ajax({
url: '/getMovies',
type: 'GET',
success:function(response) {
console.log(response);
var data = JSON.parse(response);
var itemsPerRow = 0;
var div = $('<div>').attr('class','row');
for(var i=0;i<data.length;i++){
console.log(data[i].Title);
if(itemsPerRow<3){
console.log(i);
if(i==data.length-1){
div.append(CreateThumb(data[i].Id,data[i].Name,data[i].Type,data[i].Copies));
$('.well').append(div);
}
else{
div.append(CreateThumb(data[i].Id,data[i].Name,data[i].Type,data[i].Copies));
itemsPerRow++;
}
}
else{
$('.well').append(div);
div = $('<div>').attr('class','row');
div.append(CreateThumb(data[i].Id,data[i].Name,data[i].Type,data[i].Copies));
if(i==data.length-1){
$('.well').append(div);
}
itemsPerRow = 1;
}
}
},
error:function(error){
console.log(error);
}
});
});
})
function CreateThumb(id,name,type,copies){
var mainDiv = $('<div>').attr('class','col-sm-4 col-md-4');
var thumbNail = $('<div>').attr('class','thumbnail');
var caption = $('<div>').attr('class','caption');
var title = $('<h3>').text(name);
var title = $('<h5>').text(type);
var title = $('<h4>').text(copies);
var p = $('<p>');
caption.append(name);
caption.append(p);
caption.append(type);
thumbNail.append(caption);
mainDiv.append(thumbNail);
return mainDiv;
}
</script>
`.
After you've added the thumbnails use:
$(".thumbnail").onclick(function(){
document.location.href = newUrl;
}
You can listen to clicks with jQuery by using:
// Change the selector used below
$('#some-id-here').click(function(){
// Your code here
});
There's also another way, using "on". This might be more useful to you, because it also triggers on items added dynamically to the page, which looks to be your case.
// Change the selector used below
$('#some-id-here').on('click', 'img', function(){
// Your code here.
});
Also, you can select the document with $(document) (instead of #some-id-here) to apply it globally on your page, so every img tag would trigger this function.

Calling a javascript function with parameters from a dynamically created element

I'm trying to dynamically load pictures to a profile page like site from MySQL with PHP and
then add them to an unordered list with javascript. I would like each list item to also have
a like button, which upon clicking calls a javascript function, passing the image name as
its parameter. I've searched and found answers on how to call a function without passing it
any variables, but every time I add the image name to the function call, the console log reads
"undefined".
The pictures show up fine and the imgArray[i] is a string containing the file's name (e.g. photo.jpg)
But
console.log(imgArray[i])
in the onclick function reads undefined. I've also tried
like.setAttribute()
without any results.
function showGallery(imgArray) {
for(var i=0; i < imgArray.length; i++){
var list = document.getElementById("image-list"),
li = document.createElement("li"),
img = document.createElement("img"),
like = document.createElement("a");
img.src = "user_images/" + imgArray[i];
like.className = "button-like";
li.appendChild(img);
li.appendChild(like);
list.appendChild(li);
like.href = "javascript:void(0);";
like.onclick = function() {
console.log(imgArray[i]);
addLike(imgArray[i]);
};
}
}
function addLike(img) {
console.log("Liking.. " + img);
$.ajax({
url: 'like.php',
type: 'POST',
data: {
'photo': img
},
success: function(likes){
console.log(likes);
}
});
}
The problem is that by the time the click event fires, imgArray[i] doesn't exists.
try doing it like this...
like.href = "javascript:void(0);";
like.imgArray = imgArray[i];
like.onclick = function() {
console.log(this.imgArray);
addLike(this.imgArray);
};
Hope that helps

Jquery: Is there an element based method similar to $(document).ready()?

Is there a method, similar to $(document).ready(), that can be applied
to an arbitrary element? For example, if an ajax call sets the content
of a DIV and includes a lot of IMG tags, is there a way to trigger
a function call when all of the images have completed loading? Something
along the lines of:
$.ajax({
url: '/get/my/page.php',
dataType: "html",
success: function(response)
{
$('#my_element').html(response);
$('#my_element').ready(function() {alert('all images loaded');});
}
});
Thanks for your advice.
If you're specifically interested in images being loaded, then you can try imagesLoaded, which seems to cover the example case that you mention.
Identical to $("document").ready() -- no, however, there are ways that you can make it work:
Put whatever function you need executed as a callback to the AJAX call:
$.get("link.php?item=1", function() {
//callback function here
})
You can have an onchange event listener that triggers whenever the div is being changed and you can specifically trigger a function after a certain number of elements is loaded:
$("#div").on('change', function() {
if ( $("#div").length > DESIRED_NUMBER_OF_ELEMENTS + 1)
{
//Execute function here
}
})
The on('change') can be used in any which way you want: it can trigger a function based on the number of elements, based on the nature of elements inside (if it's an image, a link, another div, etc), anything you can think of.
Something along these lines should do what you want.
onImagesLoaded('#my_element img',function(){
console.log('images have all loaded')
});
function onImagesLoaded(seletor,callback){
var $images = $(seletor);
var count = $images.length;
$images.each(function(img){
//create an image
var tempImage = new Image();
//set a function for the onload event
tempImage.onload = function(){
count--;
//if the count is 0 it means all images are done loading
if(count===0){
callback();
}
};
//set the source to the src of the image.
tempImage.src = $(img).attr('src');
});
}
Try
var request = $.ajax({url: "/get/my/page.php", dataType: "html"});
request.done(function (data, textStatus, jqxhr) {
// parse returned `data` string for html
var html = $.parseHTML(data),
//
len = html.length,
div = $("div");
// do stuff when all images loaded into `div`
div.on("imgsready", function(e, htmlimgs, divimgs) {
console.log("ready", htmlimgs, divimgs);
$(e.target).prepend(divimgs + " images ready<br>" )
});
// set `div` html contents to `html` string
$.when(div.html(html)
// return image `on` `load` event
, $("img", div)
.load(function(e) {
// return image `promise` object
return $(e.target).promise()
})
)
.then(function (el, i) {
// if `div` contains `len` length images , call `imgsready` event
return el.children(i).length === (i.length && len)
&& el.children(i).eq(len -1).is("*")
? el.trigger("imgsready", [len, i.length])
// else check again in 1000ms
: setTimeout(function() {
el.children(i).eq(len -1).is("*") ?
el.trigger("imgsready", [len, i.length])
: console.log(el.children(i).length)
},1000)
});
});
jsfiddle http://jsfiddle.net/guest271314/vhuaen71/

div with an id wont accept any event handlers JavaScript. No Jquery

Im trying to pause a timed slideshow when you're hovering over a div
<div id="play_slide" onMouseOver="clearTimeout(playTime)"></div>
If i put onMouseOver="clearTimeout(playTime)" inside an li on the page, it'll pause, so I know my code is correct, it just wont work on the div! Also if i get rid of the id, it will alert when i put an alert function into an event handler
This is the js.
var playTime;
function playSlide()
{
var slideshow = document.getElementById("play_slide").style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if(indexPlay > images.length - 1)
{
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/"+images[indexPlay]+".png')";
playTime = setTimeout("playSlide()", 2500);
}
you can see this here: www.nicktaylordesigns.com/work.html
I would do it like this:
( and no inline script... just <div id="play_slide">Something</div> )
var playTime;
var indexPlay = 0;
var slideElement;
window.onload = function () {
slideElement = document.getElementById("play_slide");
slideElement.addEventListener('mouseenter', function () {
console.log('stop');
clearTimeout(playTime);
});
slideElement.addEventListener('mouseleave', function () {
console.log('continue');
playTime = setTimeout(playSlide, 2500);
});
playSlide();
}
function playSlide() {
var slideshow = slideElement.style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if (indexPlay > images.length - 1) {
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/" + images[indexPlay] + ".png')";
playTime = setTimeout(playSlide, 2500);
}
Fiddle
This issue is related to the script loading. Your script gets loaded after the DOM is processed so function doesn't get attached to the event.
If you are using jQuery then you can use below code.
$(function () {
$("#play_slide").mouseover(function(){
var playTime = 33;
clearTimeout(playTime);
});
});
If you don't want to use JQuery then you can do the same thing in JavaScript as below.
window.onload = function(){
document.getElementById("play_slide").onmouseover = function(){
var playTime = 33;
clearTimeout(playTime);
};
}
I got it! the div tag was somehow broken, I coded a div around it and gave it the event handlers and a class. That worked, then i simply changed the class to an id and got rid of the original div. Idk what was going on but it works now. Thanks for your suggestions!
Can you try this,
<div id="play_slide" onmouseover="StopSlide();">Stop</div>
<script>
var playTime;
var indexPlay;
function playSlide()
{
var slideshow = document.getElementById("play_slide").style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if(indexPlay > images.length - 1)
{
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/"+images[indexPlay]+".png')";
playTime = setTimeout("playSlide()", 2500);
}
function StopSlide(){
window.clearTimeout(playTime);
}
playSlide();
</script>

When is Jquery pseudo recussion finished

I use the function below to show a list of items. I want to change the function so that I can display the navigation when the pseudo recussion is finished. Is there a way to dtect when it is finished?
function fadeItem() {
$('ul li:hidden:first').fadeIn(fadeItem);
}
(update: added this first part) Loads all embed images then recursively fades everything in every half second, then does an alert (replace with the concept you commented back on)
var selector = "ul li:hidden:first";
function fadeIn($item) {
$item.fadeIn(500,function() {
var n = $(selector);
if(n.length > 0) {
fadeIn($(selector));
} else {
// add a div
alert("added a div");
}
})
}
$(document).ready(function() {
// load images first
var imgs = []; // cached
$("ul li img").each(function() {
// create a separate img tag because img is not active due do [assumed css] display:none;
var cacheImage = document.createElement('img');
cacheImage.src = $(this).attr("src");
imgs.push(cacheImage);
});
// this is a quick method, you can change window to the image nodes to optimize better
$(window).load(function() {
fadeIn($(selector));
});
});
Source: http://jsfiddle.net/MattLo/ukLaG/1/ (using a very large image to test)
See the documentation. You can pass a callback function:
function fadeItem() {
$('ul li:hidden:first').fadeIn(fadeItem, function() {
// do something
});
}

Categories

Resources