Function from External file is not defined [JS] - javascript

Hello I have a problem with JavaScript function.
I have 3 external JS files that are included to my JS file like that:
var badgeJs = document.createElement('script');
badgeJs.type = 'text/javascript';
badgeJs.src = 'url'
document.head.appendChild(badgeJs);
So here is the problem I need to use 3 functions, but sometimes I received error
Refference error: functionName is not defined, after that I refresh the page and first function works but second one no, and every time on refresh some of functions are not defined.
I don't know what is the problem and why this happen? Any advice will be appreciate.
I don't know if this is gonna help but JS code is for a shopify-app
How I call functions
var content = 'function1(param);function2(param1, param2, param3, [10, 25]);function3(param1, param2);';
(function() { var script = document.createElement('script'); script.text = content; var body = document.querySelector('body'); body.append(script);})();

Your file inclusions run at the sime time you're trying to call your functions. As the file inclusion need time to load your files, you are calling the functions before they have been loaded.
You have to manually add your scripts to the HTML:
<script type="text/javascript" src="/to/your/file.js">
And then run your function when the DOM has been loaded:
document.addEventListener("DOMContentLoaded", function(event) {
// Your code to run since DOM is loaded and ready
});
If you can't change the HTML, then include your files dynamically and make sure to call your functions when the files are loaded.

Related

Load external file then run function from file

I'm trying to load another JS file from JS (because the url can change depending on what the user selected and load both would cause conflict issues) and then right after loading the file run a function from the file. I need to run a function and I can't just run code because the function requires client inputs. How can I do this?
In this example, I haven't included the dynamic URL part because that works. Also, no 2 attempts were tried at once. I tested them all separately. None of them worked. This is what I've tried:
var url="file.js", script = document.createElement('script');
script.setAttribute('src',url);
script.setAttribute('id','option');
document.head.appendChild(script);
// code attempt 1 at loading the function:
fileInit(param1);
// code attempt 2:
document.getElementById("option").onload = fileInit(param1);
// code attempt 3:
script = document.getElementById("option");
script.onload = script.onreadystatechange = fileInit(param1);
// code attempt 4:
document.getElementById("option").addEventListener("load", fileInit(param1));
I just want to load the file is JS (so I can have a dynamic url) and then when the file is loaded run the init function defined in the file. I also don't want to use jQuery. I want the code to be vanilla JS. I know you can use jQuery.getScript().
In both files you should have this statement exports.__esModule = true; and in the export file you do this for each thing you want to export exports.thingToExport = thingToExport; then you import like so:
var file = require("path/to/file");
file.thingToExport;
Edit: This question explains what you do in typescript to get this node code.This also works in modern browsers import functions from another js file and is probably a duplicated.

Injected Javascript seems to run asynchronously

I'm making a bookmarklet version of a Greasemonkey extension that appends two <script> tags to the page body: the first one is a largish library, the second calls a function from that library.
Generally, it takes two or more attempts (never one, sometimes more than two) to get the script to properly fire. Running the function directly from the console after injecting the library also works. If I check my error logs, I get the message that my injected method doesn't exist yet - hence the title: despite the fact that JavaScript ought to be single threaded, somehow the second method tag is being run first, before the library is done loading.
The bookmarklet code, before minifying, looks like this:
document.body.appendChild(document.createElement('script')).src = "https://my-site-address";
var scrN = document.createElement('script');
var txtN = document.createTextNode("main.Main().main(document.location.href)");
scrN.appendChild(txtN);
document.body.appendChild(scrN);
and the generated html is simply
<script src="https://my-site-address"></script>
<script>main.Main().main(document.location.href)</script>
Use the load event of the script element to execute the function in it:
var script = document.createElement("script");
script.onload = function() { main.Main().main(document.location.href); };
script.src = "https://my-site-address";
document.body.appendChild(script);

How to insert a string into a script tag?

