making sure my loop is completely finished before running a function? - javascript

I have created a loop that templates my data and then appends it into a selected div, I want to make sure that this data has been completely templated and injected before I run my next function so what I really need is something like a callback function. Can anyone advise how I might do this?
JS
// Template slideshow
for (var i = 0, len = data.films.length; i < len; i++) {
var dataPath = data.films[i];
var tmp = '<li><img src="http://dummyimage.com/300/000/' + dataPath.id + '" /><h2>' + dataPath.title + '</h2></li>';
$('.slides').append(tmp);
}
// Want to run this once Im sure all data has been templated and injected
$('.flexslider').flexslider({
animation: "slide"
});​

You don't need a callback. The code that you have created is always injected by the time the loop completes.

// Template slideshow
for (var i = 0, len = data.films.length; i < len; i++) {
var dataPath = data.films[i];
var tmp = '<li><img src="http://dummyimage.com/300/000/' + dataPath.id + '" /><h2>' + dataPath.title + '</h2></li>';
$('.slides').append(tmp);
// Want to run this once Im sure all data has been templated and injected
if (i==len) {
$('.flexslider').flexslider({
animation: "slide"
});​
}
}

Related

Loop does not work as intended

http://codepen.io/abdulahhamzic/pen/aNexYj
I'm trying to get this loop to correctly print out ten results on the screen, but it seems like there is something wrong with my loop and I can't figure out what that is. On Mozilla, I only get the first result displayed on the screen and it seems like the loop is stuck after the first iteration, and on Chrome I get the ten results, but it looks like the loop is still running afterwards since I can't really do any styling on the newly created elements, plus I still get that loading icon on the page. Can anyone help me in fixing this loop? Here's the code:
var url = "https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=aa&limit=10&callback=?";
$(document).ready(function(){
$.getJSON(url, function(json){
for (var i = 0; i < json[1].length; i++){
document.write("<div><span class='header' style='color:red'>" + json[1][i] + "</span><br>" + json[2][i] + "</div><br>")
}
})
})
The document.write() function is dangerous and has different behaviour over different browsers. Better not use it. You can have something like the below working code:
var url = "https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=aa&limit=10&callback=?";
$(document).ready(function(){
$.getJSON(url, function(json){
for (var i = 0; i < json[1].length; i++){
$("body").append("<div><span class='header' style='color:red'>" + json[1][i] + "</span><br>" + json[2][i] + "</div><br>")
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Can't figure out why my JS doesn't work

I've been messing around with JavaScript samples and ever since I edited this one I can't figure out why it wont work. Everything looks fine to me, but here is the code (JSFiddle)
https://jsfiddle.net/en2a8c1v/1/
function click(e) {
document.body.style.backgroundColor='" + e.target.id + "';
}
document.addEventListener('DOMContentLoaded', function () {
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', click);
}
});
First, make sure that in the JS settings you have no-wrap enabled (I used no-wrap head) in the load type dropdown.
Next, you need to understand that when you call e.target.id, this is already a string variable. You are literally making the background color "e.target.id". That isn't a color.
Simply change document.body.style.backgroundColor='" + e.target.id + "';
to document.body.style.backgroundColor= e.target.id;
I'm not going to touch on the fact that this is a terrible way to go about this as I am assuming you are just playing with event handling.
Maybe someone will find this usefull. Use CSS attribute: background-color:rgb(x,y,z);
You can do it on simple way, for example:
document.getElementById("elementID").style.backgroundColor = 'rgb('+ this.red + ', ' + this.green + ', ' + this.blue + ')';
These r,g,b values can be, for example:
this.red = 0;
this.green = 255;
this.blue = 130;

JQuery .load () in a loop does not work

Trying to run the following code, but it works either way I need to:
if(my_condition){
$('body').append("<div id='loaddiv'><div>");
for(var i=1; i<=100; i++){
var dl = 0;
$('#loaddiv').load('/script/?p='+i);
dl = $('#loaddiv .standart-view tr').length;
alert(dl);
}
}
Thus, I have to get the number of tr-elements, which is the parent element with class standart-view, and his parents - div block c id = load214235, for each page, but constantly displays zeros in the Alert :( I tried to upgrade the code, adding all the code in the load-callback function, but still does not work ...
if(my_condition){
$('body').append("<div id='loaddiv'><div>");
for(var i=1; i<=100; i++){
var dl = 0;
$('#loaddiv').load('/folder/?p='+i, function(){
dl = $('#loaddiv .standart-view tr').length;
alert(dl);
});
}
}
+I have yet to load after going condition with break; firebug it just swears that break does not know that close ... How do I get out of the situation? I feel that something with a visibility of variables and data do not have time to load another page, and the script is running on. Jquery is connected, the rest of the code is working, including the functions of jquery, the hierarchy of elements on another page observed (number of tr should be).
First load is an Asynchronous call, you are treating it as synchronous. You are reading the content before the Ajax call is returned. Hence why it is always zero.
Second, when you do hook it up write, the content will end up writing on top of each other. You can not use load() and expect it to work in a loop.
Here is the basic idea:
(function () {
var pageCounter = 1;
var tableRowsTotal = 0;
max pageMax=10;
function loadPage() {
$.get('/folder/?p='+pageCounter, function(data){
var table = $(data).filter(".standart-view");
//or
//var table = $(data).find(".standart-view");
var rows = table.find("tbody tr");
var rowCount = rows.length;
console.log(pageCounter, rowCount);
tableRowsTotal += rowCount;
pageCounter++;
if(pageCounter<pageMax) {
loadPage();
} else {
console.log("done");
}
});
}
loadPage();
}());

Getting images to change in a for loop in javascript

So far I created an array with 11 images, initialized the counter, created a function, created a for loop but here is where I get lost. I looked at examples and tutorial on the internet and I can see the code is seeming simple but I'm not getting something basic here. I don't actually understand how to call the index for the images. Any suggestions. Here is the code.
<script type="text/javascript">
var hammer=new Array("jackhammer0.gif",
"jackhammer1.gif",
"jackhammer2.gif",
"jackhammer3.gif",
"jackhammer4.gif",
"jackhammer5.gif",
"jackhammer6.gif",
"jackhammer7.gif",
"jackhammer8.gif",
"jackhammer9.gif",
"jackhammer10.gif")
var curHammer=0;
var numImg = 11;
function getHammer() {
for (i = 0; i < hammer.length; i++)
{
if (curHammer < hammer.length - 1) {
curHammer = curHammer +1;
hammer[i] = new Image();
hammer[i].src="poses/jackhammer" +(i+1) + ".gif";
var nextHammer = curHammer + 1;
nextHammer=0;
{
}
}
}
}
setTimeout("getHammer()", 5000);
</script>
</head>
<body onload = "getHammer()";>
<img id="jack" name="jack" src = "poses/jackhammer0.gif" width= "100" height ="113" alt = "Man and Jackhammer" /><br/>
<button id="jack" name="jack" onclick="getHammer()">Press button</button>
Following on what Paul, said, here's an example of what should work:
var hammer=["jackhammer0.gif","jackhammer1.gif","jackhammer2.gif","jackhammer3.gif",
"jackhammer4.gif","jackhammer5.gif","jackhammer6.gif","jackhammer7.gif",
"jackhammer8.gif","jackhammer9.gif","jackhammer10.gif"];
var curHammer=0;
function getHammer() {
if (curHammer < hammer.length) {
document.getElementById("jack").src= "poses/" + hammer[curHammer];
curHammer = curHammer + 1;
}
}
setTimeout("getHammer()", 5000);
The big missing element is that you need to call getElementById("jack") to get a reference to the DOM Image so that you can change it's source. If you're using jQuery or most other JS frameworks, just type $("#jack") to accomplish the same.
I don't understand the need for the for loop at all, just increment the index value [curHammer] each time you click, and reset if it passes your max index length (in this case 11).
Pseudo-Code:
currentHammer = -1
hammers = [ "a1.jpg", "a2.jpg", "a3.jpg"]
getHammer()
{
currentHammer = currentHammer + 1;
if(currentHammer > 2)
currentHammer = 0;
image.src = hammers[currentHammer];
}
a) are you just trying to show an animated gif? If so, why not use Adobe's Fireworks and merge all those gifs into a single gif?
b) you know that the way you have it the display is going to go crazy overwriting the gif in a circle right?
c) you might want to put a delay (or not). If so, make the load new gif a separate function and set a timeout to it (or an interval).
Also, you are being redundant. How about just changing the src for the image being displayed?:
var jackHammer = new Array();
for (var i=0;i<11;i++) { //pre-loading the images
jackHammer[i] = new image();
jackHammer[i].src = '/poses/jackHammer'+i.toString()+'.gif';
} //remember that "poses" without the "/" will only work if that folder is under the current called page.
for (var i=0;i<11;i++) { //updating the image on
document.getElementById('jhPoses').src = jackHammer[i].src;
}
on the document itself,
< img id='jhPoses' src='1-pixel-transparent.gif' width='x' height='y' alt='poses' border='0' />

Dual Twitter feeds with jquery fadeIn and setInterval

I am making a project that shows two opposite views in two divs side-by-side. I have everything set up so the Tweets show in their respective div, but I'd like to make them both fade in, one tweet at a time (both sides can fade in at once, I don't mind that).
My Tweets are coming from an array, and I'm currently using the following code to push updates to the div:
for(var i=0; i < tweets.length; i++)
{
$("#proTweetList").prepend("<li><img src='" + tweets[i].profile_image_url + "' />" +
tweets[i].text+"</li>");
}
and
for(var i=0; i < tweets.length; i++)
{
$("#antiTweetList").prepend("<li><img src='" + tweets[i].profile_image_url + "' />" +
tweets[i].text+"</li>");
}
I found a great example on Stackoverflow, which is as follows:
var x=0; // The corner counter
function fading() {
$("#corner"+(++x)).fadeIn(2000); // Fade in the current corner
if (x==4) { // Last image to be faded in?
clearInterval(); // Stop interval
}
}
$(document).ready(function(){
setInterval("fading()",1000); // Call function every second
});
but I am very new to JQuery and cannot figure out how to translate this code into getting LI items in TWO different divs to fade in.
-- Derek
I would do something like this:
for(var i=0; i < tweets.length; i++)
{
var $item = $("<li style='display:none;'><img src='" + tweets[i].profile_image_url + "' />" +
tweets[i].text+"</li>");
$("#proTweetList").prepend($item);
$item.fadeIn(2000);
}
Didn't test that piece of code though, but I think it will work. This will create the list item within a jQuery object($item), that way you can use functions like fade on it directly.
You could do this with a simple plugin. This way you can attach the behaviour to as many divs as you like. I've written a very simple one (untested sorry) that may help:
;(function ($) {
$.fn.loadtweets = function (options) {
var settings = $.extend(
{
fadeTime : 1000,
delay: 2000,
tweets : array()
},
options
);
return this.each(
function() {
var _this = $(this),
tweets = settings.tweets,
index = 0;
var loadTweet = function() {
if (tweets.length > index) {
_this.prepend("<li><img src='" + tweets[index].profile_image_url + "' />" +
tweets[index].text+"</li>").fadeIn(settings.fadeTime);
index++;
setTimeout(loadTweet, settings.delay);
}
}
loadTweet();
}
);
};
})(jQuery);
You would call this plugin by going (I assume you have an array of tweets for each div):
$('#proTweetList').loadtweets({'tweets': proTweetsArray});
$('#antiTweetList').loadtweets({'tweets': antiTweetsArray});

Categories

Resources