Element inserted with jQuery doesn't appear right away - javascript

I am trying to add a loading message while some stuff is loading, but it doesn't appear until after the stuff loads. Here is my code:
$('#loading').text('Loading...').show();
//alert('test');
for ( var i in ['list','of','things'] )
{
// dummy loop to waste some time
for ( var j=0; j<5000000; j++ ) {
var asd = j+123*j%17;
var qwe = j+123*asd%17 + j;
var zxc = j+123*asd%17 + j*zxc;
}
}
$('#loading').hide();
$('#content1').html('<ul><li>Test</li><li>Test</li></ul>');
When running this, the page appears blank while the for loop is running and the loading banner doesn't appear. When loading is done it simply appears and instantly starts fading out. (I added a big for loop inside the above loop to simulate a slower load and it still doesn't show the loading message until the loop is done.)
The loading takes less than a second (on Chrome, anyway) so it's not a huge problem, but why does this happen, and can I get the message to appear before the delay?
EDIT: updated code an put version on jsFiddle: http://jsfiddle.net/an2Pc/3/

If it is a static message, you don't need to create on the fly. Simply put it in and hide it using display: none; in css. Then, you can show it using $('#loading').show() or even $('#loading').fadeIn(). I don't know what do you do in the loop, but there should not be a reason for not showing inmediately.
Edited: I could verify you are right, it doesn't show, not sure why. Anyway, you can fix it by inserting the code as a callback of the show() method, it works:
$('#loading').text('Loading...').show(function() {
for ( var i in ['list','of','things'] )
{
for ( var j=0; j<5000000; j++ ) {
var asd = j+123*j%17;
var qwe = j+123*asd%17 + j;
var zxc = j+123*asd%17 + j*zxc;
}
}
$('#loading').hide();
$('#content1').html('<ul><li>Test</li><li>Test</li></ul>');
});
Edited for new case: for adding a callback to a method that doesn't include one, you can use the trick of animate some property that doesn't change anything, like this (I don't know if it's a best practice, but it works :)
<div class="notice" id="loading">Testing</div>
<div class="content" id="content1">a</div>
$('#loading').text('Loading...').animate({ opacity: 1 }, function() {
for ( var i in ['list','of','things'] )
{
for ( var j=0; j<5000000; j++ ) {
var asd = j+123*j%17;
var qwe = j+123*asd%17 + j;
var zxc = j+123*asd%17 + j*zxc;
}
}
$('#loading').hide();
$('#content1').html('<ul><li>Test</li><li>Test</li></ul>');
});

Hi~ Please use it in your page:
<div class="notice" id="loading" style="display:none">Loading...</div>
<input type="button" onclick="Load()" />
following code in head block:
<script type="text/javascript">
function Load() {
$("#loading").css("display", "block").fadeIn('slow');
for ( i=0; i<1000;i++) {
// load some stuff here
}
$("#loading").fadeOut('slow');
}
</script>
Don't forget to include the JQUERY file:
<script type="text/javascript" src="../Scripts/jquery-1.5.1.min.js"></script>

I'm not sure why this happens, but a solution is to the put the loop inside a setTimeout to delay it a bit.
$('#loading').text('Loading...').show();
setTimeout(function() {
for (var i in ['list', 'of', 'things']) {
for (var j = 0; j < 5000000; j++) {
var asd = j + 123 * j % 17;
var qwe = j + 123 * asd % 17 + j;
var zxc = j + 123 * asd % 17 + j * zxc;
}
}
$('#loading').hide();
$('#content1').html('<ul><li>Test</li><li>Test</li></ul>');
}, 1);
jsFiddle: http://jsfiddle.net/an2Pc/4/

Related

jQuery nicescroll is not working with dynamic content and other JavaScript function that makes random effect

