Randomly load different JavaScript between each page load using loadExternalHTMLPage - javascript

I have a site and I want it to randomly load a different HTML5 Javascript animation each time the page is loaded, JavaScript is by far one of the weakest of my skills and I appreciate any help in advance and if this happens to be duplicate (I've tried searching) then please vote for the question to be closed.
Basically the method I have used is a dirty one and most likely the reason its not working, basically I tried randommath and had no luck and put this down to my JS skills being extremely weak, the alternative method which looked easier doesn't work either and this is basically inserting a HTML on page load, so for example a.html and b.html which both contain different scripts.
This is what my code looks like:
HTML
<html>
<head>
<script src="js/insert.js"></script><!-- This inserts the Random Page -->
</head>
<body onload="loadExternalHTMLPage()">
<div id="injectjs"> </div>
<canvas="id"> </canvas>
<script src="js/animation-lib-pageA.js"></script><!--Library for pageA -->
<script src="js/animation-lib-pageB.js"></script><!--Library for pageB -->
</body>
</html>
Inject.js
function loadExternalHTMLPage() {
var xmlhttp;
var pagesToDisplay = ['a.html', 'b.html'];
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("jsinsert").innerHTML = xmlhttp.responseText;
}
}
var randomnumber = Math.floor(Math.random() * pagesToDisplay.length);
xmlhttp.open("GET", pagesToDisplay[randomnumber], true);
xmlhttp.send();
}
Most JS Guru's should be able to see that I'm randomly inserting a.html and b.html on page load, now this works but the problem is the scripts contained within a.html and b.html are not executing. (using firebug I can clearly see that the scripts are being inserted as intended).
so for example a and b looks like:
a.html
<script> window.onload = function () { }</script>
b.html
<script> window.onload = function () { } </script>
Basically the code within A and B are valid and work fine within this insert and I've filled the above examples as just a placeholder. A and B both contain JavaScript that executes animation contained within the canvas but it doesn't work at present and I suspect its something to do with the fact I'm loading the scripts after the page has been loaded. Thanks in advance.

You can randomly load the html for A or B and then run its animation.
This example uses jQuery which makes the task of loading remote html easier. Here is a link to the jquery .load function which replaces an existing elements html with the downloaded html: http://api.jquery.com/load/ If you want pure javascript, you can use that [messier!] alternative, but the logic remains the same.
These are the steps:
Be sure the web page has loaded,
Randomly pick A or B to load/execute,
Replace the html in #injectjs with htmlForA or htmlForB,
Wait until the html has been fully replaced,
Run the appropriate animationA or animationB.
Here is starter code. (Be sure you include the jQuery library)
<script>
window.onload(){
// randomly load html+animation A or B
if(Math.random()<.50){
$('#injectjs').load(
'yourSite.com/HtmlForA.html', // first load the html for A
function(){ animationA(); } // then run animationA
);
}else{
$('#injectjs').load(
'yourSite.com/HtmlForB.html', // first load the html for B
function(){ animationB(); } // then run animationB
);
}
}
</script>

