i am using an ajax function to read some contents. Also i want to impliment lazy loading in this content
my code
$(document).ready(function () {
var getparam = '<?php echo $this->paramData;?>';
$.ajax({
type: "POST",
url: "/Index/" + getparam
}).done(function (data) {
console.log(data);
$('#append_here').html(data);
var check = 0;
var int = 0;
var int = setInterval("doThis(check)", 10);
function doThis(check) {
var images = $('img:hidden').length;
if(check >= images) {
clearInterval(int);
}
$('img:hidden').eq(0).fadeIn(10);
check++;
}
});
});
the content coming perfectly. after that there is an error present that doThis is not defind
if any one know about this please help me.
Put doThis() in the global scope, not inside $(document).ready() or inner functions/ callbacks of that.
To say it simply:- move it below the end of the $(document).ready( ...) section.
This kind of error is not entirely uncommon, now that with jQuery we write so much of the Javascript inside the $(document).ready() callback.
setInterval("doThis(check)", 10);
This calls doThis from the global scope since it's called thru an eval-like fashion - and doThis isn't in the global scope.
Try this instead:
var int = setInterval(function(){
var images = $('img:hidden').length;
if(check >= images) clearInterval(int);
$('img:hidden').eq(0).fadeIn(10);
check++;
}, 10);
Related
So Javascript is not multithreaded. But I have the following problem.
I use AJAX calls from a function called from setTimeout. I need to know be able to distinguish when there are active AJAX calls before rescheduling the function.
For that I am using 2 global variables. So the code structure is as follows:
setTimeout(some_function, 10000);
window.ajax_running = 0;
window.calls_so_far = 0;
function some_function () {
if(window.ajax_running) {
setTimeout(some_function, 10000);
return;
}
window.ajax_running = 1;
$.ajax({
//various
success: function (data) {
window.calls_so_far = window.calls_so_far + 1;
console.log('Running calls: ' + window.calls_so_far);
if(window.calls_so_far >= SOME_VALUE) {
//we are ok ajax has finished
window.ajax_running = 0;
}
}
Simple code. The problem is that it does not work. I see in the console:
Running calls: 1
So the global variable is not being incremented. It is as is each AJAX call sees the original value 0 and increments it (like as if there were threads).
What am I messing up here? How can I fix this?
When success runs, the ajax call had already finished, so you are not running this call when u add calls_so_far.
I'm not sure why u need the call to be "counted", but if is just the other problem (to call the same function after the first had finished, i would suggest this approach:
var counter;
counter = 0;
function recallSomeFunction() {
setTimeout(some_function, 10000);
}
function some_function () {
$.ajax({
//various
success: function (data) {
if (++counter < SOME_VAL) recallSomeFunction();
//...
},
error: function ( jqXHR, textStatus, errorThrown )) {
recallSomeFunction()
//...
});
}
I am trying to pass "this" from:
myVar = setInterval("displayDate(this )",1000);
and is passing "div.test" like it should when I step through it, but when receiving it in:
function displayDate(obj){
}
It says that it is "Window"??? Below is the JavaScript I am building. I am trying to build a foundation for classes that trigger events and eventually I am going to be changing the elements.src=".jpg" by a variable rate (now set to 100) through Sprite parsing. But I am currently stuck on this and I don't want to have to insert onmousemove attributes, etc. in the .html code to keep it clean. . . keep in mind this is only my third day writing .html/.css/.js so any help is appreciated!
// This helps create a static variable that isn't polluting the global namespace
var incr = (function () {
var i = 0;
return function(){ return i++; };
})();
// This perform all of the functions that we would like with some error handling
function displayDate(obj){
var counter = incr();
try{
obj.innerHTML=counter;
}catch(err){
var txt="There was an error on this page.\n\n";
txt+="Error description: " + err.message + "\n\n";
txt+="Click OK to continue.\n\n";
alert(txt);
}
}
// This is our trigger that sets an interval for our main Java function
$(function(){
var myVar;
$(".test").hover( function() {
// The mouse has entered the element, can reference the element via 'this'
myVar = setInterval("displayDate(this )",100);
},function () {
// The mouse has left the element, can reference the element via 'this'
clearInterval(myVar);
}
);
});
The time the displayDate function is called, your into another scope and this is your window object (not the div element anymore). To resolve, you can do like this:
$(".test").hover( function() {
var self = this;
myVar = setInterval(function() {
displayDate(self);
},1000);
}, function() {
clearInterval(myVar);
});
instead of setInterval("displayDate(this )",100);
$(".test").hover( function() {
var that = $(this);
setInterval(function () {
displayDate(that);
},100);
I am trying to create a recursive function in Javascript. But in order to loop my XML file properly I am trying to pass the right value taken from the XML length and pass it to the setTimeout function.
The problem is that the setTimeout ( setTimeout('cvdXmlBubbleStart(nextIndex)', 3000);
)function does not get the value of nextIndex and thinks it is undefined. I am sure I am doing something wrong.
jQuery(document).ready(function($) {
cvdXmlBubbleStart('0');
});
function cvdXmlBubbleStart(nextIndex) {
$.ajax({
url: "cross_video_day/xml/broadcasted.xml",
dataType: "xml",
cache: false,
success: function(d) {
broadcastedXML = d;
cvdBubbleXmlProcess(nextIndex);
}
});
}
function cvdBubbleXmlProcess(nextIndex) {
var d = broadcastedXML;
//console.log(nextIndex);
var length = $(d).find('tweet').length;
if((nextIndex + 1) < length) {
nextIndex = length - 1;
$(d).find('tweet').eq(nextIndex).each(function(idx) {
var cvdIndexId = $(this).find("index");
var cvdTweetAuthor = $(this).find("author").text();
var cvdTweetDescription = $(this).find("description").text();
if (cvdTweetAuthor === "Animator") {
$('#cvd_bubble_left').html('');
obj = $('#cvd_bubble_left').append(makeCvdBubbleAnimator(cvdIndexId, cvdTweetAuthor, cvdTweetDescription));
obj.fitText(7.4);
$('#cvd_bubble_right').html('');
setTimeout('$(\'#cvd_bubble_left\').html(\'\')', 3000);
} else {
$('#cvd_bubble_right').html('');
obj = $('#cvd_bubble_right').append(makeCvdBubble(cvdIndexId, cvdTweetAuthor, cvdTweetDescription));
obj.fitText(7.4);
$('#cvd_bubble_left').html('');
setTimeout('$(\'#cvd_bubble_right\').html(\'\')', 3000);
}
});
}else{
$('#cvd_bubble_left').html('');
$('#cvd_bubble_right').html('');
}
//broadcastedXMLIndex++;
setTimeout('cvdXmlBubbleStart(nextIndex)', 3000);
}
Using an anonymous function will work because it shares the same scope as nextIndex.
setTimeout(function(){cvdXmlBubbleStart(nextIndex);}, 3000);
The reason that your current code does not work for you is because when you use a string inside of the setTimeout function it uses the Function constructor to create a function based on the string passed (which is similar to using eval and is not best practice). What is worse here is that the function created with Function will not share the same scope as where it was created and thus not have access to nextIndex.
Checkout How can I pass a parameter to a setTimeout() callback? - basically you need to pass an anonymous function to the set timeout call
setTimeout(function(){
cvdXmlBubbleStart(nextIndex)
}, 3000);
Can someone please explain to me what is wrong with my code below? I am declaring a public variable and setting it to a setTimeout, and if not null, clearing the timeout before it gets set again. When I try to clear the timeout I get undefined so the timeout continues to run.
var usernameCheckTimeout = null;
$(document).ready(function(){
$("#username").on("keyup", function(e){
if($(this).val().length >= 6)
{
if(usernameCheckTimeout != null)
{
clearTimeout(usernameCheckTimeout);
}
usernameCheckTimeout = setTimeout(isUsernameAvailable($(this).val()), 1000);
}
});
});
function isUsernameAvailable(username)
{
$.ajax({
url : "/account/username-check",
method : "POST",
dataType : 'json',
data : {
'username' : username
}
}).done(function(data) {
console.log(data);
});
};
You do not need to do the null check also you need to create a closure around this, otherwise this will refer to not what you think this actually is.
var usernameCheckTimeout;
$("#username").on("keyup", function (e) {
if ($(this).val().length >= 6) {
clearTimeout(usernameCheckTimeout);
var that = this;
usernameCheckTimeout = setTimeout(function () {
isUsernameAvailable($(that).val();
}, 1000);
}
});
Some jsfiddle love like usual.
The timeout is being cleared. The problem is that you are calling your function immediately instead of passing the function to setTimeout.
setTimeout(isUsernameAvailable($(this).val()), 1000);
isUsernameAvailable($(this).val()) will be called and the result of this call will be passed to setTimeout.
You should instead pass a function which calls this function:
EDIT: As #Mark said, you also need to deal with this not being what you expect:
var value = $(this).val();
setTimeout(function(){
isUsernameAvailable(value)
}, 1000);
You have a couple of issues. The first issue, which is huge, is that you are executing isUsernameAvailable($(this).val()) immediately and passing the return value to setTimeout - you need to move this into an anonymous function so it does not execute until the anonymous function is called by the timeout:
usernameCheckTimeout = setTimeout(function () {
isUsernameAvailable($(this).val());
}, 1000);
the javascript timeout functions rely on numeric IDs to function. You should avoid testing for null or undefined or anything else, and instead test for a number:
// leave it as undefined
var usernameCheckTimeout;
...
if (typeof usernameCheckTimeout === 'number') {
clearTimeout(usernameCheckTimeout);
}
I have an Ajax function that brings data of a web method and displays it on the page. I want to show the first page with 4 item on page load. When the button is clicked, the next four items should show, and so forth for the next clicks. This executes on page load, but when I click the button nothing happens.
$(document).ready(function () {
var s;
var countnumber = 0;
function dos(s, countnumber) {
participant = s.split("!");
var i
for (i = countnumber; i < countnumber + 4; i++) {
part = participant[i].split("ٌ");
rk = part[5];
if (rk == 1) {
$("#ts" + i).attr('src', 'con1.png');
} else if (rk == 2) {
$("#ts" + i).attr('src', 'con2.png');
} else if (rk == 3) {
$("#ts" + i).attr('src', 'con3.png');
} else if (rk > 3 && rk < 20) {
$("#ts" + i).attr('src', 'briliant.ico');
} else if (arrlist[5] > 20 && arrlist[5] < 50) {
$("#ts").attr('src', 'cup.png');
} else {
$("#ts" + i).attr('src', 'box.png');
}
{ $("#st" + i) }
$("#use" + i).html(part[1]);
$("#rnk" + i).html(part[5]);
$("#avg" + i).html(part[2]);
$("#pnt" + i).html(part[4]);
$("#wit" + i).html(part[3]);
$("#kl" + i).html(part[0]);
$("#use" + i).html(username);
}
}
$('#kil').bind('click', function () {
countnumber = countnumber + 4;
dos(s , countnumber);
})
var arrlist;
var participant, part;
var username, klll, wt, pt, av, rk;
$.ajax({
type: "POST",
url: "rank.aspx/bringdata",
data: "",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function (ret) {
s = ret.d;
dos(s, 0);
},
error: function (x, e) {
alert("error");
}
});
});
From what I've understood, you are trying to execute the dos() function via an onclick="" event.
The reason it doesn't work is very simple: dos() does not exist from the perspective of the global scope.
What you have to do instead is one of the following two:
Move the dos() function into a globally accessible scope.
Attach the dos() function to the click event via jQuery.
Personally, I would prefer the second option, because it avoids polluting the global namespace.
From local variables
Example: local variables
function f() {
var x = 1;
}
process_x(x); # this will trigger a "ReferenceError: x is not defined"
I am sure you are aware, that it is not possible to access a variable that is local to a function from the outside.
to local functions –
When you define a function inside a function, you are essentially creating a local variable that just happens to be a function.
Example: function declaration, this is the form that you have:
$(document).ready(function() { # enclosing_function
function dos() {
}
});
As previously explained, this will lead to dos() being local to the enclosing_function.
... which are essentially the same thing
You can think of it like this to better illustrate the similarity:
Example: function expression
$(document).ready(function() { # enclosing_function
var dos = function () {
};
});
Hoist the colo– functions high
In the example, the two versions are equivalent. However, a function declaration – that is, the thing that does not have a an assignment (those are so called "function expressions") – are "hoisted" at the top of the code, in which they are defined.
This means, that the definition is moved (or "hoisted") to the very top (or beginning) of the scope in which it was defined. It is not possible to execute code (in that scope) before defining that function. Thus, you cannot receive a ReferenceError for function declarations. (Unless you are in the wrong scope, that is.)
Function expressions on the other hand are evaluated the same way all other statements are: as soon as they are encountered by the program flow.
Example: Hoisting
$(document).ready(function() { # enclosing_function
# <- This is where "hoisted" is being defined <--
non_hoisted(); # ReferenceError |
hoisted(); # Works fine |
var non_hoisted = function () { # This is where "non_hoisted" is defined
|
}; ^
hoisting
non_hoisted(); # Works fine ^
|
function hoisted() { ------>-------->------->----
}
});
One more thing
var s;
function dos(s, countnumber) {
...
}
The formal parameter s will introduce s as a local variable inside the dos() function. It will shadow the s variable from its parent scope.
Why do you pass s as a parameter to the dos() function? You already assign it to the local variable var s inside the enclosing_function() when the Ajax request returns successfully.