So here is the thing, I have a sidebar that has big height due the lots of navigation links. And I'm using jQuery nicescroll plugin to make it look fine. In the sidebar I also have h3 tag which makes a random effect of showing letters (see the code) every 4 seconds. So, when it's on - scroll is not working at all for these 4 seconds and you can't do any scrolling. I tried to use $("#sidebar").getNiceScroll().resize() but it doesn't work either. Is there any way to make it work?
<div id="sidebar">
<h3 id="output">Random</h3>
</div>
//Calling for nicescroll function for my sidebar
$(function(){
$("#sidebar").niceScroll({ cursorcolor:"#66aee9", cursorfixedheight: 400 });
})
//Random effect for my h3 tag
setInterval(function(){
$(document).ready(function(){
var theLetters = "abcdefghijklmnopqrstuvwxyz#%&^+=-"; //You can customize what letters it will cycle through
var ctnt = "Random"; // Your text goes here
var speed = 50; // ms per frame
var increment = 8; // frames per step. Must be >2
var clen = ctnt.length;
var si = 0;
var stri = 0;
var block = "";
var fixed = "";
//Call self x times, whole function wrapped in setTimeout
(function rustle (i) {
setTimeout(function () {
if (--i){rustle(i);}
nextFrame(i);
si = si + 1;
}, speed);
})(clen*increment+1);
function nextFrame(pos){
for (var i=0; i<clen-stri; i++) {
//Random number
var num = Math.floor(theLetters.length * Math.random());
//Get random letter
var letter = theLetters.charAt(num);
block = block + letter;
}
if (si == (increment-1)){
stri++;
}
if (si == increment){
// Add a letter;
// every speed*10 ms
fixed = fixed + ctnt.charAt(stri - 1);
si = 0;
}
$("#output").html(fixed + block);
block = "";
}
});
}, 4000);
I change to rows and check it in jsfiddle, looks like working scroll fine.
Before:
setInterval(function(){
$(document).ready(function(){
...
});
}, 4000);
After:
$(document).ready(function(){
setInterval(function(){
...
}, 4000);
});

Clone HTML elements with JS