You can always use eval() to execute the content you downloaded ... :) (not recommended).
Or you can modify the html page on server to include the random script you want before serving the page to the user (you don't state platform) since it's anyways changed at page load.

Related

How to stop JavaScript execution when Ajax loads new content?

In the website I am working on, the content is loaded with Ajax, along with any JavaScript included. I am doing this because all the pages are of the same layout, but only the content is the different.
The problem is when a "content" has JavaScript in it, I was afraid the script will continue executing even after new content has been loaded. So I made this test to make sure.
First a main page that will load 2 other pages :
<script src="scripts/jquery.min.js"></script>
<script>
function loadPage1(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
response = xhttp.responseText;
$("#content").remove();
$("#mainContent").append(response);
}
};
xhttp.open("GET", "page1.html", true);
xhttp.send();
}
function loadPage2(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
response = xhttp.responseText;
$("#content").remove();
$("#mainContent").append(response);
}
};
xhttp.open("GET", "page2.html", true);
xhttp.send();
}
</script>
<button onclick="loadPage1()">Load page 1</button>
<button onclick="loadPage2()">Load page 2</button>
<div id="mainContent">
</div>
And then the 2 pages with JavaScript content, basically just spamming the console with "I am page x" every second.
Page 1:
<div id="content">
<h1>Page 1</h1>
<script type="text/javascript">
setInterval(function(){
console.log("I am page 1");
},1000);
</script>
</div>
Page 2:
<div id="content">
<h1>Page 2</h1>
<script type="text/javascript">
setInterval(function(){
console.log("I am page 2");
},1000);
</script>
</div>
The Ajax loads fine, I can see the h1 changing from Page 1 to Page 2. But in the console, I can see that the first script is still spamming even after the content has been removed.
Is there a way to prevent such behavior? Preferably while keeping each script in it's proper place, and not by moving all scripts to the "main page" .
EDIT: To avoid confusion, setInterval() is not the main problem, it's merely an example. I'm asking how do you usually deal with such a problem with Ajax and JavaScript
Even though the 1st <script> block has been replaced, you see the console logs because of the way javascript works.
Your anonymous function
function(){
console.log("I am page 1");
}
will live on and keep executing till you call clearInterval or move away from this page.
This is also the case when you add a click handlers eg $('#some_button').on("click",function(evt){/*do something*/});
Even if you have a variable declared, like <script>var x='data1';</script>
and then you delete the enclosing <script> tag, the variable x will continue to exist.
In both cases, the references to the functions and variables are stored somewhere. References to the setInterval, and click handler function are held by the event handlers. A reference to any var and function you declare is held in the window object (unless you use a closure).
In your newly loaded script, you could re-assign stuff: the behavior of a function will be the last loaded behavior. Any calls made to that function will execute the new instructions because they too have now been assigned to the window object(scope).
In summary,
You will need to clear interval
The functions and vars you declare will exist till you change them
Re:Question in comment
oh, so If I declare a new behavior for a function, it wouldn't give me an error like it would with static programming languages. It 2ould save me a lot of work if I can keep the namings the same. I guess all I need to do is clearInterval, and keep whatever functions as they are.
Right but rather than draw a parallel to other programming languages, try and see these as instructions that are interpreted immediately when you inject the script tag into the DOM. So, what you are doing is actually just re-assigning the properties of the window object. To understand this better, open the developer console on chrome and run these in order:
window.hasOwnProperty("xy")
var xy=1
window.hasOwnProperty("xy")
window.xy
xy="foo"
typeof window.xy
typeof window
This should help you understand how the JavaScript engine is treating your code.
You removed/replaced the content, not the script, you are still on the same page. also you only load new data into that page, so your script is still running in that page unless its stopped explicitly or when the page reloads.

Write a js script in a div

