Why How to Not Define Functions in Jquery's Document.Ready()

Why can I not define functions in jQuery's document.ready()?

Not sure why defining the function with in the scope of ready() is important to you, but you can make it work by declaring foo up front:

<html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script>
var foo; // Here's the difference
$(document).ready(function(){
foo = function ()
{
alert('Bar');
}
});
</script></head><body>
<input type="button" onclick="foo()" value="Click me">
</body></html>

Obviously you can't call foo() from the inline script immediately after ready() because the ready() code hasn't yet run, but you can call the function later on.

Just make sure that nothing can try to call foo() before the ready() code has run (or make the initial declaration of foo() a harmless function).

Javascript function not defined within document.ready jquery code

Haven't been able to double-check, but I'm guessing it's because of the scope of the submit callback. Try something along these lines;

$(document).ready(function(){   
$('#upload').submit(function(){ window.startProgress('<?php echo $uid; ?>'); });
});

var startProgress = function(uid) {
console.log("starting progress");
setTimeout('getProgress("' + uid + '")', 500);
//some more stuff
};

var getProgress = function(uid) {
console.log("getting progress");
$.ajax({ type: "GET",
url: 'upload_getprogress.php?uid=' + uid,
success: function(msg) {
progress = msg;
setTimeout('getProgress("' + uid + '")', 100);
// do some more stuff
}

});
};

window.startProgress = startProgress;
window.getProgress = getProgress;

Why is a function declared in document.ready() not defined when called?

You're placing the function's scope within another function, basically.

Picture this:

<script>
document.onload = function(){
function foo(){
alert('bar');
}
};
foo();
</script>

That is the facsimile of what you're trying to accomplish. Just like variables defined within a function are off limits outside of it, function names take on the same characteristics.

Side-Note JavaScript doesn't require $ prefix on variable names (though is acceptable as far as names are concerned). I didn't know if you're coming from PHP and are just accustomed or were aware.

Thought I'd make my comment an answer.

Should a Javascript function be written and called inside jQuery document ready or outside?

I think you should defined your functions outside the jQuery ready method, because:

  • the function definition code is a "passive" code: it doesn't need the DOM to be runt
  • if you want to use your function before the ready event, you can't do it if the function is defined inside the event,
  • the jQuery ready method should be used only when it's really needed, it means when you *really have to wait for the DOM to be ready

For information, here is a simplified but common HTML page pattern that I use every time, it works pretty well:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Page title</title>
<!-- your CSS code -->
<link rel="stylesheet" href="/path/to/file.css">
</head>
<body>
<!-- your HTML elements -->

<!-- all your scripts elements at the bottom -->

<!-- load jQuery from Google CDN -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<!-- load all your "passive" code that defines custom or vendor jQuery plugins -->
<script src="jquery.plugins.js"></script>

<!-- load all your "active" code -->
<script src="yourcode.js"></script>
</body>
</html>

The jquery.plugins.js file could contains something like you provided:

// define all jQuery plugin, aka "passive" code
// "passive" means it won't affect the page
$.fn.jQueryExample = function(){
//Do something
};

$.fn.somePlugin = function(){
// Do something
};

// you could define vanilla JavaScript functions in a separated file if you want
function nativeExample(a, b)
{
return a + b;
}

The file yourcode.js could be:

// place here all "active" code
// by "active" code I mean all code that will interact/alter/modify your page
$(function(){
$('select').jQueryExample();
nativeExample();
});

About your edit, your question what would happen as opposed to having it defined outside but called inside document ready doesn't have a universal answer. Look at this example:

<!-- basic html setup -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Page title</title>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
// placing <script> tag in the <head> tag is considered as a bad practice
// I use it for the example but you should not do the same in real code

// define your functionsin the <head> tag
function getFoo() {
return "foo";
}
function getAnchor() {
return document.getElementsByTagName('a');
}
</script>

<script>
// reference: ONE
// call your function in the <head> tag
console.log( "one", getFoo() ); // "foo"
console.log( "one", getAnchor() ); // empty array
</script>
<script>
// reference: TWO
$(document).ready(function(){
// call your function inside the jQuery 'ready' event
console.log( "two", getFoo() ); // "foo"
console.log( "two", getAnchor() ); // array with one element
});
</script>
</head>
<body>

<a href="www.example.com">bar</a>

<script>
// reference: THREE
// call your function at the end of the <body> tag
console.log( "three", getFoo() ); // "foo"
console.log("three", getAnchor() ); // array with one element
</script>

<script>
// reference: FOUR
$(document).ready(function(){
// call your function inside the jQuery 'ready' event
console.log( "four", getFoo() ); // "foo"
console.log( "four", getAnchor() ); // array with one element
});
</script>
</body>
</html>

The function getFoo doesn't need the DOM to work. So, its 4 calls always returns 'foo', so the function works wherever and whenever she was called (inside or outside the 'ready' event).