Trying to set up a Tic-Tac-Toe board based on JS input with an alert. The alert never shows up, and the HTML is never rendered... what am I missing?
ALL HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tic Tac Toe! (and more...)</title>
<meta name="description" content="Tic Tac Toe">
<meta name="author" content="SinSysOnline">
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js.js"></script>
<style>
body{
font-family:"Lucida Console", Monaco, monospace;
}
td{
border-right:1px solid #000;
border-bottom:1px solid #000;
width:100px;
height:100px;
text-align:center;
font-size:72px;
}
td:last-child{
border-right:none;
border-bottom:1px solid #000;
}
tr:last-child td{
border-bottom:none;
}
</style>
</head>
<body>
<div id="dashboard">
<input type="text" value="How large is your grid? (default 3)" size="35" />
</div>
<table id="board">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</body>
</html>
ALL JS (minus jQuery)
/* Sadly, there is a very well known algorithm to ensure one NEVER loses at
tic-tac-toe. Ties, perhaps, but if you play right you can NEVER LOSE.
I will not institue this cheap shot into my program, and this will be
a computer vs you. I will add in potential moves :-) */
(function($) {
function create(x){
var board = [];
for(var i=0;i<x;i++){
var tempArr = [];
for(var j=0;j<x;j++){ tempArr[j] = ""; }
board.push(tempArr);
}
$('#board tr').clone(x);
return board;
}
var x = prompt("How large would you like your grid? (3-10)");
var board = create(x);
})(jQuery);
I've tried adding the JS to the bottom of my body... just kind of confused here. I know JS inside and out... except for DOM manipulation...
you didn't do any thing with your cloned element!
if you want to dynamically generate a table
the code should be like this
var $board = $('#board');
var td = "<td></td>", $tr = $("<tr></tr>");
function create(x) {
$board.empty();
var arr = [];
for(var i = 0; i < x; i++) {
arr.push(td);
}
var $trCloned = $tr.clone().append(arr.join(''));
for(var j = 0; j < x; j++) {
$board.append($trCloned);
}
}
Here is the fiddle
// JQuery
function create(board, x)
{
var row = $("<tr></tr>");
var i;
for (i = 0; i != x; i++) row.append ($("<td>x</td>")); // create a row
for (i = 0; i != x; i++) $('#'+board).append(row.clone()); // then the board
}
// sample use
var x = window.prompt ("How much, boss?");
create('board', x);
// html
<table id='board' />
I've put an 'x' inside the cells so that the board is visible
As Fiddle works, this No-Prompt problem is more like an environment/compatibility/typo issue. The problem can be solved progressively.
There is a misuse of jQuery's clone() function, the clone() function accepts boolean type (http://api.jquery.com/clone/) , which means whether or not event handlers will be copied. From the code I guess this is not what you want. Please correct it and try again.
On which browser did you test? Does this issue happen on one specific browser, or happens on all browsers in your computer? If it is the latter one, then copy your code (copy the files, not re-type) to someone else' computer and try again.
Simplify the JS code and test step by step. First, just leave the prompt() line and delete all else, will it work? Then, add an empty create() function and try again. Then, add something more. Sooner or later, you will find the line which causes the problem.
Please let us know if you deliver the above experiment and find something new.
EDITS
I'll never stop if I don't stop now. I'm stuck anyway. Hope this helps you on your way. Still needs some work (undefined references) but is functional if my fanciness didn't distract me so much:
JS Fiddle Demo (not working)
Javascript:
(function (window, document, $) {
var $board = $('#board');
var x = parseInt(prompt("How large would you like your grid? (3-10)"), 10);
var taken = [];
create(x);
function create(x) {
var tmp;
var $tr = $('<tr/>');
var $td = $('<td/><td/><td/>');
if (x <= 10 && x >= 3 && typeof x === 'number') {
for (var i = 0; i < x; i++) {
tmp = $tr.append($td);
tmp.clone().appendTo($board);
}
$('#board').on('click', 'td', function (evt) {
var e = evt || window.event;
var y = $(this).index();
var z = $(this).parent('tr').index();
taken = (!taken) ? [y, z] : taken;
userChoice(y, z, x, this);
});
} else {
alert('You entered an incorrect value. Try again!');
return false;
}
}
function userChoice(y, z, x, el) {
//if($(el).text() !== "") {
console.log(taken);
for (var d = 0; d < (x - 1); d++) {
for (var o = 0, n = 0; o < 3; o++) {
if ((taken[n].indexOf(y) && taken[n].indexOf(z)) || (taken[n].indexOf(y) && taken[n].indexOf(z))) {
alert('Already played that spot. Nice try.');
return false;
}
n++;
}
}
taken.push([y, z]);
$(el).text('O');
console.log(taken);
if ((taken.length * taken[taken.length].length) / (x - 1) === 3) {
alert('No more spaces! Game over!');
return false;
}
compChoice(x);
}
function compChoice(x) {
console.log(taken);
var a = Math.floor(Math.random(10) * x);
var b = Math.floor(Math.random(10) * x);
for (var d = 0; d < (x-1); d++) {
for (var o = 0, n = 0; o < 3; o++) {
if ((taken[n].indexOf(a) && taken[n].indexOf(b)) || (taken[n].indexOf(a) && taken[n].indexOf(b))) {
compChoice(x);
}
n++;
}
}
taken.push([a,b]);
console.log(taken);
$board.find('tr:nth-of-type(' + a + ')').find('td:nth-of-type(' + b + ')').text('X');
if ((taken.length * taken[taken.length].length) === x) {
alert('No more spaces! Game over!');
return false;
}
}
})(this, this.document, jQuery, undefined);
HTML:
<div id="dashboard">
<noscript>
<input type="text" value="How large is your grid? (default 3)" size="35" />
</noscript>
</div>
<table id="board"></table>

Error $.get(...).done is not a function

