Firefox not executing JavaScript files that were loaded dynamically - javascript

I'm trying to load two scripts that were functionally deferred on account of their type attributes being non-standard i.e. text/javascript/defer. Doing this causes the parser to ignore them so I want to reload them using JavaScript.
My HTML is as below:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>No Title</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript/defer" src="assets/js/test3.js"></script>
<script type="text/javascript/defer" src="assets/js/test4.js"></script>
<script type="text/javascript" src="assets/js/jquery.js"></script>
<script>
$(document).ready(function(){
var defer_js_collection_obj = $("[type='text/javascript/defer']"),
el_head_rq_obj = $('head'),
el_head_obj = el_head_rq_obj[0]
;
if(defer_js_collection_obj.length > 0)
{
//Reload JavaScript
defer_js_collection_obj.each(function() {
var file_src_outer_html_str = this.outerHTML;
var file_src_res_arr = file_src_outer_html_str.match("src *\= *[\"\']{1}(.*?)[\"\']{1}");
var file_src_str = file_src_res_arr[1];
var fileref = document.createElement('script');
fileref.setAttribute("type", "text/javascript");
fileref.setAttribute("src", file_src_str);
document.getElementsByTagName("head")[0].appendChild(fileref);
});
//Unload JavaScript with defer tag
for(var j = defer_js_collection_obj.length-1; j >= 0; j--)
{
defer_js_collection_obj[j].parentNode.removeChild(defer_js_collection_obj[j]);
}
}
});
</script>
</head>
<body>
<div>Load Deferred JavaScript</div>
</body>
</html>
jquery.js is version 1.11.2. test3.js and test4.js reference the javascript files I want to load, and they contain console.log('test3.js is loaded'); and console.log('test4.js is loaded'); respectively.
The issue I'm having is that this script works virtually everywhere else except on Firefox. I'm on a Mac OS X 10.10.5 using Firefox 46.0.1, and I don't see the console.log message when I load the script.
How can I fix this?

It might be a mime type issue. Do you happen to see any message in the console stating "not well-formed"? In any case, this seemed to work for me and I agree that your code did not work in FF when I first tried it.
$(document).ready(function(){
console.log("main");
var $body = $($("body")[0]);
var $scripts = $("[type='text/javascript/defer']");
$scripts.each(function(){
var scriptTag = document.createElement("script");
scriptTag.setAttribute("type", "text/javascript");
scriptTag.setAttribute("src", $(this).attr("src"));
$body.append(scriptTag);
});
});

Try to append your script at the end of body, so instead do:
document.getElementsByTagName("body")[0].appendChild(fileref);

Related

How to run a JS Function in HTML5

How can I run my function "title()" in HTML?
I have created a "main.js" File, in there, there is following Code:
"use strict";
document.addEventListener("DOMContentLoaded", function() {
let newScript = document.createElement("script");
newScript.src = "javascript/head.js";
let heads = document.getElementsByTagName("head")[0];
console.log(heads)
heads.prepend(newScript);
});
in the "main.js" File load an another Script which is called "head.js" and here is the Code of this File:
function title(titleName) {
let title = document.createElement("title");
document.title = titleName;
document.head.appendChild(title);
}
Maybye you need my HTML Code:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="javascript/main.js"></script>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script> title("Framework"); </script>
</head>
<body>
</body>
</html>
in head.js add:
window.addEventListener("load", () => title("my desired title name"));
Not sure why someone downvoted, but to clarify, you can run this code anywhere so long as the head.js file has been loaded, it doesn't have to be directly in head.js.
You can add it into main.js:
let newScript = document.createElement("script");
newScript.addEventListener("load", () => title("my desired title name"));
newScript.src = "javascript/head.js";
// ...
You can also run it directly in the HTML in a <script> tag but you'll have to ensure the script is loaded first.

On changing script attribute value dynamically, reloads html with appending new script replacing previous one

