I'm new to Jquery/javascript with almost all of my experience being in PHP. I am now finding the importance of how things are ordered :)
So I'm trying to load some <div>s into the container #text-container using .load and then count them. My understanding of jquery's load function is that the 2nd argument is a callback function which will only run once all data has been loaded. But it is always reported as 0 even if there are 4-5 divs being placed in the container. Am I missing something?
1.txt
<div>1</div><div>2</div>
Code:
$("#text-container").load("1.txt",alert($("#text-container div").length));
This is just an example but I need to use that number to do a whole bunch of maths in other functions. So if I call those instead of alert and try to run .length in there they all get 0 and my math doesn't work :(
Ideas?
You need an anonymous function for the callback
$("#text-container").load("1.txt", function(data) {
alert( $("#text-container div").length )
});
This is just an example but I need to use that number to do a whole
bunch of maths in other functions.
Note that it's async, so you can't use it until it's actually there, and why would your .txt file contain DIV elements, seems like the wrong file extension to me ?
Answer
$("#text-container").load('1.txt',function(){
alert($("#text-container div").length);
});
Explaination
First let us talk about the callback function passing, the right syntax:
$(selector).load(source,callback);
Suppose you have some function named as gg and we want to use it in place of callback
function gg(){
//some code for task 1
}
now lets use it as callback
(the wrong way)
$(selector).load(source,gg());
Note: when you write the function with parenthesis (), the function is called at the same time, so you just need to pass the identifier
(the right way)
$(selector).load(source,gg);
OR USE ANONYMOUS FUNCTION
$(selector).load(source,function(){
// some code for task 1
});
Note: Instead of defining a function only for callback and if you are not using it again it is preferred to use anonymous function
You are not doing what you think you do. You pass the result of alert() as an argument.
$("#text-container").load("1.txt",alert($("#text-container div").length));
is equivalent to :
var data = alert($("#text-container div").length); // data = 0
$("#text-container").load("1.txt", data);
What you want is to pass a function as an argument :
var callback = function() {
alert($("#text-container div").length);
}
$("#text-container").load("1.txt", callback);
or shorter :
$("#text-container").load("1.txt", function() {
alert($("#text-container div").length);
}
Related
I had a doubt about replacing some characters in a textbox using jQuery and I landed in this question. The accepted answer suggested something like this:
$("#mySelector").val(function(i, v) { //i, v... where they come from??
return v.replace("#","Custom Text");
});
That works fine but I still have the same doubt. Those parameters, i and v. Where do they come from and how they are filled with data? They are not declared anywhere. How do i and v in this case, has the data that I need?
These answers talk about it, but it seems just an overcomplicated explanation for what should be, an easy thing to explain.
So, the question is simple. How in the world those parameters in the anonymous function, get filled with data. Where do they come from if I didn't declare them anywhere?
They are set when the jQuery library calls the callback. Note that you are passing a function as a parameter into the $.val function. The $.val function passes values to the function that you passed to it.
Here is a simple example of how callbacks work:
function coolFunction(callback) { // accepting callback
// extra processing here
callback(1, 2); // calling the callback
}
coolFunction(function(a, b) { // passing function as callback
console.log('annonymous', a, b);
});
The jQuery function val checks the argument passed into it. When it finds a function, it calls it for every element contained in the selector, where i is the index of the element in selector, and v is the value... ie the element's value.
I am trying to get image in Base64 format outside of
var codedPic;
var purl = 'http://upload.wikimedia.org/wikipedia/commons/4/4a/Logo_2013_Google.png';
var codedPic = convertImgToBase64(purl, function(base64Img){ console.log('attempt 1: ' + base64Img); });
console.log('attempt 2: ' + codedPic);
It is getting results of attempt 1 but for attempt 2 it displays undefined. But I need it working too. Can anyone help me please?
Please feel free to amend this jsfiddle: http://jsfiddle.net/s7x0otdc/2/
(in fiddle) after you complete the conversion, you call callback, therefore nothing is stored in codedPic variable.
you can fix it by using return codedPic; instead of using callback
or you can do everything you need in that callback function (because after completing callback function you lose "hers" variables)
i suppose there is some way with global vars.. but just now i don't know how i would do that
EDIT:
New demo to show you how to modularize your code. The encoded picture is available outside of your conversion function (more precisely in your global variable codedPic). But you have to wait for your callback to be triggered to be sure it now has the correct value.
http://jsfiddle.net/s7x0otdc/7/
Well you have several mistakes in your code.
As pointed out by Jimmmy, your function does not return anything, so the assignment var codedPic = convertImgToBase64(purl /* ... */ ); is useless as codedPic will remain undefined.
Time to read How to return the response from an asynchronous call? to understand why you need to use callbacks, and that you have to put any code that depends on a server response inside a callback. Since your conversion function needs to wait for the load event of your image, you will get data into dataURL at an unkown moment in the future. When this moment arrives, JS will trigger your callback and give it that data as argument, as per your conversion function specifies. So only your callback can safely assign your desired data into a global variable, and trigger any action that depend on that data.
Demo: http://jsfiddle.net/s7x0otdc/5/
I would like to know the difference between 2 implementations of callback functions.
This:
$("#button").on('click', function () {
//do something
});
Versus having the function already defined.
$("#button").on('click', btnFunction);
function btnFunction() {
//do something
}
Are there any implications with one compared to another? Performance-wise is one faster?
The first uses an anonymous function and the second does not. There's no difference in both.
See:
Why do you need to invoke an anonymous function on the same line?
Some folks prefer the second form because it gives a function name when using the debugger and tracing, but there are ways to get the same functionality in the first form.
If you are attaching and removing the event handler based on changing conditions, the second form is much easier to maintain, however.
There's no difference at all, and there's no performance issue with neither one of them. The only difference is that in one of them you're defining the callback function as an anonymous function, this way you cannot reuse it.
The other way, where you define it else where and named it and then pass it as a callback, you're defining a function that you can later reuse in another part of your code.
For example: if you want to do something when the document is ready, and then do se exact same thing when some one press a button you can use something like this:
function getData() {
//do something
}
$(function() {
// Call the function once the DOM is ready
getData();
});
// Call the same function when the button is clicked
$("#refresh_button").on('click', getData);
In most cases the first one will be used, called Anonymous Functions
The second one will be used when the function is not only used inlined here, but also needs to be reused somewhere else.
But anyway it could be a personal preference.
The only real difference you could see is that stack trace (if an exception is thrown for example) will be better, i.e. easier to debug, when using the second one.
Just reuse-ability.
In the second case, you could call btnFunction() somewhere else if need be.
I learn now that a callback is function that pass to argument.
but I can do it without so what is the point?
for example
function i()
{
alert("callback");
}
function p(a)
{
for(r=0;r<100;r++)
{document.write(r);}
a();
}
p(i);
or
function i()
{
alert("callback");
}
function p()
{
for(r=0;r<100;r++)
{document.write(r);}
i();}
I searched but could not find an answer
Callbacks are usually used when you want to do something with some data that isn't immediately available.
For example, to process some data from an HTTP response when the response arrives or to perform an action based on where a mouse click occurred when the mouse button is clicked.
So to take you example, yes if you want to call i() in function p() you can just go ahead and do that. But what if you want a function just like p() accept that it calls j() at the end instead of i()? Well, that's easy, you pass a function as a parameter for p() to call at the end instead of hardcoding it.
It's about flexibility. There's no need to do it for the sake of doing it, but there are many cases where it's useful.
So let me try and come up with a simple example, let's say we have a function called sum() that adds up all the elements of an array. Now let's say somewhere in our program we want to sum not all the elements, but some of the elements, maybe only the elements over a certain value, or every other element. If we set up sum so that it could take, in addition to the array to work on, a function parameter that will call filter (which if left null, we'll just sum all the elements by default), we could make our sum() function much more useful and avoid writing a whole bunch of different sum functions.
Also, as Quentin already answered, it's especially useful for asychronous functions.
Is it possible to edit a JavaScript function after the page has loaded?
I want to edit a function dynamically after Loading.
You can't edit a function, but you can replace it, e.g.:
var myFunc = function() { return "Hello World"; };
myFunc = function() { return "Goodbye"; };
javascript functions are objects, so can be replaced by setting a new value. Is this what you mean?
Unless you are trying to hack some code that doesn't belong to you, the better solution is to write a more flexible initial javascript function who's behavior can be adapted based on conditions (parameters passed, environment, other state, data fetched from other sources, etc...). Then, the one function you have can be written once initially to handle all your different circumstances.
You can even use design patterns such as passing in callback functions that can be used to adapt the behavior at runtime. If you desire many callbacks, you can pass in an object that has a number of different optional methods and call those during your function. In this way you can significantly alter the behavior of the main function without ever changing it's code by passing in different callback functions.
For example, let's assume we have a parsing function that takes some tagged data structure as input and returns an array of results. We want to be able to modify the behavior of this parsing function by passing in callbacks. So, we write the parsing function to take a callback object. That callback object contains one or more methods (all of which are optional) and a state variable that is passed to each callback. Anyone who has worked with ajax or any asynchronous networking in Javascript will recognize the callback object concept. Here's some pseudo code for such a process that shows how the callback object can be used. A real function would obviously be a lot more involved than this one, but it hopefully illustrates the concept:
function parseMyData(data, callbacks) {
var output = []; // output we accumulate
var currentTag;
callbacks = callbacks || {}; // make the callbacks object optional
// do any preprocessing that the caller specified
if (callbacks.preProcessData) {
data = callbacks.preProcessData(data, callbacks.state);
}
[[code to parse to the first tag in the data (after doing so currentTag contains the tag we just parsed)]]
// give our callback object the opportunity to do something to this tag or return null to skip it
if (callbacks.preProcessTag {
currentTag = callbacks.preprocessTag(currentTag, callbacks.state);
}
if (currentTag) {
[[code here for the default processing of the tag that will push results into the output array]]
}
return(output);
}
If you want to add an action to the existing function you can "hijack" it by putting it in a temporary variable and calling it within your overwritten function. E.g.
// The original function.
function sayName(name) {
alert(name);
}
// Temporary variable for original function.
var __sayHello = sayName;
// Overwrite the original function, adding extra actions.
sayName = function(name) {
alert('Hello');
// Call the original function using its temporary variable.
__sayHello(name);
}
// Call the overwritten function.
sayName('Bob');
How to edit a function - 101.
If we reconsider that editing a function at runtime is not absolutely changing the guts of the function, but rather changing what the function guts are digesting, then I would say functions are already built to do just that.
example 1 - The guts cannot be changed.
function one(){
return true;
}
// one() => true;
// Note: We could still change the output without changing the guts.
// !one() => false;
example 2 = The guts can be created to digest a dynamic call.
function one(payload){
return payload;
}
// one(true) => true;
// one(false) => false;
// one('whatever I want to feed the guts to digest');
// => 'whatever I want to feed the guts to digest';
These are quite simple examples, but since you did not provide any real examples as to what you are trying to do, we have to assume you are attempting normal patterns of programming.
Considering NORMAL patterns of programming, it wouldn't be the function itself that needs to change, rather how you are calling it.
example 3 - Give the choice of which function to the caller.
function firstChoice(payload){
return http.post(payload);
}
function secondChoice(choice){
return `Do something else with ${choice}`;
}
// And where you make the choice, perhaps after a click event handler...
function onClick(choice, payload){
choice ? firstChoice(payload) : secondChoice(choice);
}
Functions are supposed to be small bricks with which you build logic. Give them something small to do, then select between them based on your logic.
To answer your question, in my opinion, assuming normal programming needs...
"Is it possible to edit a JavaScript function after the page has loaded?" YES.
Use arguments in your function definition to add the dynamic ability to suit your needs.