I am trying to get a script from another website using jQuery then document.write it
here is my code
var url = "https://code.jquery.com/jquery-1.10.2.js";
var dam = $.getScript(url);
document.write(dam);
But this doesn't work!!
all what I get on the page is [object Object]
Can this be achieved without XHR?
jsfiddle
Don't use document.write, it does not do what you think it does. What it does not do is write some data at the end of the document. What it does instead, is pipe data into the current write stream. And if there is no write stream, it will make a new one, resetting the document's content. So calling document.write(dam) means you just wiped your document. document.write is a low level JS function from an earlier era of JavaScript, don't use it.
Instead, you want to use modern DOM manipulation functions, so in jQuery, that's stuff like:
$(document.head).append($("<script>").attr("src", url));
where
$("<script>")
builds a new script element,
$(...).attr("src", url)
sets the "src" attribute to what you need it to be, and:
$(document.head).append(...)
or
$(document.body).append(...)
to get the script loaded into your document. If it's a plain script with src attribute, it can basically go anywhere, and if it's a script with text content that should run, you can only make that happen through document.head.
Although if it's just a script you need to load in and run, you can use getScript, but then you don't need to do anything else, it's just:
var url = "https://code.jquery.com/jquery-1.10.2.js";
jQuery.getScript(url);
Done, jQuery will load the script and execute it. Nothing gets returned.
Of course, the code you're showing is loading jQuery, using jQuery, so that's kind of super-odd. If you just want to load jQuery on your page, obviously you just use HTML:
<!doctype html>
<html>
<head>
...
</head>
<body>
...
<script src="http://https://code.jquery.com/jquery-1.10.2.js"></script>
</body>
</html>
with the script load at the end so the script load doesn't block your page. And then finally: why on earth are we loading jQuery version 1.x instead of 2.x? (if you need to support IE8: that's not even supported by Microsoft anymore, so you probably don't need to).
And finally, if we don't want to load the script, but we really just want its content, as plain text, there's only a million answers on Stackoverflow already that tell you how to do that. With jQuery, that's:
$.get("http://https://code.jquery.com/jquery-1.10.2.js", function(data) {
$(document.body).append($("div").text(data));
});
But you knew that already because that's been asked countless times on Stackoverflow and you remembered to search the site as per the how to ask instructions before asking your question, right?
executing the script on the page is not my goal!. I want to get the
script content and put it a div (USING JAVASCRIPT - NO XHR) , is that
possible ?
Try utilizing an <iframe> element
<div>
<iframe width="500" height="250" src="https://code.jquery.com/jquery-1.10.2.js">
</iframe>
</div>
jsfiddle http://jsfiddle.net/snygv469/3/
Make it easier... use my fiddle
http://jsfiddle.net/wwwfzya7/1/
I used javascript to create an HTML element
var url = "https://code.jquery.com/jquery-1.10.2.js";
var script = document.createElement("SCRIPT"); //creates: <script></script>
script.src = url; //creates: <script src="long_jquery_url.js"></script>
document.body.appendChild(script); //adds the javascript-object/html-element to the page.!!!
Use this way, it can fix your problems.
$.get( "https://code.jquery.com/jquery-1.10.2.js", function( data ) {
alert(data);
});
You can try adding
<script src="http://code.jquery.com/jquery-1.8.3.min.js" ></script>
Then an AJAX call, but it pulls data from CACHE. It looks like an AJAX but when <script> is added file goes in cache, then read from cache in the ajax. In cases where it is not stored in cache read it using normal AJAX.
jQuery.cachedScript = function(url, options) {
// Allow user to set any option except for dataType, cache, and url
options = $.extend(options || {}, {
dataType: "text",
cache: true,
url: url
});
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return jQuery.ajax(options);
};
$(document).on('ready', function() {
// Usage
$.cachedScript("http://code.jquery.com/jquery-1.8.3.min.js").done(function(script, textStatus) {
console.log(script);
});
});
Normal Solution
If you are ready to use AJAX look at this fiddle
How to fetch content of remote file and paste it on your document and execute that js code
I guess you want to get content written on remote file and want to write that content in your HTML. to do this you can use load() function.
To do this follow the following steps:
1. Create a file index.html Write the following code in it:
<pre id="remote_script"></pre>
<script>
$(document).ready(function() {
//var url = "https://code.jquery.com/jquery-1.10.2.js";
var url = "remote_script.html";/* For testing*/
$('#remote_script').load(url,function(){
eval($('#remote_script').text()); /* to execute the code pasted in #remote_script*/
});
});
</script>
2. Create another file remote_script.html for testing write alert('a'); in it without any <script> tag and run the above code.

JavaScript not executing on Ajax loaded content (no jQuery)

