Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to load a JavaScript and CSS file when I click a button. I've tried a lot of methods and a few are working but they only allow immediate execution with predefined functions and I at least don't want to have to predefine the functions. All I want to do is load a new JavaScript and CSS file from my server and execute (at least the JavaScript) it whenever I want.
You can add javascript dynamically but the only the way that worked to me always is:
var path_to_script = "the url";
var response = syncRequest("GET", path_to_script, null);
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.type = "text/javascript";
script.text = response;
head.appendChild(script);
function syncRequest(_method, _url, _data) {
var req = getXmlHttp();
try{
req.open(_method, _url, false);
req.send(_data);
}catch(e){
alert(e.description);
}
return req.responseText;
}
function getXmlHttp() {
var xml_http = null;
if (window.XDomainRequest) { xml_http = new XDomainRequest(); }
else { xml_http = new XMLHttpRequest; }
return xml_http;
}
I am not sure that ajax request will work, it is partially copy paste from my project with many changes, but I think it easy to understand how it should to work.
CSS loading:
var css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", path_to_css);
document.getElementsByTagName("head")[0].appendChild(css);
<link id="custom_stylesheet" rel="stylesheet" type="text/css" href="" />
<script id="custom_script"></script>
<script>
function LoadStyleAndScript()
{
$("#custom_stylesheet").attr("href", "//example.com/mystyle.css");
$("#custom_script").attr("src", "//example.com/myscript.js");
}
</script>
<input type="button" onClick="LoadStyleAndScript();" value="Load it">
Maybe you could have an iframe inside a hidden div and load a javascript file in that based on what the user clicks. The problem will be passing javascript variables. You'll need to predefine them in PHP before you render the page in the iframe.
If you just load a javascript file and add to the current document body I don't think it will work in terms of using global variables (unless, again, you predefine them with PHP).
Related
I have written a script which I have in the head section on my landing pages. What it does is that it loads a facebook pixel which I have stored in another part of my application which I access by calling an endpoint. This because I need to dynamically change the script without interfering with the code on the landing page itself. This code is written in Jquery but now I need jQuery gone from my application so I've tried to rewrite it using only vanilla javascript.
The problem is that it works just fine with the jQuery code, but when I've tried to replace it with vanilla Javascript it does not seem to inject the code in the correct way. The output in the DOM looks exactly the same but it does not fire the pixel somehow.
So my question is. Why is this?
Here is the working example of my jQuery script
<script>
$.get('https://api.mydomain.com/script', function (data) {
$('head').append(data);
});
</script>
Here is my vanilla Javascript version
<script>
var theUrl = 'https://api.mydomain.com/script';
let xhr = new XMLHttpRequest();
xhr.open("GET", theUrl);
xhr.send();
xhr.onload = function() {
document.querySelector("head").insertAdjacentHTML("beforeend", xhr.response);
};
</script>
I think the issue is with insertAdjacentHTML - just a guess, but maybe it only works for HTML (divs, images, etc.) rather than scripts. Hopefully this workaround is an acceptable solution:
(function() {
const
exampleScript = getScriptContent(`
<script>
alert("example script loaded");
<\/script>
`),
s = document.createElement("script"),
t = document.createTextNode(exampleScript);
s.appendChild(t);
document.getElementsByTagName("head")[0].appendChild(s);
function getScriptContent(htmlStr) {
const tempDiv = document.createElement("div");
tempDiv.innerHTML = htmlStr;
return tempDiv.innerText;
}
})();
This is a very common question in here related to AJAX, but I can't seem to find one for my case, because most of them used jQuery, and other reasons. Probably mine isn't efficient/recommended, but either way, here we go.
I have a button [let's say we have a reference to it for the sake of it called btn].
It listens for a clicking event. When the user clicks the button, it makes an AJAX request to a .txt file present in the same directory the main HTML/CSS/JS file is. Let's call it test.txt.
Now, it changes the <html>'s innerHTML(not the head/body, the html), and the innerHTML is the response from the AJAX request.
test.txt holds HTML code. And within that HTML code there's <script src="another-js-file.js">.
This doesn't get executed, this is the problem.
Before you scream at me INNERHTML DOESN'T EXECUTE ANY SCRIPTS I know that. I've seen other answers saying to create a <script> tag within a div that's within yet another div, but it doesn't seem to work with external js files, and the solutions indeed used innerHTML.
Okay, here's a sketch:
btn.onclick = function(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState = XMLHttpRequest.DONE){
document.documentElement.innerHTML = this.responseText;
}
}
xhr.open("GET", "./test.txt");
xhr.send();
}
Where test.txt holds:
<head>
<title>Document</title>
<link rel="stylesheet" href="test.css">
<script src="another-js-file.js"></script>
</head>
<body>
<h1>Hello World!</h1>
</body>
No jQuery.
I found that by creating a script element and setting its source to "another-file.js" like this worked:
var script = document.createElement("script");
script.src = "test.js";
document.body.appendChild(script);
THIS GOES AFTER document.documentElement.innerHTML = this.responseText;
I noticed in your initial XHR request you wrote:
if(xhr.readyState = XMLHttpRequest.DONE)
This should actually be triple === not the single one.
Add this function to your initial JS file where you make the XHR request,
function setInnerHtml(el, html) {
el.innerHTML = html;
// Get all the scripts from the new HTML
const scripts = el.querySelectorAll('script');
// Loop through all the scripts
for (let i = 0; i < scripts.length; i++)
{
// Create a new script
const s = document.createElement('script');
// Go through all the attributes on the script
for (let j = 0; j < scripts[i].attributes.length; j++) {
const a = scripts[i].attributes[j];
// Add each attribute to the new script
s.setAttribute(a.name, a.value);
}
// Incase there is code inside the script tag
// Example: <script>alert</script>
s.innerHTML = scripts[i].innerHTML;
// Append the new script to the head (you could change this to the end of the body as well)
document.head.appendChild(s);
}
}
Then when you go to set the innerHTML of the root document object, use the above function instead.
if(xhr.readyState === XMLHttpRequest.DONE){
setInnerHtml(document.documentElement, this.responseText);
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I create a textarea and then I want, with Javascript or what I need, to fill the textarea with a content of a file, when I clicked a button.
How can I do that, or what do I need?
Is the text already loaded into the page and held in a Javascript variable? If not, as other have suggested then an AJAX call may be required to retrieve this data.
Changing the value of a textarea can be done with some simple javascript as below;
<textarea id="textarea"></textarea>
<input type="button" onclick="changeText()" value="button" />
<script>
function changeText() {
var textarea = document.getElementById('textarea');
textarea.value = "new Value";
}
</script>
If instead we're retrieving a file without jQuery the function can be as below;
function changeText() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'request_page.php');
xhr.send(null);
xhr.onreadystatechange = function () {
var status = 4;
var http_code = 200;
if (xhr.readyState === status) {
if (xhr.status === http_code) {
var textarea = document.getElementById('textarea');
textarea.value = xhr.responseText;
} else {
// do something with an error here
}
}
}
};
Sounds like a job for an ajax call. Javascript can call a page on the server that can open a file, read its contents and return in a json string containing the contents of the file, which the javascript then puts into the textarea
Load text from local .txt file into html textarea using JavaScript
I'm running this function to open a new window.
function htmlNewWindow(id) {
var html = $(id).html();
var newWindow = window.open('');
newWindow.document.body.innerHTML = '<html><head><title>Hi</title> <script src="js/myScript.js"></script> </head>' + html;
}
This successfully creates a new window with the HTML in it. I have a bunch of HTML tags which when clicked run a function called Foo1. I've tried printing the entire function of Foo1 to the new HTML document, and tried putting Foo1 inside myScript.js. I see both Foo1 inside a script tag in the new window, and but neither are loaded since they are just written to the new page as HTML.
Scripts added with .innerHTML aren't executed. You need to create a script node and append it to the window's DOM.
$("#button").click(newWindow);
function newWindow(id) {
var html = $(id).html();
var win = window.open('');
win.document.head.innerHTML = '<title>Hi</title></head>';
win.document.body.innerHTML = '<body>' + html + '</body>';
var script = document.createElement('script');
script.src = 'js/myScript.js';
win.document.head.appendChild(script);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Click me</button>
This doesn't run in Stack Snippet's sandbox, here's a working jsfiddle.
Try this:
var newWindow = window.open('');
newWindow.document.createElement('script');
script.src = 'js/myScript.js';
newWindow.document.head.appendChild(script);
Just in case someone has this to be done in a link. Do the following:
Link
This opens a new window with that URL, it set the focus to that windows, and as soon as the 'load' event is triggered, it executes the code in the function. It only works with a page in the same domain.
Hope this helps ⬆✌.
Cheers 👍
Here's how you create, and then append a script file within a new window:
var fileref = document.createElement('script');
//creates script in current document
fileref.setAttribute("type", "text/javascript")
//set it to JS by "type"
fileref.setAttribute("src", filename)
//set your "src=yourFile_href_Here.js"
//Then create your newWindow as you did above, but slightly updated
//Create your function which will consume the "fileref" argument
function htmlNewWindow(fileref) {
var newWindow = window.open('');
newWindow.document.getElementsByTagName("head")[0].appendChild(fileref);
}; //right now the function is made but you still have to execute it
//Execute your function, and pass it the variable "fileref" that you set above.
htmlNewWindow(fileref);
//Within this edit you will append the head element
//with your newly created script(or any other parameterized argument)
/* Replace your filename to pass any other script */
NOTE - Opening a page residing on a different domain, if not specifically allowed, will reject instances of this due to CORS(https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
It's not a safe practice to be sending your scripts into other people's pages or allowing them in your own if your domain hasn't sent them. Also, depending on your server/technology stack you may need to configure your *-origin settings within your backend stack. See here: (https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Suppose the current page is some1.html, and there is a second page, some2.html. How can I access DOM elements in "some2.html" from some1.html using JavaScript?
The way you could do this is by using AJAX:
$.get(url, function(data) {
var $doc = $(data);
});
You can use that to get the contents from an url, and do something with it.
In response to your edit: You can then access the DOM elements by just doing $doc.find('selector') instead of the usual jQuery $('selector').
You can also make it a bit easier by doing:
$.get(url, function(data) {
var $doc = $(data);
var $d = $doc.find;
});
in which case you can just use the syntax $d('selector').
The way you'd do this without jQuery installed would be:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'document';
xhr.send();
xhr.onload = function(e) {
var doc = e.target.responseXML;
}
and then you can access DOM elements via doc.getElementById('id') just like you'd normally select elements, but using doc instead of document.
Note: for these functions, the $doc, $d and doc variables are only accessible within the callback function (so they're only accessible within the function where they're defined).
You cannot.
Your code shows that the new page is being loaded in the same window.
The JavaScript environment for page1 will disappear before the environment for page2 is created. Since they don't exist at the same time, you can't access the DOM of one from the other.
What you could do is store some data in localstorage or a cookie, and have code you place in page2 look for that data and run JS based on what it says.
You could experiment a bit with Ajaxh, because, as Quentin said, changing window.location.href will load the chaned file. or use an iframe like this:
var frame= document.createElement('iframe');
frame.setAttribute('src', 'some2.html');
frame.setAttribute('name', 'some2');
frame.appendTo(body);
var some2 = document.frames['name'];
//now you can acces to some2 with getElementById,...