I have code that looks like that:
<head>
<script type="text/javascript" src="jquery-1.3.2.js"></script>
<script type="text/javascript">
function draw(){
var a = 0,
timeC = 0,
timeS = 0,
meanCFf=0,
meanSFf= 0;
$.get('test1.csv').done(function(data) {
var i,
lines = data.split('\n'),
line = lines[0].split(','),
oS = line.indexOf('oS'),
browName = line.indexOf('browName'),
browVer = line.indexOf('browVer'),
timeCanvas = line.indexOf('timeCanvas'),
timeSvg = line.indexOf('timeSvg');
for(i=1; i<lines.length; i++) {
line = lines[i].split(',');
if(line[oS] === 'Windows') {
a++;
timeC += parseFloat(line[timeCanvas], 10);
timeS += parseFloat(line[timeSvg], 10);
}
}
});
meanCFf = timeC/a;
meanSFf = timeC/a;
var os1 = document.getElementById("osInfo1");
os1.innerHTML = "Twoja średnia to: " + meanCFf;
var os2 = document.getElementById("osInfo2");
os2.innerHTML = "Twój sytem operacyjny to: " + meanSFf;
}
</script>
</head>
<body onload="draw()">
<p id="osInfo1"></p>
<p id="osInfo2"></p>
</body>
And I get an error Unhandled Error: '$.get('test1.csv').done' is not a function, I tried to google this error but I don't understand the answer its some kind of name problem?? From what i googled I tried to change $ for jQuery but still got the same error
The .done() was introduced in jQuery 1.5. You seem to be using jquery 1.3. So make sure that you upgrade to jQuery 1.5 if you want to use deferred objects.
If for some reason you cannot upgrade you could use the success callback of the $.get function:
$.get('test1.csv', function(data) {
var i,
lines = data.split('\n'),
line = lines[0].split(','),
oS = line.indexOf('oS'),
browName = line.indexOf('browName'),
browVer = line.indexOf('browVer'),
timeCanvas = line.indexOf('timeCanvas'),
timeSvg = line.indexOf('timeSvg');
for(i = 1; i < lines.length; i++) {
line = lines[i].split(',');
if(line[oS] === 'Windows') {
a++;
timeC += parseFloat(line[timeCanvas], 10);
timeS += parseFloat(line[timeSvg], 10);
}
}
});
You have used old jquery, Try using latest jquery version
The jquery version you used is too low, please use higher jquery version run your code.

Textarea disappears after setting value