The function getAnchor query the DOM and return a collection of the anchor tag in the page. The first call, in the script "ONE", is outside the ready event and returns undefined. The third call, in the script "THREE", is also outside the ready event but it logs an array of anchor elements in the console. This means that, the placement of the function call can alter the function behavior. In the first call, obviously the anchor tag was not present in the page, and that's why the function returns undefined. Then, the second call and fourth call, placed at the beginning and at the end of the page, both logs an array. In this case, the placement of the function call doesn't alter the function behavior, because the function getAnchor is actually called after all the DOM elements have been loaded. If you look at your console logs, you'l see something like this:

one foo
one []

three foo
three [<a href=​"www.example.com">​bar​</a>​]

two foo
two [<a href=​"www.example.com">​bar​</a>​]

four foo
four [<a href=​"www.example.com">​bar​</a>​]

Look at the log order: one, three, two, four; which is different from the source order: one, two, three, four. Functions is the ready have been delayed until the page loading is complete.

function declared inside document.ready is undefined?

Because in Javascript, functions declared within other functions are local references, and are not visible outside the scope of their parent function. If you want to make your updateSizeOptions function globally accessible, you will need to assign a reference to it in a global namespace, say a window property:

window.updateSizeOptions = updateSizeOptions;

Javascript function inside document.ready

Because it's not available in the global scope. Any function defined within the anonymous function you pass as an argument to $.ready() is only available within that function.

To achieve what you want to do you need something like:

$(document).ready(function(){
function abc() {}

$('#a').on('click',abc);
});

For more information on function scope see this MDN article

jQuery - function inside $(document).ready function

Yes, you can do that, it's just a matter of scope.

If you only need to access callMe() from within $(document).ready(function() { }), then it's fine to put the function there, and offers some architecture benefits because you can't access the function outside of that context.

If you need to use the callMe() function outside of document ready though, you need to define the callMe() function outside of that context.

function callMe() {
// Do Something
}

$(document).ready(function() {
callMe();
});

UPDATE

Based on your clarification, you have two options:

1) DECLARE variable outside of ready(), but then define variable inside of ready():

var someVariable;
function callMe() {
someVariable++;
alert(someVariable);
}

$(document).ready(function() {
someVariable = 3;
callMe(); // Should display '4'
});

2) Within ready(), define variables using window.yourVariable = 'whatever';

Why doesn't jQuery document ready function run in my code?

It looks to me like nowhere in your code contains a <script> tag that includes the jQuery library into the page, so the browser doesn't understand what $(document).ready means. jQuery is an external library and not part of JavaScript by default, so you must include it manually.

You need a tag like the following (source) to include the jQuery library on the page:

<script
src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous"></script>

Then your code should execute, as long as the library is being included before your script. A good place to put the above tag would be inside the <head> tag of your HTML, before your own <script> tag. This should ensure the library is loaded before your script runs.

when has a function to be in $(document).ready()

A lot of what you're seeing is because of jsFiddle's very surprising default setting, which is to wrap the code in the script pane in an onload handler. So your code is wrapped in a function and no longer at global scope (which is where functions need to be if you use onclick-style attributes). You can change this with the drop-down box on the left (the second one, under the list of libraries and scripts). Change it to "no wrap" to have unwrapped code.

You're not (by far!) the first to be bit by this surprising default.


Answering your main question:

when has a function to be in $(document).ready()

If you control where the script tags loading your script go, you basically never have to use ready; instead, just make sure your script tags are at the end of the HTML, just before the closing </body>.

You can use ready, of course. The reason for doing so is to make sure that all the DOM elements have been created before your code runs. But if you put your script tag at the end, that's already true. You can still define your functions outside of the ready handler (if you want them to be globals), but if you're using ready, you would call them from the ready handler so the elements exist.


FWIW, I would avoid using onclick-style attributes for hooking up event handlers, primarily because they require you to create global functions. I prefer to avoid creating any global symbols when I can avoid it.

The general form I'd recommend:

<!-- ...your page markup here... -->
<script src="any_libraries_you_need_if_you_are_not_combining.js"></script>
<script src="your_script.js"></script>
</body>
</html>

where your script looks like this:

(function($) { // A scoping function that wraps everything
// Hook up event handlers here. You can use `$` for jQuery, even if
// you've used noConflict, because we have a private `$` symbol (see
// the `$` argument above)

// The body of your code goes here

})(jQuery); // <== Note how we're passing the jQuery reference in
// and immediately executing the scoping function

Here's a complete example: Live Copy

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Script Placement Example</title>
</head>
<body>
<input type="button" class="hello-button" value="Click me">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
// This would be in a file, rather than inline
(function($) {
// Hook up handlers
$(".hello-button").click(sayHello);

// Body of the code
function sayHello() {
$("<p>Hello!</p>").appendTo(document.body);
}
})(jQuery);
</script>
</body>
</html>


Related Topics



Leave a reply



Submit