Including html with script, require not defined - javascript

I'm building electron app that allows extendable modules. I'm getting require not defined when i call it from loaded html script. How can i do this or what approach can i take to deal with this?
I've html loaded into iframe on click. Html has script tag with what module has to do.
mainWindow.html
<iframe id="frame"></iframe>
<script>
var moduleOrange = document.querySelector('.module-orange')
moduleOrange.addEventListener('click', addScript);
function addScript(e) {
var frame = document.getElementById('frame');
frame.setAttribute("src", "orange.html");
}
</script>
orange.html
<script>
require('puppeteer')
</script>
I want included html script to have separate functionality, without need of calling every method from mainWindow.html.

Related

JavaScript addEventListener use external JavaScript file

So I have this page which is setup with a Bootstrap template.
What I would like to do is to use an external JavaScript-file as such: drive:\myfolder\mysubfolder\myexternaljavascriptfile.js. The <script> tag is located just before the </body> tag.
The Bootstrap-javafiles are in the <head> section. Also tried placing it in the <body> section.
So this is what I have now.
<script>
const element = document.getElementById("hitme");
element.addEventListener("click", myfunc);
</script>
also tried using myfunc() to no avail.
I want myfunc to use my external JavaScript file
It works if I use it in the same <script> tag in the HTML doc but that is not what I want.
Also, it does work if I use <button onclick("Myfunc")>Hit Me</button> but I reckon this is the old way using the click-event etc.
Put the js file in the same folder as your index.html file and link it to HTML with script tag <script href="script,js" defer><script> defer attribute load the js file after HTML CSS done loading

Running a js function in html while the script tag has a defer attribute set

I the defer attribute of the script tag in the <head> section of HTML files. This almost always means that I cannot run js functions in the HTML since the js file is only loaded after the HTML file has been loaded..
I have run into a situation where I needed to run a js function in my HTML file, but would not want to remove the defer attribute from the script tag because of other functions in the js file. I looked at the possibility of using async, but it also was not helpful.
Any idea on how this could be done... other than using defer? I would still like to keep the script tag in the head, but going that way would mean that I have no open (non-function based) instructions in the linked js file... which is not always ideal.
Here is a sample of the HTML file
temp.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="temp.js" defer></script>
<title>Defer et al</title>
</head>
<body>
<script>
runThisFunction('Home');
</script>
</body>
</html>
And here is a sample of the js file
temp.js
function runThisFunction(varin) {
console.log(varin);
}
If I remove the defer from the js file, the function will run; if I leave it there, or use async instead, the function will not run because it has not loaded yet.
Any assistance in this small issue will be appreciated.
The best way to do this would be to refactor your script to contain an entry point in a function, and run that function once the DOM loads. Instead of, for example
// temp.js
function runThisFunction(varin) {
console.log(varin);
}
document.querySelector('.foo').textContent = 'doing stuff';
// other code here
put all of the functionality that depends on the page being loaded into its own function:
// temp.js
function runThisFunction(varin) {
console.log(varin);
}
function init() {
document.querySelector('.foo').textContent = 'doing stuff';
// other code here
}
window.addEventListener('DOMContentLoaded', init);
This way, if you also remove the defer attribute, runThisFunction will be available immediately, but the other parts of your code won't run until the page is loaded.

How to make the browser run JavaScript code injected by DOM manipulation?

