html loaded with jQuery.load() doesn't render p5.js [duplicate] - javascript

This question already has answers here:
jQuery .load() call doesn't execute JavaScript in loaded HTML file
(13 answers)
Closed 6 months ago.
I have a website composed of multiple html pages ('home.html', 'gallery.html' etc), injected to index.html using jquery load().
Each of these pages reads data from csv tables. To do this, each page calls a js script that reads the csv and assigns data from the table to html elements, using p5.js loadTable().
This works fine for each page being the main html, but as soon as I inject them into the index.html, sketch.js doesn't recognize its p5.js syntax anymore (I think that's the issue here): key functions like preload() and draw() don't run unless called, and loadTable() isn't recognised either.
sketch.js is read, I've pinged from it to the console, just the p5 doesn't work as mentioned above.
Below is a slim version of my code. I need to keep the main structure of html pages dynamically loaded into index.html, and I need to read my content from csv's. Any advise on how to solve this?
index.html:
<html>
<head>
<!-- p5.js and dom -->
<script src='./lib/p5.min.js'></script>
<script src='./lib/p5.dom.min.js'></script>
<!-- jQuery min -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<header>header, applies across the website></header>
<div id="activePage"></div>
<script>$("#activePage").load("home.html");</script>
</body>
</html>
home.html:
<div id="tempTarget"></div>
<!-- js to read the csv and assign to #tempTarget -->
<script src='./script/sketch.js' defer></script>
sketch.js:
var data;
var loaded = false;
function preload() {
data = loadTable(
'./assets/copyText.csv', 'csv', 'header',
// Callback:
function(table) {
loaded = true;
});
}
function draw() {
// check if table data is loaded
if (!loaded) {
console.log('Data not yet loaded');
return;
}
// if data is loaded, get cell (0, 0) into #tempTarget
document.getElementById("tempTarget").innerHTML = data.get(0,0);
}

Solved: all code using p5.js - in my case, using loadTable() - needs to be fired from index.html:
<script src='./script/sketch.js' defer></script>
needs to move from home.html to index.html.
I've added defer to avoid firing the script before the DOM is in place.
That's it!

Related

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.

JavaScript (jQuery) sometimes does not work when you link it as a separate file

I found these sample code from here
The code is like this:
<script>
$("#modal2Button").click(function() {
$("#modal1").fadeOut();
setTimeout(function() {
$("#modal2").fadeIn();
}, 400)
});
$("#close-button").click(function() {
setTimeout(function() {
$("#modal1").fadeIn();
$("#modal2").fadeOut();
}, 1000)
});
</script>
When I paste the jQuery as a separate file and link it inside the <head>
<head>
<script src="sample_code.js"></script>
</head>
and for some reason that does not work?
Any help will be much appreciate!
This is simply a matter of making sure you're using the correct path to your JavaScript file:
<head>
<script src="./sample_code.js"></script>
</head>
Notice the ./ before the file name, which indicates the file is on the same level as your HTML file.
Yes, Definitely it will not work because the DOM Elements are yet not loaded, and you are accessing them, so their will be an error undefined id modal2Button same for the next one.
If you run your js file when all DOM Elements are loaded their will be no problem..
You can do that via following:
Move your script tag at the bottom of html or just before the body tags ends
Use async or defer in <script> | script notes | script tag - async and defer
Use onload function in your js

How to simplify my js code without loading the js file twice?

I hava many jsp page using the common function in body's onload and onunload event when using ocx control.So I extract the common function in one js file call common.js and import the js file in the jsp page.But I find the sometimes the jsp page could not execute the function in js file.Finally,I solve the problem in two way but I think there must have the other simple way?How to simplify my js code?
write all the js function in each jsp,it works well
in the each jsp file,includ the common.js,and in the jsp file the script call the function before load the common.js,but I think it have already be loaded two times
//init(),asynclogin_onclick(),logout_onclick() function is in the common.js file
<head>
<script type="text/javascript" src="/js/common.js"></script>
</head>
<body onload="init()" onunload="logout_onclick()">
$(function(){
$.getScript("/js/common.js")
.done(function(script,textStatus ) {
asynclogin_onclick();
});
});
I try to write the code like this,but it could not work.
$(function(){
asynclogin_onclick();
});

Includes taking a long time to load and you can see them loading

I’m including one HTML file in another, as a way to reuse my header and navigation generation logic.
The trouble is that when I browse to pages on my site, I can see the HTML that isn’t included in the include files load first. Only then you can see the menus and banners load afterwards. I’d like everything to appear to load at the same time.
Here's the rendered HTML.
And here’s a code snippet showing you how I generate these pages:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
<script>
$(function(){
$("#includeHeader").load("includes/templates/header.html");
$("#includeNavigation").load("includes/templates/navigation.html");
});
</script>
<div id="includeHeader"></div>
</head>
<body>
<div id="wrapper">
<!-- Navigation -->
<div id="includeNavigation"></div>
I’m currently working with the code to try to move any external libraries / CSS to the bottom of the page vs. in the header. But so far, that hasn’t really changed or improved anything.
You should use one of the templating languages.
If your includes are simple HTML files then you could use Handlebars or Dust - you could just copy your code and that's it, then in Javascript you would need just render these templates - see the documentation.
You could use Jade/Pug instead, but its syntax is different from the HTML, so that's not just question of copy-paste.
You are using $(handler) to load them, which is a form for $.ready(). So it waits for the document to load everything before loading your header.html and navigation.html.
Try
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
</head>
<body>
<div id="includeHeader"></div>
<script>
$("#includeHeader").load("includes/templates/header.html");
$("#includeNavigation").load("includes/templates/navigation.html");
</script>
</body>
Your problem is that the load function does not run until the document.ready event has fired. Which is probably after your page has started rendering. To get everything to appear at the same time you could use the callback from .load to show everything. So everything is hidden,
$( "#result" ).load( "ajax/test.html", function() {
/// show your stuff
});
You will of course need to know both has loaded.
I would recommend not using javascript to render HTML from a static path and would use a server side lang instead for speed.
I think it make some level fast its not waiting for load all dom element, I am considering #includeNavigation element is under #includeHeader element
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
</head>
<body>
<div id="includeHeader"></div>
<script>
$("#includeHeader").load("includes/templates/header.html", function(data){
console.log("header loaded");
$("#includeNavigation").load("includes/templates/navigation.html", function(data){
console.log("navigation loaded");
});
});
</script>
</body>

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