I need to add the pages later for my project, but after adding the script tag at the bottom is not executed.
Main
const fetch = (url, call) => {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
call(xhttp);
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
const UpdatePage = page_name => {
fetch(`/app/${page_name}`, (data => {
App.innerHTML = data.responseText;
}))
}
Code of new page
<div>
<%= showId %>
</div>
<script>console.log("Welcome to somewhere")</script>
Page loads sucessfuly but the javascript not be executed. How i can execute the script tag on new page added?
I didn't really understand your question.
From what I did though you want to run the script after the page has loaded.
For that you can use the defer tag
<script src="script.js" defer></script>
Read this MDN article for more info.
You must call the function
fetch();
UpdatePage();
Before doing this, you must call your file js in the ejs file
Related
This question already has answers here:
Executing <script> elements inserted with .innerHTML
(23 answers)
Closed 8 months ago.
I have a JavaScript function that gets data and a function statement from PHP via XMLHttpRequest.How do I call the function that the PHP returned? It doesn't seem to exist. I'm totally lost as to how to make this happen.
Here are test files that better explain it:
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<script>
function main(){
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "/test2.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send('foo=bar');
xhttp.onreadystatechange = function(){
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById('testDiv').innerHTML = xhttp.responseText;
if (typeof injectedJS === "function") {
console.log('yes');
}else{
console.log("no");
}
}
};
};
</script>
</head>
<body onLoad=main()>
<div id="testDiv"></div>
</body>
</html>
test2.php
<?php
echo("<h1>Hello!</h1>");
echo("<script>function injectedJS() {var foo='bar';}</script>");
?>
The "Hello!" text is being displayed but "no" is logged to the console.
Thanks in advance for any help or a steer in the right direction,
John
Adding script tags using innerHTML won't execute those tags
Not even adding them through other methods like using DOMParser works
What you need to do is for each script tag you added, you use document.createElement('script') and duplicate the content, then add it to the DOM
const html = `<h1>Hello!</h1>
<scrpt>function injectedJS() {var foo='bar';}</scrpt>`.replaceAll('scrpt', 'script');
// ignore the replaceAll - seems snippets are careful about script tags - this is just dummying up the received data anyway
function main() {
// this is what you put inside
// if (xhttp.readyState == 4 && xhttp.status == 200) {
const tgt = document.getElementById('testDiv');
// add the html to the target node
tgt.innerHTML = html;
// process any script tags in the target node
tgt.querySelectorAll('script').forEach(scr => {
// create a new script tag
const newscript = document.createElement('script');
// copy the contents to the new script tag
newscript.textContent = scr.textContent;
// add new script directly after the current location
scr.insertAdjacentElement('afterend', newscript);
// remove old script - not strictly required
scr.remove();
});
if (typeof injectedJS === "function") {
console.log('yes');
} else {
console.log("no");
}
}
main();
<div>Test</div>
<div id="testDiv"></div>
By the way, instead of
xhttp.onreadystatechange = function(){
if (xhttp.readyState == 4 && xhttp.status == 200) {
// your code
}
}
do
xhttp.onload = function(){
// your code
}
or better still use fetch for cleaner looking code, but that's just opinion so not important
I have this variable in js :
var video_embed = '<script src="https://stream.laminor.academy/1qwyvs9ystd9/embed"><\/script>';
$('.my_video').after("<div class='col-xs-12' id='video_content'>"
+ video_embed +
"</div>");
but my rendered HTML code is :
<div class="col-xs-12" id="video_content">
<script src="https://stream.laminor.academy/1qwyvs9ystd9/embed"></script>
</div>
embed code not working!
Thanks for help
when you generate script tags after the document is loaded, it won't run.
You need to download the script and execute it :
//Code that will download the script
function loadScript() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
// Making sure there's no error
if (this.readyState == 4 && this.status == 200) {
// Executing the script
eval(this.responseText)
} else if (this.readyState == 4) {
// If the server responded with something else than a 200 OK
console.warn(this.status)
}
};
xhttp.open("GET", "https://stream.laminor.academy/1qwyvs9ystd9/embed", true);
xhttp.send();
}
// Executing the function
loadScript()
Let me know if it isn't working.
My problem is that I have a JavaScript function written in a PHP file and when I call it from AJAX request, I want to run that JavaScript function on the main page too after successful AJAX request. As an example, I have a main.html file where I have written an AJAXX function as below.
main.html
<script type="text/javascript">
/* AJAX Function
----------------------------------------------- */
function ajaxFunction() {
var FD = new FormData();
var ajx = new XMLHttpRequest();
ajx.onreadystatechange = function () {
if (ajx.readyState == 4 && ajx.status == 200) {
document.getElementById("mainContent").innerHTML = ajx.responseText;
hello(); //Uncaught ReferenceError: hello is not defined
}
};
ajx.open("POST", "/example.php", true);
ajx.send(FD);
document.getElementById("mainContent").innerHTML = 'Loading...';
return false;
}
</script>
And my example.php file contains a JavaScript function as
example.php
<?php
echo 'Some contents and functions';
echo '<script type="text/javascript">
function hello() {
alert("Hello");
}
</script>';
echo 'Some contents and functions';
?>
Now when I run index.html file, I get Uncaught ReferenceError: hello is not defined error in console rest I am seeing the function body is written on HTML page while inspecting elements on-page.
As I know that innerHTML does not run scripts. So what's the workaround to this problem. You can view the below-linked answer also that I think is related to my question but tried and not working with my problem.
Researched Questions/Answers:
https://stackoverflow.com/a/3250386/3170029
https://stackoverflow.com/a/47614491/3170029
As I shared and you know that innerHTML does not run scripts. so we have to look around it then I found a solution on StackOverflow and I am sharing here with this problem's answer.
main.html
<script type="text/javascript">
/* AJAX Function
----------------------------------------------- */
function ajaxFunction() {
var FD = new FormData();
var ajx = new XMLHttpRequest();
ajx.onreadystatechange = function () {
if (ajx.readyState == 4 && ajx.status == 200) {
setInnerHTML(document.getElementById("mainContent"), ajx.responseText); // does run <script> tags in HTML
hello();
}
};
ajx.open("POST", "/example.php", true);
ajx.send(FD);
document.getElementById("mainContent").innerHTML = 'Loading...';
return false;
}
//https://stackoverflow.com/a/47614491/3170029
var setInnerHTML = function(elm, html) {
elm.innerHTML = html;
Array.from(elm.querySelectorAll("script")).forEach(oldScript => {
const newScript = document.createElement("script");
Array.from(oldScript.attributes)
.forEach(attr => newScript.setAttribute(attr.name, attr.value));
newScript.appendChild(document.createTextNode(oldScript.innerHTML));
oldScript.parentNode.replaceChild(newScript, oldScript);
});
}
</script>
Its concept is clear. When you get the response data from PHP file then first extract <script ..... </script> tags from it and add them in index.html file hear by using createElement('script') and copy all the script to this then you can easily call your function after response data anywhere.
In other words, You can create an executing script element outside of that initial parse using the DOM method of calling createElement('script'), setting its src/content, and adding it to the document. The alternative is what jQuery's getScript90 does.
I have an index which shows a list of orders, each of which calls a function (named dynamically with PHP when I brought the data from the db), to simplify I've reduced the function that each div contains to just an alert. But also every minute an ajax function executes that searches for new orders and appends them on top, with the exact same code as the ones initially loaded. The jQuery works perfectly in the elements that are loaded initially but doesn't work at all in the elements generated dynamically.
This is the index with one initial order inside, BEFORE newOrders runs for the first time. The alert on that order functions properly
<div id="content">
<div id="pedido_4126" class="pedido">
<h4>Pedido 4126</h4>
<button id="btn4126">Alert</button>
<script>
alert("Pedido 4126");
</script>
</div>
</div>
<script>
function newOrders() {
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "simplereq.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse(this.responseText);
console.log(response);
var element = document.querySelector('#content');
var content = element.innerHTML;
ultimoid = response.ultimoid;
element.innerHTML = response.contenido + content;
}
};
xhttp.send("ultimoid="+encodeURIComponent(ultimoid));
}
setInterval(newOrders, 60000);
</script>
And this is the index when the function has executed once and appended a new order on top with it's corresponding script, dynamically generated and received from the AJAX call:
<div id="content">
<div id="pedido_4255" class="pedido">
<h4>Pedido 4255</h4>
<button id="btn4255">Alert</button>
<script>
alert("Pedido 4255");
</script>
</div>
<div id="pedido_4126" class="pedido">
<h4>Pedido 4126</h4>
<button id="btn4126">Alert</button>
<script>
alert("Pedido 4126");
</script>
</div>
</div>
<script>
function newOrders() {
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "simplereq.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse(this.responseText);
console.log(response);
var element = document.querySelector('#content');
var content = element.innerHTML;
ultimoid = response.ultimoid;
element.innerHTML = response.contenido + content;
}
};
xhttp.send("ultimoid="+encodeURIComponent(ultimoid));
}
setInterval(newOrders, 60000);
</script>
As you can see, the html and script are exactly the same, but the one on the new order brought by the ajax call, doesn't work.
Ok, so doing more research I came upon the best answer for my case, I'll leave it here in case it helps someone:
In the content I generate in the AJAX call, I print the scripts like this, and obviously hide it with css:
<div class="javascript">
$("body").on("click","#btn4255",function(){
alert("Pedido 4255");
});
</div>
And then I execute this function every time the AJAX call is returned
$('.javascript').each(function() {
eval($(this).text());
});
I only evaluate strings I generate myself so in this case I think it's not unsafe to use eval().
I'm relatively new to JS, and I'm currently working on XMLHttpRequests and closures. My main goal is to (1) have all the xhr code on one .js file (2) pull it in to my index.html page via an src tag, and finally (3) call the xhr function on the index.html page.
The trouble comes when I try to do number 3... I'm able to call my function to trigger the xhr on its native .js file, but not in the index.html.
Here's what I've written so far:
var experiment = function(callback){
return function(destination){
var xhr = new XMLHttpRequest();
xhr.onload = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
var text = xhr.responseText;
callback(text);
}
else{
console.log(xhr.statusText);
}
}
}
xhr.open("get", destination, true);
xhr.send(null);
}
}
function closure(url){
return experiment(alert)(url);
}
And then, in my index.html page, pull in something like this:
<script type="text/javascript" src="exp.js">
closure("url.com/json");
</script>
But the XHR never fires. What am I doing wrong?
<script type="text/javascript" src="exp.js"/>
<script>
closure("url.com/json");
</script>