I have a javascript file that I'm am calling in the head of an HTML file, it's called custom.js, it defines this function:
var example = function(element){
console.log(element);
};
Then in the actual HTML document, just before the body tag closes, I try to initialize it by calling the same function like this
example('.header-background');
I get the error example is not a function, what exactly am I doing wrong? Thank you so much for your help.
here is a bit more context
<!DOCTYPE html>
<html>
<head></head>
<body>
// the main body of html
<script src="custom/custom.js"></script> // here is the file with the example function
example ('.header-background'); // here im calling the function
</body>
</html>
Change var example to window.example. If you declare a variable with var inside of a function or closure it isn't globally accessible.
e.g.,
function foo()
{
var test = 'hi';
}
console.log(test); // error, test isn't accessible
function foo()
{
window.test = 'hi';
}
console.log(test); // works
Global variables should generally be avoided there. There's most likely a better way to do what you want to do.
Make sure to the file where your function in the html page you are calling the function:
<script type="text/JavaScript" src="youtpathtothefile/custom.js"></script>
Hope it helps
Please make sure two things:
your javascript file is loaded after jQuery library.
your javascript is loaded after the every dom in the html file has finish loading.
Maybe that could help you.
Related
I'm looking for a way to pass functions as parameters to the script tag. For example, to make the following work:
<script src="http://path/to/widget.js?param_a=1¶m_b=3" data-myfunc={myfunction()}></script>
<script>
myfunction() {
console.log("hello world")
}
</script>
And then trigger the function from the script.
Since we can pass values in attributes and capture using getAttributes : ref
Try this
<script>
// move function definition above and pass function ref - don't call that function
myfunction(){
console.log("hello world")
}
</script>
<script src="http://path/to/widget.js?param_a=1¶m_b=3" data-myfunc={myfunction}></script>
Yes there is a way!
you can delete the " () "
just turn :
<script src="http://path/to/widget.js?param_a=1¶m_b=3" data-myfunc={myfunction()}></script>
into:
<script src="http://path/to/widget.js?param_a=1¶m_b=3" data-myfunc={myfunction}></script>
And over!
It's my pleasure to help you!
by the way if you are interested, please help me also:
The is my question
that's pretty easy however it won't be accurate as you don't know which script tag will work first or if it will be compiled using inline or not.
if it uses inline your code will not work and you have to use the server to render javascript instead
here is an example using pure javascript. in my understanding you want after loading script /widget.js it will execute function stored in data-myfunc:
widget.js
if (document.currentScript) {
const script = document.currentScript.getAttribute('data-myfunc')
if (script) {
new Function(`
// sandbox faker
const window = undefined;
const document = undefined;
const Document = undefined;
const Window = undefined;
// run script
${script}
`)()
}
} else {
console.warn('widget.js loaded inline. Not working')
}
note if you want to declare the function myFunc after the script /widget.js you have to edit my code to use events like DOMContentLoaded to make sure the function exists
I have two files as below:
trycapture.js (which has) trycapture() (which has) drawaggregate() definition
main.js from which I want to call drawaggregate();
trycapture.js
trycapture(){
... some code
function drawaggregate(){
... definition
}
}
main.js
.. some variables
var try_obj = new trycapture();
try_obj.drawAggregate(emit_x1,emit_y1,emit_x2,emit_y2);
HTML
<head>
<script src="trycapture.js"></script>
<script src="js/main.js"></script>
</head>
How can I call that function. I tried creating an object right before calling drawaggregation() such as above:
I still get the error:
TypeError:try_obj.drawaggregate is not a function
Also, in index.html I made sure that I include trycapture.js before main.js How can I call that function?
Add
this.drawaggregate = drawaggregate;
after your function definition to make it a public method of the trycapture object.
Overall, you will change your trycapture.js to the following:
function trycapture(){
... some code
// Locally accessible only
function drawaggregate(){
... definition
}
this.drawaggregate = drawaggregate; // Makes it publicly accessible also
}
the drawaggregate() method can then be called like so:
var try_obj = new trycapture();
try_obj.drawaggregate();
I've got some problems splitting up my jquery source code into more than one file. My real source code is a bit more complicated but the following simple example shows my problem very good. At first I would like to show you a working example with only one javascript file. Afterwards, I will describe what I tried in order to split the javascript into two files.
My html code looks like this ("./jquery" is a symbolic link to my local jquery download):
<html>
<head>
<script src="./jquery"></script>
<script src="./file1.js"></script>
</head>
<body>
<div id="content"></div>
</body>
</html>
The jquery source code in file1.js looks like this:
$(document).ready(function() {
var Test = (function() {
var content = $('#content');
var init = function() {
content.html('<p>test</p>');
};
return {
init: init
}
})();
Test.init();
});
After opening the page, "test" is displayed so that this example works as expected.
But now I want to put the whole Test part into another file file2.js. My html is basically the same but gets an additional line:
<script src="./file2.js"></script>
file1.js now contains only the call of the init function:
$(document).ready(function() {
Test.init();
});
and file2.js contains the definition of Test:
var Test = (function() {
var content = $('#content');
var init = function() {
content.html('<p>test</p>');
};
return {
init: init
}
})();
When I open the page, "test" is not displayed any more. In order to make sure that the init function is called at all, I added a console.log("test"); to the init function which is working fine. Therefore, I suppose that the function might be called before the DOM is ready, but actually I am pretty clueless. Maybe someone can give me a hint how to make that run.
Best regards and thanks in advance!
You can do several things according to your preferences...
1. Move your scripts to the end of the HTML file intead than in header...
<html>
<head>
</head>
<body>
<div id="content"></div>
</body>
<script src="./jquery"></script>
<script src="./file2.js"></script>
<script src="./file1.js"></script>
</html>
Think this problem secuencially... if you don't want to declare a var in each module referring an element in your DOM you need that the element exists first, then you can declare the "global" var to the module content. This way your original file2.js works.
Another way is to declare the content "global" to your module but init this in your init function...
var Test = (function() {
var content;
var init = function() {
content = $('#content');
content.html('<p>test</p>');
};
return {
init: init
}
})();
Now you can use the content variable in all of your module's functions.
Hope this helps, let me know.
file1 depends on file2. Make sure file1 comes ordinally after file2 in your html.
AngularJS offers dependency injection, modules, services, factories and all sorts of other goodness. Takes a bit to get used to, but well worth it IMO: much cleaner abstraction of javascript from DOM, data from presentation etc.
I appreciate your question is JQuery specific, but especially if you're starting a new site, I suggest you give Angular a try.
Modify your file2.js as follows:
var Test = {
content : $('#content'),
init : function() {
Test.content.html('<p>test</p>');
}
//, include other functions here
};
Modify your file1.js as follows:
$(document).ready(function(){
Test.init();
})
Now declare file2.js before your declare file1.js because file1.js is referencing a function from file2.js .
I currently have a HTML file that has one script that is declared as follows:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
code.......
var a = "hello"
});
</script>
I am trying to add another script within the HTML file that will call on this variable "a". Right now, I am doing something like this:
<script type="text/javascript">
alert(a);
</script>
But it is not alerting anything. If I replace a with a string like "hello", I do get alerted. Am I calling the variable wrong? I've tried searching for solutions but all of them say you should be able to easily call variables from another script assuming that script is declared and initialized before. Thanks.
Move the a declaration outside of the function.
E.g.,
var a;
$(document).ready(function() {
code.......
a = "hello"
});
And then later on...
alert(a);
Remember that variables are function-scoped, so if you define it inside of a function, it won't be visible outside of the function.
Update based on comments:
Because you now have a timing issue when trying to interact with the a variable, I would recommend introducing an event-bus (or some other mechanism) to coordinate on timing. Given that you're already using jQuery, you can create a simple bus as follows:
var bus = $({});
bus.on('some-event', function() {});
bus.trigger('some-event', ...);
This actually lends itself to some better code organization, too, since now you really only need the bus to be global, and you can pass data around in events, rather than a bunch of other random variables.
E.g.,
var bus = $({});
$(document).ready(function() {
var a = 'hello';
bus.trigger('some-event', { a: a });
});
And then in your other file:
bus.on('some-event', function(e, data) {
alert(data.a);
});
JSBin example (obviously not spread across multiple files, but the same principles apply).
Replace your code as
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">
var a="";
$(document).ready(function() {
a = "hello";
});
</script>
Now you can access the variable a as below.
<script type="text/javascript">
alert(a);
</script>
The problem with your code was that, you was declaring the variable a inside $(document).ready() which made it local to the ready().
When you write a inside function block you make it a local variable, you can move variable declaration outside of the function block as other answer say or you can use:
$(document).ready(function() {
window.a = "hello";
});
and later:
alert(a);
In both cases you are declaring a as a global variable and that is not recommended.
I can't get following problem.
I define variables like this:
<script type="text/javascript">var myVar;</script>
<script type="text/javascript" src="/myScript.js"></script>
myScript.js looks something like this:
$(document).ready(function() {
myVar = new myClass();
myVar.init();
});
if I try to access the variable like this:
<div onclick="myVar.activate(x);">some content</div>
all is working fine, but if I do
<img src="path" onload="myVar.activate(x);"/>
I get an error "myVar is not defined". I don't get it.
<script type="text/javascript">var myVar;</script>
some DOM Elements
<script type="text/javascript" src="/myScript.js"></script>
<script type="text/javascript">myVar.activate(x);</script>
Is not working either?!?!! Weird, isn't it?
*x is generated serverside *
$(document).ready(function(){
// this function is executed after the entire document is ready,
// and it will fire after window.onload
myVar = new myClass();
myVar.init();
});
Here you are trying to access a method of myVar, but your .ready() function hasn't fired yet so myVar has not been set to new myClass(). It is still an undefined variable
<script type="text/javascript">
myVar.activate(x);
// this script executes *before* the code inside your document ready function,
// so this is *before* you have set myVar = new myClass();
var_dump(myVar);
// above should output 'undefined'
</script>
If you really need/want to call this method in an onload attribute, then you should set myVar to new myClass() in your inline script, like this:
<script type="text/javascript">
var myVar = new myClass();
myVar.init();
myVar.activate(x);
</script>
If it's absolutely necessary that your code to assign a value to myVar happen in the doc ready, a better way to handle this would be something like this:
$(document).ready(function() {
myVar = new myClass();
myVar.init();
$("#idOfMyImage").load(function() { myVar.activate(x); });
});
What happens here is that you are attaching the load handler only after the dom ready event is fired and myVar has a value assigned to it. If the image has already loaded by the time the doc ready fires, then this will execute immediately, it it hasn't, it will fire when the image loads. Now you've removed the race condition where you code depended on the order those two events would fire in (your original code might have worked if the server delivering the image was slow enough providing the data - what is probably happening is that the image you are loading is cached by your browser).
As a bonus, you've now got rid of the inline event handler which make a better separation of your HTML from your Javascript.
There is nothing scary here, you just doesn't declare the variable at a good time. When using online script, variable must be assigned before the browser read the DOM node.
In your code, you assign myVar on DOM ready, hence the browser already finished reading the DOM and throw an error.
My question now is why do you need to wait the DOM to be ready before creating an object? There sure have a work around.
The following function is executed when your HTML is completely rendered
$(document).ready(function() {
myVar = new myClass();
myVar.init();
});
And the following is rendered as soon as it's downloaded and added in the HTML by the browser:
<img src="path" onload="myVar.activate(x);"/>
So myVar cannot be defined, because when <img> is rendered by the page, ready() has not been called yet.
Same reason for your second example. myVar is null
You should remove:
$(document).ready(function() ...
And try again.
why not simply, depending on what x is and where it's declared, obviously:
$(document).ready(function() {
myVar = new myClass();
myVar.init();
myVar.activate(x);
});
the nett result should be the same without the error
Thanks to Billy Mathews, i do know why it is not working. Thank you very much!
This is now how i did it (not clean, but working!)
<script type="text/javascript" src="/myScript.js"></script>
myScript.js looks something like this:
$(document).ready(function() {
var ServerGeneratedValue = $('myID').html();
var myVar = new myClass();
myVar.init();
myVar.activate($ServerGeneratedValue);
});
Thank you very much to all answers!