Here's what I'm trying to do:
Type initials (e.g. MS,AK,LT) by clicking on "Enter Names". This saves a string, which I then turn into an array (nameArray) in order to get each set of initials. After reordering these randomly, I want to place some of the initials into the textareas, but that's where things go wrong.
Here's what's wrong:
the initials display for a moment, then disappear after the function executes. (ALSO, I'm trying to have a div (with text "randomizing...") that is otherwise hidden, show itself for 4 seconds (4000 ms) while the initials are being reordered to indicate as such. That's what the setTimeout is for...but that doesn't work either. The div disappears along with the text). Why are these only in coordination with the execution of the function?
Here's the JS code:
var nameArray;
window.onload = pageLoad;
function pageLoad() {
$("#randomizingNotification").hide();
$("#prev_arrow").click(prevUser);
$("#next_arrow").click(nextUser);
$("#enter_names").click(orderNames);
}
function orderNames() {
nameArray = getNames();
randomizeNames();
displayNames();
}
function getNames() {
var initialsString = prompt("Please enter initials, separated by a comma (e.g LK,AS,NM)");
nameArray = initialsString.split(",");
return nameArray;
}
function randomizeNames() {
$("#randomizingNotification").show();
var timer = setTimeout(function(){randomize(nameArray);},4000);
$("#randomizingNotification").hide();
clearTimeout(timer);
}
function randomize(array) {
for (var i = 0; i < array.length; i++ ) {
var randNum = Math.floor(array.length*Math.random()) //random number between 0 and length of array (rounded down
var temp = array[i];
array[i] = array[randNum];
array[randNum] = temp;
}
}
function displayNames() {
var curr, up, prev, current, upcoming, previous;
curr = 0;
up = 1;
prev = null
current = nameArray[curr];
upcoming = nameArray[up];
$("#upcoming_pick").val(upcoming);
$("#current_pick").val(current);
}
Here's the relevant HTML code:
<body>
<div id="header">
<div id="randomizeNotContDiv">
<div id="randomizingNotification">randomizing...</div>
</div>
<div id="page_title"><h1>Welcome to Classtech Shift Scheduler!</h1></div>
<div id="helper_functions_div">
<div id="enter_names_div">
Enter Names
</div>
</div>
<div id="main_content">
<div id="name_tracker">
<div><img src="Images/prev_arrow.png"/></div>
<textarea name="upcoming_pick" cols="10" rows="1" class="picker_names" id="upcoming_pick"></textarea>
<textarea name="current_pick" cols="10" rows="1" class="picker_names" id="current_pick"></textarea>
<textarea name="previous_pick" cols="10" rows="1" class="picker_names" id="previous_pick"></textarea>
<div><img src="Images/next_arrow.png"/></div>
</div>
You've got at least few issues, but the main problem is the structure of your setTimeout. A setTimeout is like an AJAX call in that it's non-blocking. Anything inside the function you pass to it will only execute when the timer is done, while code that comes after it will execute immediately.
I've reorganized the hiding of your randomization message and the displayNames function to go inside of the setTimeout function and things work fine.
Here it is in a fiddle: http://jsfiddle.net/nate/LB6dz/
And here's the code:
var nameArray;
window.onload = pageLoad;
function pageLoad() {
$("#randomizingNotification").hide();
$("#enter_names").click(orderNames);
}
function orderNames(event) {
// Prevent the link's default action
event.preventDefault();
nameArray = getNames();
randomizeNames();
}
function getNames() {
var initialsString = prompt("Please enter initials, separated by a comma (e.g LK,AS,NM)");
nameArray = initialsString.split(",");
return nameArray;
}
function randomizeNames() {
$("#randomizingNotification").show();
var timer = setTimeout(function (){
randomize(nameArray);
// These items need to be inside the timeout, so they only run once it's done
$("#randomizingNotification").hide();
displayNames();
}, 4000);
// No need to clearTimeouts after they're done... they only run once
// clearTimeout(timer);
}
function randomize(array) {
for (var i = 0; i < array.length; i++ ) {
var randNum = Math.floor(array.length*Math.random()) //random number between 0 and length of array (rounded down
var temp = array[i];
array[i] = array[randNum];
array[randNum] = temp;
}
}
function displayNames() {
var curr, up, prev, current, upcoming, previous;
curr = 0;
up = 1;
prev = null
current = nameArray[curr];
upcoming = nameArray[up];
$("#upcoming_pick").val(upcoming);
$("#current_pick").val(current);
}

changing background image with a for loop

i have a table with 3 cells the middel 1 in a black image so it will look like there is a line in the middle of the screen.
now in the other cell i want to show pictures, so i tryed to do a loop that changing the images every second with by hiding the cells and then show them.
the script:
$(window).ready(function () {
//the images sits in a div with a hidden property.
var AlumniumPictures = $("#AlumnimPictureHolder").children();
var ShipozimPictures = $("#ShipozimPictureHolder").children();
//var timer = $.timer(yourfunction, 10000);
for (var i = 0; i < 10; i++) {
$(".almoniyomButtonTD").css({
"background-image": "url(" + $(AlumniumPictures[i]).attr('src') + ")"
});
$(".shipozimButtonTD").css({
"background-image": "url(" + $(ShipozimPictures[i]).attr('src') + ")"
});
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
//for some reson the code dosnt work if im not using the setInterval method.
document.setInterval(1000);
}
});
this is not working it only show me the first images and then stop.
is there a batter way to do this?
am im doing this right?
I think you might do this for the background:
$(window).ready(function () {
//the images sits in a div with a hidden property.
var AlumniumPictures = $("#AlumnimPictureHolder").children();
var ShipozimPictures = $("#ShipozimPictureHolder").children();
//var timer = $.timer(yourfunction, 10000);
time = 0;
step = 1000; // One secund
for (var i = 0; i < 10; i++) {
time+= step;
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
//for some reson the code dosnt work if im not using the setInterval method.
document.setInterval("changeBG('" + $(AlumniumPictures[i]).attr('src') + "', '.almoniyomButtonTD')", time);
document.setInterval("changeBG('" + $(AlumniumPictures[i]).attr('src') + "', '.shipozimButtonTD')", time);
}
});
function changeBG(image, obj) {
$(obj).css({
"background-image": "url(" + image + ")"
});
}
But I don't undestand what you want to do with this:
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
See the docs about setInterval. You need to tell it what code you are running.
window.setInterval(code, delay);
You aren't specifying any code for it to run! Try placing your for statement in a function and calling that.
Also, from Mozilla and MS docs setInterval seems to be on the window object, not on the document object. I don't think it will work the way you have it. I imagine if you looked in a debugger you would see an error thrown.
window.setInterval(myFunction, 1000);
function myFunction() {
for (var i = 0; i < 10; i++) {
$(".almoniyomButtonTD").css({
"background-image": "url(" + $(AlumniumPictures[i]).attr('src') + ")"
});
$(".shipozimButtonTD").css({
"background-image": "url(" + $(ShipozimPictures[i]).attr('src') + ")"
});
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
}
}

Categories