Reputation: 2009
I am trying something like:
var usernameDone = false;
/*Some application logic*/
alert(usernameDone);
This is always evaluating to undefined
. However, if I change the variable name from usernameDone
to anything else, even usrnameDone
, the script works fine. Does usernameDone
conflict with jQuery? If not, then why does it happen?
(I am testing on Chrome with jQuery-1.6.1 currently and have not tried other browsers.)
[Update]
The variable evaluates to undefined
even if the application logic is eliminated.
[Update-2 The full code]
I have marked the usage using //
comments
$('document').ready( function() {
/**
* The following set manages the effects for the login menu. The effects including highlighting
* the login box when focused, showing guidance through a pop-up menu and handling transformation
* through fade effects.
*
*/
var usernameDone = false; //Declared here
/**
* @function login-box focus()
* Handles the onFocus() effects of the login box and displays the initial guidance pop-up box.
*
*/
$('#login-box').focus( function() {
/**
* Color change effect of the login box
*/
$(this).css('background-color' , '#000');
$(this).css('color' , '#FFF');
$(this).css('border' , '2px solid #000');
/**
* Fade in effect of the login guide
*/
$('#login-guide').fadeIn(1200);
$('#login-guide-triangle').fadeIn(1200);
});
/**
* @function login-box focusout()
* Handles the focusOut effects of the login box and hides the guidance pop-up box.
*
*/
$('#login-box').focusout( function() {
/**
* Color change effects of the login box
*/
$(this).css('background-color' , '#FFF');
$(this).css('color' , '#000');
$(this).css('border' , '3px solid #000');
/**
* Fade out effect of the login guide
*/
$('#login-guide').fadeOut(1200);
$('#login-guide-triangle').fadeOut(1200);
});
/**
* @function login-box bind(keypress)
* Handles the progression of the login steps. Specifically, what state the login box is in
* (ie, username or password) and how to respond when the state change key ('return/enter key')
* is pressed.
*
*/
$('#login-box').bind('keypress' , function(e) {
/**
* Checks for the current state (using usernameDone) if not, then registers the current username
* changes the state to username done and converts the login box into password. Also, changes the
* guidance contents.
*/
alert(usernameDone); //Always undefined (no modification before this)
if(e.keyCode == 13 && usernameDone == false) { //Owing to undefined it never evaluates to true.
var loginUsername = $(this).val();
$(this).val('');
var usernameDone = true;
$(this).fadeOut(0);
document.getElementById('login-box').setAttribute('type' , 'password');
$('#login-guide-title').html('Password');
$('#login-guide-info').html('Press enter to login');
$(this).fadeIn(800);
}
});
});
Upvotes: 0
Views: 3969
Reputation: 7663
Two things:
usernameDone
will be defined when
your <document>
tags are fully
loaded. On the off-chance those
don't exist, you want
$(document).ready()
.usernameDone
? I don't see an alert
function in your example, so I can only assume you're trying to access it outside of $(document).ready()
. That won't work. If you want that functionality, declare var usernameDone
outside of that function block.The following examples work just fine:
$(document).ready(function() {
var usernameDone = false;
alert(usernameDone);
});
and
var usernameDone;
function testMe() {
alert(usernameDone);
}
$(document).ready(function() {
usernameDone = false;
testMe();
});
Upvotes: 0
Reputation: 30498
Some explanation is required here:
Douglas Crockford recomends that you declare all your JavaScript variables at the top of your nearest scope, because that's what effect Javascript does when it interprets the code.
This is a term known as 'hoisting'.
This is a perfect example of the confusion that can be caused by not doing this and why his JSLint tool highlights this.
You nearest scope is the function immediately above. JavaScript does not have 'block' scope, the if
block does not define any local scope.
So in you example, the declaration is effectively moved to the top of the function, and the assinment made later (where you do it). This means that the variable is, in fact, undefined at the point you check it, as it overloads the one declared in the scope above.
Upvotes: 1
Reputation: 8527
You are re-declaring the variable in the last if statement. Since the second declaration happens inside a child scope (function), but after the alert is called, the javascript parser is waiting for the new value to be assigned, and until then it is undefined.
If you remove the var, you will be fine.
Upvotes: 1
Reputation: 195992
The problem lies at
var loginUsername = $(this).val();
$(this).val('');
var usernameDone = true; // <-- PROBLEM HERE
You re-define the variable inside the keypress method.. so it is undefined..
remove the var
part
usernameDone = true;
and you will be fine..
demo http://jsfiddle.net/gaby/3CrZG/1/
Upvotes: 1
Reputation: 117334
remove the var
when assigning the value inside the function, the var
makes the variable private.
Upvotes: 2
Reputation: 45589
Of course it is going to be undefined
, because you listen for a ready
event on the string 'document'
not on the variable document
. Do NOT enclose the variable document
with single or double quotes, otherwise the ready
event will never fire, hence why your variable is never defined. Also, do not re-declare the variable usernameDone
with var usernameDone = true;
, just assign a value to it like this usernameDone = true;
, because it is already defined.
Upvotes: 7