I am having an issue where I am loading ajax HTML content into an element on my page using JavaScript, and trying to execute JavaScript within the loaded content, which is not working.
I am not (and cannot) use jQuery on this project.
The JavaScript I am using to load the ajax content look like:
var loadedobjects = "";
var rootDomain = "http://" + window.location.hostname;
function ajaxPage(url, containerId){
var pageRequest = false;
pageRequest = new XMLHttpRequest();
pageRequest.onreadystatechange = function(){
loadpage(pageRequest, containerId);
}
preventCache = (url.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime();
pageRequest.open('GET', url+preventCache, true);
pageRequest.send(null);
}
function loadpage(pageRequest, containerId){
if (pageRequest.readyState == 4 && (pageRequest.status==200 || window.location.href.indexOf("http") == -1)){
document.getElementById(containerId).innerHTML = pageRequest.responseText;
}
}
As you can see, I am passing a URL (of an HTML page) to the function ajaxPage()
The ajaxPage() function is being called in a separate .js file, like so:
ajaxPage('test.html', 'ajax-wrapper');
Which is working, test.html is being loaded in the element with id 'ajax-wrapper', but no JavaScript in the test.html page is working.
Here is what the test.html page looks like (just plain HTML):
<div class="t-page-title">
View Thread
</div>
<script>
alert('hello');
</script>
Even a simple alert('hello'); on the loaded HTML is not firing. The page is not being cached, so that is not the issue. I would know what to do if I was using jQuery, but I am a bit stumped with finding a JavaScript only solution. Any suggestions?
When you use innerHTML, the tags get copied to the destination element, but scripts are not executed. You need an additional eval step to execute the scripts.
jQuery has a function for that called globalEval, without jQuery you'll need to write your own.
[Update] Here is a variation with an iframe that might help address your issue: http://jsfiddle.net/JCpgY/
In your case:
ifr.src="javascript:'"+pageRequest.responseText+"'";
The standard behavior with a div: http://jsfiddle.net/JCpgY/1/

How can I embed an existing multi-level drop down menu without inserting the whole code?

I have a multi-level drop down menu (done using HTML + CSS) that I want to put on a number of different pages. In the future I will need to update this menu and change its contents, so I have saved the HTML in its own file so that I can roll out the changes to all the pages at once (instead of having to go through each page and repeatedly paste in the changed list items).
I have tried using iframe, but this cuts off the menu items with its limited height (setting a manual height that's big enough would leave tons of blank space, of course):
<iframe height="100%" src="menu.html" frameborder="no" width="100%" scrolling="no"></iframe>
I also tried using embed (this looks fine until you mouse over the menu items -- it just scrolls within the frame):
<embed type="text/html" src="menu.html" width="100%" height="100%"></embed>
The menu functions fine when the code is simply dumped into the individual pages I need it on, so I know that's not the issue. It's the embedding and calling it from its own HTML file that is the problem. Is there a simple way to do this that will allow the drop-down menu to appear as it should?
I should mention that while I have my IT department's blessing to do this, this is a project that they aren't supporting. I can only edit the HTML of my webpages in the body, and not the head. The exception being HTML pages I upload as files (like the menu code). So there are some constraints.
Well here is a bit of a long winded javascript approach that might keep your IT guys happy:
window.onload = new Function("load('embed-me.html','content')"); // Replace with URL of your file and ID of div you want to load into.
function ahah(url, target) {
document.getElementById(target).innerHTML = ' Fetching data...';
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
if (req != undefined) {
req.onreadystatechange = function() {ahahDone(url, target);};
req.open("GET", url, true);
req.send("");
}
}
function ahahDone(url, target) {
if (req.readyState == 4) { // only if req is "loaded"
if (req.status == 200) { // only if "OK"
document.getElementById(target).innerHTML = req.responseText;
} else {
document.getElementById(target).innerHTML=" AHAH Error:\n"+ req.status + "\n" +req.statusText;
}
}
}
function load(name, div) {
ahah(name,div);
return false;
}
Not written by me(LINK) (I just added the run on page load bit).
Tested and working (in Chrome at least). Though your site will have no menu if the user has javascript disabled!
EDIT:
Example...
<body>
<script type="text/javascript" src="embed-me.js"></script> <!-- load the javascript -->
<div id="content"></div> <!-- html will be embedded here -->
</body>
I use the following php code and works very nice. It doesn't even show when you check the source code online.
<?php include("menu.php"); ?>
Use php Include !!
Okay first.. copy the menu code and save it on to a file called menu-1.php
then whenever you want to use your menu; just type the following code:
<?php include("menu-1.php"); ?>
This is a good way to do menu's because every time you need to update your menu, you wont have to update every single page, just update your menu-1.php
P.S. PHP might not show up on your local machine unless you are using wamp or xamp

What are the ways to minimize page wait from external javascript callouts?

What tricks can be used to stop javascript callouts to various online services from slowing down page loading?
The obvious solution is to do all the javascript calls at the bottom of the page, but some calls need to happen at the top and in the middle. Another idea that comes to mind is using iframes.
Have you ever had to untangle a site full of externally loading javascript that is so slow that it does not release apache and causes outages on high load? Any tips and tricks?
window onload is a good concept, but the better option is to use jQuery and put your code in a 'document ready' block. This has the same effect, but you don't have to worry about the onload function already having a subscriber.
http://docs.jquery.com/Core/jQuery#callback
$(function(){
// Document is ready
});
OR:
jQuery(function($) {
// Your code using failsafe $ alias here...
});
edit:
Use this pattern to call all your external services. Refactor your external script files to put their ajax calls to external services inside one of these document ready blocks instead of executing inline. Then the only load time will be the time it takes to actually download the script files.
edit2:
You can load scripts after the page has loaded or at any other dom event on the page using built in capability for jQuery.
http://docs.jquery.com/Ajax/jQuery.getScript
jQuery(function($) {
$.getScript("http://www.yourdomain.com/scripts/somescript1.js");
$.getScript("http://www.yourdomain.com/scripts/somescript2.js");
});
Not easy solution. In some cases it is possible to merge the external files into a single unit and compress it in order to minimize HTTP requests and data transfer. But with this approach you need to serve the new javascript file from your host, and that's not always possible.
I can't see iframes solving the problem... Could you please elaborate ?
See articles Serving JavaScript Fast and Faster AJAX Web Services through multiple subdomain calls for a few suggestions.
If you're using a third-party JavaScript framework/toolkit/library, it probably provides a function/method that allows you to execute code once the DOM has fully loaded. The Dojo Toolkit, for example, provides dojo.addOnLoad. Similarly, jQuery provides Events/ready (or its shorthand form, accessible by passing a function directly to the jQuery object).
If you're sticking with plain JavaScript, then the trick is to use the window.onload event handler. While this will ultimately accomplish the same thing, window.onload executes after the page--and everything on it, including images--is completely loaded, whereas the aforementioned libraries detect the first moment the DOM is ready, before images are loaded.
If you need access to the DOM from a script in the head, this would be the preferred alternative to adding scripts to the end of the document, as well.
For example (using window.onload):
<html>
<head>
<title>Test Page</title>
<script type="text/javascript">
window.onload = function () {
alert(document.getElementsByTagName("body")[0].className);
};
</script>
<style type="text/css">
.testClass { color: green; background-color: red; }
</style>
</head>
<body class="testClass">
<p>Test Content</p>
</body>
</html>
This would enable you to schedule a certain action to take place once the page has finished loading. To see this effect in action, compare the above script with the following, which blocks the page from loading until you dismiss the modal alert box:
<html>
<head>
<title>Test Page</title>
<script type="text/javascript">
alert("Are you seeing a blank page underneath this alert?");
</script>
<style type="text/css">
.testClass { color: green; background-color: red; }
</style>
</head>
<body class="testClass">
<p>Test Content</p>
</body>
</html>
If you've already defined window.onload, or if you're worried you might redefine it and break third party scripts, use this method to append to--rather than redefine--window.onload. (This is a slightly modified version of Simon Willison's addLoadEvent function.)
if (!window.addOnLoad)
{
window.addOnLoad = function (f) {
var o = window.onload;
window.onload = function () {
if (typeof o == "function") o();
f();
}
};
}
The script from the first example, modified to make use of this method:
window.addOnLoad(function () {
alert(document.getElementsByTagName("body")[0].className);
});
Modified to make use of Dojo:
dojo.addOnLoad(function () {
alert(document.getElementsByTagName("body")[0].className);
});
Modified to make use of jQuery:
$(function () {
alert(document.getElementsByTagName("body")[0].className);
});
So, now that you can execute code on page load, you're probably going to want to dynamically load external scripts. Just like the above section, most major frameworks/toolkits/libraries provide a method of doing this.
Or, you can roll your own:
if (!window.addScript)
{
window.addScript = function (src, callback) {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = src;
script.type = "text/javascript";
head.appendChild(script);
if (typeof callback == "function") callback();
};
}
window.addOnLoad(function () {
window.addScript("example.js");
});
With Dojo (dojo.io.script.attach):
dojo.addOnLoad(function () {
dojo.require("dojo.io.script");
dojo.io.script.attach("exampleJsId", "example.js");
});
With jQuery (jQuery.getScript):
$(function () {
$.getScript("example.js");
});
If you don't need a particular script ad load time, you can load it later by adding another script element to your page at run time.

Categories

Resources