I have been using XMLHttpRequest to load my javascript file and insert it into the the head of my html file. I have tried:
var headNode = document.getElementsByTagName('head')[0];
var js = document.createElement("script");
js.type = "text/javascript";
js.src = this.url.replace(project.basePath,'');
headNode.appendChild(js);
This works but i have a timing problem when i do it this way, so no function can be called. I am now trying another way, where i can get the string of codes from the js file and insert it into the head, when i do it this way it clears my html and only adds the new code in.
var code= this.ajaxRequest.responseText;
script.write('<script>'+code+'</script>')
is there away to append it to the head for example (this doesn't work);
var code= this.ajaxRequest.responseText;
var headNode = document.getElementsByTagName('head')[0];
var script = document.createElement("script");
script.write('<script>'+code+'</script>')
headNode.append(script)
Thanks for the help in advance. p.s I am not using jquery.
The first approach you tried failed because XmlHttpRequest (also called an ajax request) is asynchronous.
So by the time your script gets loaded, your other scrip tags code get executed (before the script file is load).
You could fix this issue, by using event handling in javascript.
You can create a custom event called 'loaded' and dispatch it.
And in your other script tag that contains code, add an event listener for the same event.
And in the event handling or the event listener function, call the required functions that you want to execute after the script gets loaded.
Your second approach fails because document.write or document.append over-writes the document if it is used after the html page is rendered.
So using this functions after the page has displayed should be avoided.
P.S - Sorry that I could not give any demo code as I am answering this from my cell phone.
JS parser error on your < /script> in code.
try
var code= this.ajaxRequest.responseText;
script.write('<script>'+code+'</scr'+'ipt>');
Can you just eval() the response text?

External JS file can't be executed

I have a js function that should get some advertisement js code from some server and place it in specified DOM element. It looks like this:
function LoadAd(scriptContainer)
{
var js = document.createElement("script");
js.async = true;
js.src ='someAdUrl';
var sHolder = document.getElementById(scriptContainer);
if (sHolder != null) {
sHolder.appendChild(js);
}
}
the argument 'scriptContainer' is an ID of DOM element, that should contain created js element.
This external js file contains a lot of code that should provide an ad. But this code is never reached and never executed.
When I put this js src directly in html:
<script src='someAdUrl'></script>
it works fine.
I've checked, the js file is being loaded.
Any ideas?
EDIT: Here is an example of content of js file:
document.write('<!-- Some Message -->\n\n\n<img width=\"336\" height=\"110\" border=\"0\" src="someImageSource">\n\n');
And it always contains document.write
If the external JS file is being loaded, have you checked whether or not the function is actually being invoked and run?
If the function isn't self-executing and you don't explicitly call it, the code won't run.
I use this code in my case. It may help you
var js=document.createElement('script');
js.setAttribute('src','http://domain.com/js/jscpt.js');
document.body.appendChild(js);

From a script call a function in .js file

I have this in a test.html:
<script>
function h(){
g();
}
<script>
k.js has:
g();
In test.html I successfully entered h() but not g(). I added k.js as a script tag:
scriptTag.src="k.js"
It is not finding g() just the same.
What am I doing wrong?
You said that k.js has this:
g();
This isn't a valid function to call, it's just trying to call g(); which still isn't defined.
What k.js should have is something like this:
function g() { alert('you called g()'); }
It sounds like you are trying to add the script when the document loads or whenever an event fires. If you try to call a function immediately after the external file that contains it is added to the dom, you will get an error. The external file will not have been downloaded. There is latencey in this process. The computer cycles through the client side script faster than it can dowload the .js file. Ad a set timeout and you should see it working. I could be wrong but that is my thoughs...
Have you ensured that k.js is loaded before calling h()?
Is it successfully finding k.js and the path resolves correctly?
Make sure the function you are calling is higher up in the DOM than the line calling it.
I added k.js as a script tag [ scriptTag.src="k.js" ]
Sounds like you're writing your script tag dynamically? If so, make sure you're injecting it into the DOM then waiting for the browser to load it before you try and access anything from it. Just creating the script node won't do anything until you inject it somewhere.
Does your code look someyhing like this?
var scriptTag = document.createElement('script');
scriptTag.src = 'k.js';
Really, you ought to have this line:
scriptTag.type = 'text/javascript';
And as previously mentioned, the script has to be inserted into the DOM. These two lines should solve the problem:
var head = document.getElementsByTagName('head')[0];
head.appendChild(scriptTag);
resulting in:
var scriptTag = document.createElement('script');
scriptTag.src = 'k.js';
scriptTag.type = 'text/javascript';
var head = document.getElementsByTagName('head')[0];
head.appendChild(scriptTag);
Now why aren't you using this?
<script type="text/javascript" src="k.js" />

Categories