I want to change its script in the head section of the HTML dynamically on clicking the button and want to reload the page with a new script(with its new values) replacing previous one with JavaScript.
/* To change the root api */
function passRoot(data) {
const parsedData = JSON.parse(data);
var newScript = document.createElement("script");
newScript.id = "someID";
newScript.setAttribute("data-root", parsedData["data-root"]);
newScript.setAttribute("api-root", parsedData["api-root"]);
newScript.setAttribute("src", parsedData["src"]);
document.head.appendChild(newScript);
window.location.reload();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<script id="someID" api-root="some-api-value" data-root="some-data-value" src="some-src-value"></script>
</head>
<body>
script change:
<textarea style="font-size: 9px; width: 90%; height: 30%" id="passroot">
{"api-root": "enter new value", "data-root": "enter new value", "src":"some-new-src-value"}</textarea
>
<div>
<button onclick="passRoot(document.querySelector('#passroot').value)">
Submit to change script
</button>
</div>
**************html-starts***********************************<br>
stuff I manage with bundle, here I want to load new bundle after providing new url in the src of script tag
</body>
</html>
Please open view frame source in the code snippet to see the script tag.
Please help!
Why you want to change the script tag. If you want to load your js on some event. Let's say button click. Please go for Dynamic import that will run your script file.
When you reload the page the script will be removed. So you need to use localStorage to keep current script attribute:
let scriptData = localStorage.getItem('script');
if (scriptData)
craeteScript(scriptData);
function craeteScript(data) {
localStorage.setItem('script', data)
const parsedData = JSON.parse(data);
var newScript = document.createElement("script");
newScript.id = "someID";
newScript.setAttribute("data-root", parsedData["data-root"]);
newScript.setAttribute("api-root", parsedData["api-root"]);
newScript.setAttribute("src", parsedData["src"]);
document.body.appendChild(newScript);
}
function passRoot(data) {
craeteScript(data);
window.location.reload();
}

Uncaught ReferenceError: load is not defined

I'm making a site that, depending on the user's time of the day, will show a night, afternoon or morning image.
But as it seems, the JS isn't working due to a Syntax Error on calling the function with "onload=" in the tag <body>. My VS Code Javascript higlighter isn't working on the words window, document nor getElementById.
Which part of my JS could be wrong?
Here's the HTML
<!DOCTYPE html>
<html lang="pt-br">
<head>
<script type="javascript" src="/script.js"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie-edge">
<link rel="stylesheet" href="/style.css">
</head>
<body onload="load()">
<section>
<div id="msg">
Message here
</div>
<div id="foto">
<img id="image" src="img/afternoon.png">
</div>
</section>
<footer>
<p>© Koala</p>
</footer>
</body>
</html>
And here's the JS
function load(){
var msg = window.document.getElementById('msg');
var img = window.document.getElementById('image');
var dt = new.Date();
var hour = dt.getHours();
msg.innerHTML = 'Now it is ${hour} hours.';
if (hour>= 0 && hour < 12) {
img.src = 'img/morning.png';
} else if (hour => 12 && hour < 18) {
img.src = 'img/afternoon.png';
} else {
img.src = 'img/night.png';
}
}
PS: I've tried running it on Mozilla and Chrome. No success.
The error appears to be with this line:
var dt = new.Date();
To instantiate a new Date object, you need to use this syntax:
var dt = new Date();
Once this syntax error is fixed, then the JS file should be loaded properly and then the onload attribute will be able to fire the load function.
Here's a working demo: https://codesandbox.io/s/stack-overflow-onload-8opgp?file=/script.js

Marketing cloud SSJS - javascript passing values between 2 scripts

I have a cloud pages.
On this page , i have
SSJS script , which retrives records from a data extension. From the count column in the data extension , i want to create a array like
dataarray = [10,20,30,40,50]
Then i need to pass this array (dataarray ) to another script where i can use it in d3.
The problem i am facing is how to pass values from a script which run at server to a script which run in client . I have tried hidden html element method which does not work and does not garrentte seq of script execution.
can you please advise how to pass values .
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="https://www.abc.nl/favicon.ico">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
</head>
<body>
<script runat="Server">
Platform.Load("core","1.1.5");
var data_rec;
try
{
var myDE = DataExtension.Init('01_Reporting_Sent_Today');
var filter = {Property:'return',SimpleOperator:'equals',Value:'1'};
var data = myDE.Rows.Retrieve(filter);
data_rec = data.length;
Write("<br/>The len is :" + Stringify(data_rec))
}catch(ex)
{
Write("<br/>The error is :" + Stringify(ex))
}
</script>
<script>
var datachart = [10,20,30,40,50];
var canvas = d3.select("body")
.append("svg")
.attr("width",500)
.attr("height",500)
var bars = canvas.selectAll("rect")
.data(datachart)
.enter()
.append("rect")
.attr("width",function (d) { return d;})
.attr("height",50);
</script>
</body>
</html>
so the dataarray from first script , i need to use in second script
You can use AMPScript to return the value inside the JS script:
Update: fixed incorrect syntax in my example as pointed out by Reidenshi
<script runat="server">
...
var dataString = Stringify(data);
Variable.SetValue("#dataString", dataString);
</script>
<script>
var data = JSON.parse(%%=v(#dataString)=%%);
</script>

Clickstream Tracking in Veeva CRM

I am working with Veeva CRM, trying to use Click Stream Tracking. I have the code which I am using and trying to track the Presentation id, Product Key Message, track an Element Description and Answer.
Can anybody help with the code that I am using.
Thanks
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>CLM_CERT_HCPName</title>
<!-- Bootstrap -->
<link href="css/style.css" rel="stylesheet">
<link href="css/animate.css" rel="stylesheet">
<script src="js/veeva-library-3.0.js"></script>
<script>
function start(){
header_getAccountName();
}
function header_getAccountName(){ com.veeva.clm.getDataForCurrentObject("Account","Name",header_displayAccountName)}
function header_displayAccountName(result){
var AccountNameHTML = document.getElementById("hcpName");
AccountNameHTML.innerHTML += result.Account.Name;com.veeva.clm.getDataForCurrentObject("Presentation","Survey_vod__c",header_getSurveyID);
}
function mySaveObject(){
//This is the start of my JSON object
var myCallClickStream = {Call_vod__c, Key_Message_vod__c};
//i am using my JSON obj name with the field API name of the call clickstream object obj.apiName then set the value. obj.apiName= value;]
// Create the record using the com.veeva.clm.createRecord
com.veeva.clm.createRecord("Call_ClickStream_vod_c", myCallClickStream, printSavedResults)}
function printSavedResults(result){
alert(JSON.stingify(result));
}
</script>
</head>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
I have also some sample code to try out but not sure what I am doing wrong.
function mySaveObject(){
var myCallClickStream = {};
myCallClickStream.Text_Entered_vod__c = "i will put some text here";
com.veeva.clm.createRecord("Call_Clickstream_vod__c", myCallClickStream, printSavedResults)
}
function printSavedResults(result) {
alert(JSON.stringify(result));
}
Not sure if you still need help on this or not. But my team uses a simple method in every project to simplify the tracking process. The below was modified to fit some of your naming conventions/needs.
// clmDescription - string submitted as the description to be tracked
// clmAnswer - string submitted as the answer to be tracked`
// callback - call back function which will be used to return the information
function mySaveObject( clmDescription, clmAnswer, clmCallback ) {
var url = window.location.pathname,
filename = url.substring(url.lastIndexOf('/') + 1),
clmTrackingID = filename.replace(".html", "");
var myCallClickStream = {};
myCallClickStream.Track_Element_Id_vod__c = clmTrackingID;
myCallClickStream.Track_Element_Type_vod__c = clmDescription;
myCallClickStream.Selected_Items_vod__c = clmAnswer;
myCallClickStream.Track_Element_Description_vod__c = clmAnswer;
// var myJSONText = JSON.stringify( myCallClickStream );
com.veeva.clm.createRecord( Call_Clickstream_vod__c, myCallClickStream, clmCallback );
}
Simply call the method and pass in your parameters, including your callback method.
Hope this helps!

Categories

Resources