I want to serve a little HTML snippet that other pages can include.
The HTML content would look something like this:
<div id="coolIncludable" style="display:none"> <!--be invisible until you are finished initializing -->
<div>Cool stuff here</div>
<div>More cool stuff and so on...</div>
</div>
<script src="http://somehwere/jquery.js"></script>
<script src="http://somewhere/something.js"></script>
<script>
$(function(){$('#coolIncludable').show();});//<- actually contained in a script file, just for illustration
</script>
I'm planning to use the method detailed here: https://www.w3schools.com/howto/howto_html_include.asp to do the actual including. Let's say the page looks something like this:
<html>
<head>
</head>
<body>
<H1>Content before snippet</H1>
<div id="registerWrapper" html-include="http://somehwere/snippet.html">
No content loaded
</div>
<H1>Content after snippet</H1>
<script type="text/javascript" src="http://somehwere/html-include.js"></script>
</body>
</html>
The HTML snippet gets loaded and embedded all right, but the JavaScript that comes with it never gets executed. Is there a way to embed content including scripts that makes sure they are executed?
I don't expect to control the embedding page, so I cannot rely on it having jQuery or anything else loaded. I therefore avoided using jQuery in the embedding function and restricted myself to plain JavaScript. Loading jQuery is one of the things the <script> tags at the end of the snippets would do.
Since you are using jQuery you can use it's built in load() method to do what you want
Something like:
HTML
<div class="include" data-include="page2.html"></div>
JS
$('.include').each(function(){
const $el = $(this), url = $el.data('include');
$el.load(url)
});
Then make sure the script tag for the new content is below that content.
Simple working demo
In retrospect, my mistake is glaringly obvious:
What does the line $(function(){$('#coolIncludable').show();});
do? does it execute $('#coolIncludable').show();? No it doesn't. It registers a callback to do so that gets triggered by the 'load' event, which already has fired, and won't fire again.
On the other hand, that's really a moot point because the code never even gets executed.
Here's what I learned about dynamic loading of javascript
Injecting script tags directly does not work
script tags injected by setting element.innerHtml do not get executed
<div id="snippet">
...
</div>
<!-- neither of these will be executed -->
<script type="text/javascript">alert("stuff");</script>
<script type="text/javascript" src="http://somewhere/script.js"></script>
Creating script tags dynamically does work
What does work is dynamic tag generation the way it is described in this article: JavaScript Madness: Dynamic Script Loading
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'helper.js';
head.appendChild(script);
//At this point (or soon after) the code in helper.js will be executed
You would do that in your loading script. My loading script looks something like this:
function importJsFiles(){
const scriptFiles = ["http://somewhere/jquery.js",
"http://somewhere/stuff.js",
"http://somewhere/bootstrapSnippet.js"];
for (let i = 0; i< scriptFiles.length; i++){
importJsFile(scriptFiles[i]);
}
}
function includeSnippet(){
//See https://www.w3schools.com/howto/howto_html_include.asp
//We still have to do it without jQuery,
//because at the time this executes the injected jquery.js
//hasn't run and we do not yet have jQuery available
}
importJsFiles();
//At this point, all script tags are created, but the scripts are NOT loaded yet
includeSnippet();
//At this point, the dom is in its final shape
bootstrapSnippet(); //<- This won't work, because the script tags injected by this code won't be evaluated until after this file/function/whatever returns
//bootstrapSnippet.js
function bootstrapSnippet(){
alert("Snippet JS running")
if (window.jQuery) {
alert("JQuery is avaliable"); //<- This will fire, because the new script
// tags are evaluated in order, and we put the
// jquery.js one before the bootstrapSnippet.js one
}
//So now we CAN do this:
$('#coolIncludable').show();
}
bootstrapSnippet();
There are many more interesting ideas and details in this post that I picked the link above from. I hope someday I'll find time to explore them all.

How to embed content generating <script> in reactjs component

I want to embed a script tag provided by a third party ad service into my react app. It is like a Github gist. It should run the script and write a <iframe> inside the HTML to show the ads.
The official scripts are something like this:
<script type="text/javascript">
var cpro_id = "uXXXXXXXX";
</script>
<script src="http://cpro.baidustatic.com/cpro/ui/c.js"></script>
I tried to put the first script tag in the template HTML, and put the second in the component I need it to be, like this:
...
componentDidMount () {
let g = document.createElement ('script');
g.setAttribute ('src','http://cpro.baidustatic.com/cpro/ui/c.js');
React.findDOMNode (this.refs.ad).appendChild (g);
},
render() {
return <div ref='ad'></div>;
}
...
Unfortunately, it failed and throw this error: It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
I tried ReactScriptLoader and it gave me the same error.
I tried dangerouslysetinnerhtml={{__html: '<script src="http://cpro.baidustatic.com/cpro/ui/c.js"></script>'}}, but failed.
I tried to study the code of c.js file and change all document.write to innerHTML=..., but failed.
Can anyone help? Thanks!

Can an inserted <script> tag be run multiple times without using eval in JavaScript?

I have to use a plugin which bundles js files inside html files (gadgets). For one use case I need to drop and re-instantiate a gadget to run updated code.
So say I have foo.html:
<html>
<head>
<script src="foo.js"></script>
</head>
<body>...</body>
</html>
and foo.js which is the file being injected into my actual document's head:
alert("hello");
Problem is I can only cachebust the html file dynamically and declare my gadget as foo.html?x=123, but the JS file I'm after will still be foo.js so the browser will not re-run it.
Question:
Once a <script> tag is inserted into the document and run, is there any way to run it again without using a module-loader or eval?
Thanks!
You could wrap your code in your <script> tags in a function then call your function. This will allow you to call your code to be called multiple times. Like this:
<script>
function loaded(){
// JavaScript here
}
loaded();
</script>
</body>

Categories