js hook on html load process in browser - javascript

Imagine I have following html with many items:
<html><body>
<img src=http://host.com/pic1.jpg>
<img src=http://host.com/pic1.jpg>
<img src=http://host.com/pic1.jpg>
</html></body>
Site owner adds some script to the page without other modifications:
<script>
var some_super_function = ... // what can i put here?
some_super_function('host.com','ghost.com');
</script>
and during loading of this html, host.com is replaced with hgost.com, so images are loaded from another server, as if the urls were:
<html><body>
<img src=http://ghost.com/pic1.jpg>
<img src=http://ghost.com/pic1.jpg>
<img src=http://ghost.com/pic1.jpg>
</html></body>
I guess selecting $('img') and tuning .attr() is not a good idea, because this may work only after page has loaded and I don't want the browser to reference host.com at all.
I guess angularJS is doing something like that, isn't it?
Is this possible?
Thanks.

Tested in firefox:
<body>
<script>
document.write('<!--');
var body = null;
setTimeout(function() {
body = document.body.innerHTML
console.log(body)
}, 0)
</script>
Now you can extract page contents from body variable, do with them whatever you wish and then put into page (with jQuery('body').html(...) for example).
I don't know if it would work if there were comments in the page. There are other ways to stop page from loading. Something like document.write('<script>');. I also tried document.write('<style>'); in firefox, also works.

You can use angular ng-src and {{}} syntax to bind your img domain:
var superFn = function(){ $('img').attr('src','ghost'); }
superFn();
angular.module('myApp',[]).controller('myCtrl',myCtrl);
function myCtrl($scope){
$scope.domain = "a3.mzstatic.com";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<img ng-src="http://{{domain}}/us/r30/Purple69/v4/d5/9e/6d/d59e6dfa-2176-7bc1-20a8-d3a1316c7bb8/icon100x100.png" >
<img ng-src="http://{{domain}}/us/r30/Purple69/v4/d5/9e/6d/d59e6dfa-2176-7bc1-20a8-d3a1316c7bb8/icon100x100.png" >
<img ng-src="http://{{domain}}/us/r30/Purple69/v4/d5/9e/6d/d59e6dfa-2176-7bc1-20a8-d3a1316c7bb8/icon100x100.png" >
</div>

I guess I know what you need. You need to define a base, and manipulate it to serve your needs. Like:
<script type="text/javascript">
document.write("<base href='http://yourimageurl.com/' />");
</script>
You must use this code before body tag.
How can you set your image urls? This way you have to mirror file names in order to make it work. And only relative url's will work.

Can you use CSS to hide the images initially, wait until the document is ready, then change the images and display them in JS?
CSS
img {
display: hide;
}
JS
$(document).ready( function() {
// ... selecting $('img') and tuning .attr() as mentioned in question
// Show the images
$('img').show();
}

I guess angularJS is doing something like that, isn't it?
No, angular use ng-src but for that you need to change the html
Is this possible?
I don't think it's possible to do reliably, from the client side without changing the html. One issue is when the document is loading, the browser will fetch images as soon as browser hits the image src element, even if you can execute a script before that, since document is not loaded script does not have access to the element.
May be you could kick off a window.setInterval function to check for elements and change sources, still it's not going to be a good approach.

In pure Js
you can do :
<!DOCTYPE html>
<html>
<head>
<script>
some_super_function = function(orig, alt)
{
Array.prototype.forEach.call(document.querySelectorAll("img[src*='"+orig+"']"), function(img)
{
var src = img.src;
var host = src.replace(/^(.*\/\/[^\/?#]*).*$/,"$1");
img.src = "http://"+src.replace(host, alt);
});
}
</script>
</head>
<body>
<img id="ol" src="http://www.intertools.net/lib/media/img/selector.png">
<img id="io" src="http://www.intertools.net/lib/media/img/selector.png">
<script>
// callable anywhere
some_super_function("www.intertools.net", "en.intertools.net");
</script>
</body>
</html>
To avoid caching, you can even use (assuming you are using html5)
<html manifest="manifest.appcache">

If I not mistaken is it your requirement.
var some_super_function = function(old_host,new_host)
{
$('img').each( function() {
var newSrc;
newSrc = $(this).attr('src').replace(old_host, new_host);
$(this).attr('src',newSrc);
console.log($(this).attr('src'));
});
}
some_super_function('host.com','ghost.com');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<img src="http://host.com/pic1.jpg" alt="pic1"/><br/>
<img src="http://host.com/pic2.jpg" alt="pic2"/><br/>
<img src="http://host.com/pic3.jpg" alt="pic3"/><br/>
JsFiddle Demo

Related

jQuery : why is document.ready function not working properly

I am trying to learn jQuery and I am confused how document.ready() function works
$(document).ready(function(){}
In html,
<script type="text/javascript" src="jquery.js"></script>
<script src="script.js" type="text/javascript"></script>
links are at the very bottom of the document, just before the closing body tag. In my javaScript file, I have all my code inside the .ready function. Yet, when I load the page, and I hover over a link, my cursor doesn't turn into a pointer for a couple of seconds, and if I immediately scroll down, the text is not yet loaded for a couple of seconds, either.
My javaScript file has a bunch of iframes etc... so I can understand why the delay, but what confuses me is that I thought the whole point of the .ready function was that the javaScript wasn't loaded until everything else in the page was loaded first? So surely my text and my css should be working straight away? Here is my code if it helps. I can post css too if required.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>myPage</title>
<link rel="stylesheet" type="text/css" href="styles2.css">
</head>
<body>
<div id="container">
<div id="backgroundLeft"><img id='backgroundLeftImage' src="Left.jpg" width="100%"></div>
<div id="wrap">
<p id="text">...some text... <span id="firstLink" class="link">click me</span>.<span><iframe id="frame" class="rect" scrolling="no" marginwidth=0 marginheight=0></iframe>
</span> ...some more text.... <span id="secondLink" class="link">click me</span>,
</span><span>
<iframe id="frame2" class="rect" scrolling="no" marginwidth=0 marginheight=0></iframe>
</span>
... some more text... <span id="thirdLink" class="link">click me</span> </span><span>
<iframe id="frame3" class="rect" scrolling="no" marginwidth=0 marginheight=0></iframe>
</span> ... some more text...
ETC...
</p>
</div>
<div id="backgroundRight"><img id='backgroundRightImage' src="2VillesRight.jpg" width="100%"></div>
<script type="text/javascript" src="jquery.js"></script>
<script src="script2.js" type="text/javascript"></script>
</body>
</html>
js
$(document).ready(function(){
var frame = $("#frame");
frame.attr("src","iframe.html");
var frame2 = $("#frame2");
frame2.attr("src","iframe2.html");
var frame3 = $("#frame3");
etc...
var player;
frame.bind("load", function () {
player = $(this).contents().find("#firstVid");
player.on('ended', function () {
frame.removeClass("open");
});
});
$("#firsLink").click(function(){
if (frame.hasClass("open"))
{
frame.removeClass("open");
player[0].pause();
}
else {
frame.addClass("open");
player[0].play();
}
});
var player2;
frame2.bind("load", function () {
player2 = $(this).contents().find("#sylvainVid");
player2.on('ended', function () {
frame2.removeClass("open");
});
});
$("#secondLink").click(function(){
if (frame2.hasClass("open"))
{
frame2.removeClass("open");
player2[0].pause();
}
else {
frame2.addClass("open");
player2[0].play();
}
});
var player3;
frame3.bind("load", function () {
player3 = $(this).contents().find("#etienneVid");
player3.on('ended', function () {
frame3.removeClass("open");
});
});
$("#thirdLink").click(function(){
if (frame3.hasClass("open"))
{
frame3.removeClass("open");
player3[0].pause();
}
else {
frame3.addClass("open");
player3[0].play();
}
});
etc...
});
I do know my code is repetitive, I am teaching myself so focused on getting it to work for now. Why is my main page taking so long to load if all my code is inside the "document.ready"? Thanks for your time
you can instead bind your javascript to the window.load event like this
Edit: tis is not good practice and unsupported in newer versions of jQuery
$(window).load(function(){ ... });
Correct way to do this
$(window).on("load", function(){ ... });
document ready lets you access the complete markup, even if the images and iframes have not loaded yet, this is desired in most cases.
In your case however, you might want to take the time penalty of waiting for everything to load, this is that the window.load event does.
$(document).ready() will only wait for all of the page's elements to load. It will NOT wait for the iFrames to load their content.
You can refer to this post if you have more questions:
$(document).ready and iframe content
Are you sure JQuery is loading properly? The source (src) property needs to point to the correct path. I find using the developer's tools to review errors, manipulate CSS and check DOM state to be helpful when learning. I prefer Chrome.
Happened to me too. What I found that, the solution is to include the file at the bottom outside of html tag (i.e the file in which you are using $(document).ready() ).
I assume that, this is because the html document is not ready by the time when browser compiler reached at this function.

Why doesn't my javascript return a url?

In my script i'm trying to get my Javascript script to return a URL, so I can use the URL as a background for the website.
Here is my code:
//background script
//backgrounds
Rblxscreenshot_zombietower = "http://saberman888etai.net/background_images/rblxscreenshot.png";
Rblxscreenshot_zombietower2 = "http://saberman888.netai.net/background_images/zombietower2.png";
Rblxscreenshot_deathrun = "http://saberman888.netai.net/background_images/deathrun_ice.png";
Rblxscreenshot_deathrun2 = "http://saberman888.netai.net/background_images/deathrun_lobby.png";
SCREENSHOTS = [
Rblxscreenshot_zombietower,
Rblxscreenshot_zombietower2,
Rblxscreenshot_deathrun2,
Rblxscreenshot_deathrun
];
function returnBackground(){
return SCREENSHOTS[Math.floor((Math.random() * SCREENSHOTS.length)+1)];
}
And here is my HTML code:
<!DOCTYPE html>
<head>
<title>Saberman888's Website</title>
<link rel="stylesheet" type="text/css" href="theme.css"/>
<script type="text/javascript" src="background.js"/>
</head>
<body style="background-image:url(<script src="http://saberman888.netai.com/background.js">returnBackground()</script>);">
<div class="box">
<div style="text-align:center;">
<h1>Home</h1>
Home
Conlangs
Projects
</div>
<hr>
<div id="minibox" style="margin-left:100px;">
<h2>Conlangs</h3>
<ul>
<li>Florrum</li>
<li>Genie</li>
</ul>
</div>
<div id="minibox" style="margin-left:100px;">
<h2>Projects</h2>
<ul>
<li>DLBOX</li>
<li>QuarryLang</li>
</ul>
</div>
<div id="links">
My Youtube
My DeviantArt
My Twitter
<a href="8.42.96.39/User.aspx?ID=49027085
">My Roblox</a>
My Github
</div>
</div>
</body>
</html>
As you can see, in the HTML code it uses the function returnBackground() to get a URL to use as a background, but the background doesn't show up, any reason why?
If you try to mod with the length of the array, it will be always inside the range. This issue looks like an out of range error in the line below:
function returnBackground(){
return SCREENSHOTS[Math.floor((Math.random() * SCREENSHOTS.length)+1)];
}
So replace it with:
function returnBackground(){
return SCREENSHOTS[Math.floor((Math.random() * SCREENSHOTS.length)+1) % SCREENSHOTS.length];
}
Update
Just saw a basic mistake, you cannot use a <script> tag or any other tag for that instance, inside an attribute. That's a syntax error:
<body style="background-image:url(<script src="http://saberman888.netai.com/background.js">returnBackground()</script>);">
You cannot set the background URL like that. Instead you need to this way:
<body onload="returnBackground();">
And in the returnBackground() should set the background in this way:
document.body.style.backgroundImage = url;
Your full returnBackground() function:
function returnBackground(){
document.body.style.backgroundImage = SCREENSHOTS[Math.floor((Math.random() * SCREENSHOTS.length)) % SCREENSHOTS.length];
}
The way you're trying to include the script is incorrect.
As per the HTML5 specification, a script tag has to contain either a src attribute or script content inside the tags, not both. (The only allowed content for a script tag with src specified is documentation, i.e. comments.)
Quote on the script element:
If there is a src attribute, the element must be either empty or contain only script documentation that also matches script content restrictions.
(This wasn't correct before HTML5 either, but (I think) it was more ill-defined, so it might work in some browsers, but don't rely on this.)
Also, the script tag cannot be inlined within a style (or any other) attribute.
For example, one of your better options is modifying the script to retrieve the body DOM element and manipulates its style, its background-image specifically (taking a more imperative approach). Then just include this script inside a script tag into your HTML.
Praveen Kumar's suggestion of adding an onload event handler is probably even easier, but the script include has to be fixed regardless of which path you choose.

How to replace Current script tag with HTML contents generated by the same script

I want to replace the current script tag with the HTML contents generated by the same script.
That is, my Page is
<html>
<body>
<div>
<script src="myfile1.js"></script>
</div>
<div>
<script src="myfile1.js"></script>
</div>
</body>
</html>
Inside each .js file corresponding html contents are generated. I want to put the contents as the innerHTML of the parent div. But can't set id for the parent div because the page is not static. So the current script tag must be replaced with the HTML content. How can I do this?
For each script tag src is the same. So can't identify with src. These scripts displays
some images with text randomly. Scripts are the same but displays different contents in divs on loading
Please help me
try inside of myfile1.js:
var scripts = document.getElementsByTagName( "script" );
for ( var i = 0; i < scripts.length; ++ i )
{
if ( scripts[i].src == "myfile1.js" )
{
scripts[i].parentNode.innerHTML = "new content";
}
}
This is a great question for those trying to implement a JSONP widget. The objective is to give the user the shortest possible amount of code.
The user prefers:
<script type="text/javscript" src="widget.js"></script>
Over:
<script type="text/javscript" src="widget.js"></script>
<div id="widget"></div>
Here's an example of how to achieve the first snippet:
TOP OF DOCUMENT<br />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
// inside of widget.js
document.write('<div id="widget"></div>');
$(document).ready(function() {
$.getJSON('http://test.com?remote_call=1', function(data) {
$('#widget').html(data);
});
});
<br />BOTTOM OF DOCUMENT
Have a look at: http://alexmarandon.com/articles/web_widget_jquery/ for the correct way to include a library inside of a script.
document.currentScript has been available since 2011 on Firefox and 2013 on Chrome.
document.currentScript documentation at MDN
<!DOCTYPE html>
<meta charset="UTF-8">
<title>currentScript test</title>
<h1>Test Begin</h1>
<script>
document.currentScript.outerHTML = "blah blah";
</script>
<h1>Test End</h1>
Unfortunately a running JavaScript file is not aware of where it is running. If you use document.write() in the script, the write function will take place wherever the script runs, which would be one way to accomplish what you want, but without replacing the contents or being able to perform any actions on the enclosing DIV.
I can't really envisage a situation where you'd have such stringent restrictions on building a page - surely if the page is dynamic you could generate identifiers for your DIV elements, or load content in a more traditional manner?
Why not use Smarty?
http://www.smarty.net/
You can use javascript in Smarty templates, or just use built-in functions.
Just take a look at http://www.smarty.net/crash_course
poof -- old answer gone.
Based on your last edit, here's what you want to do:
<html>
<head>
<!-- I recommend getting this from Google Ajax Libraries
You don't need this, but it makes my answer way shorter -->
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
function getRandomContent(){
// I expect this is the contents of your current script file.
// just package it into a function.
var rnd = Math.random();
return "[SomeHtml]";
}
$('.random').each(idx, el){
$(this).html(getRandomHtmlContent());
});
});
</script>
</head>
<body>
<div class="random">
</div>
<div class="random">
</div>
</body>
</html>
If you don't mind the script tag remaining in place you can use something as simple as document.write().
myfile1.js:
document.write("<p>some html generated inline by script</p>");
It will do exactly what you need.

Progress image while page is loaded

Before I continue:
I am aware this has been done before.
I searched SO for this before deciding to post this...
Said that, I noticed that in some browsers that have settings to clear cache on every visit to a page, certain parts of my page show with delay. I would like to have a function that will display some animated image until the page is finished loading 100%.
I would like to place it in my header include file once and have it kick in every time a page loads. I think I need it to be implemented in AJAX. I would like this function to be a stand-alone, i.e. not tied to any other functions. Shall I use jQuery? Since jQuery itself requires loading an external file, should I implement it as a simple JS function?
Any feedback would be highly appreciated. Examples would be priceless.
:)
EDIT:
I found a plug-in that does exactly what I need.
With jquery you can do something like this
html
<div id="loader"></div>
$(window).load(function () {
$("#loader").fadeOut();
});
You can incldue a div with a loader (have it fixed, or absolute, whatever you like) and then with $(window).load( callback ); you can detect when the whole page has finished loading so you can hide the loader.
Or with pure JS you can do the same,
window.onload = function() {
document.getElementById('loader').style.display='none';
}
You can use the onLoad attribute for . Do something similar to:
<body onLoad='showLoadingDiv()'>
and make the showLoadingDiv function show a full-page white div with a loading sign.
Another (probably preferred) option is to have a
<div style='background:white; width:100%; height:100%'>LOADING</div>
and hide it as soon as the page completely loads, i.e. under jQuery's $(function() { });
This page includes some AJAX progress images to use.
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js"></script>
<script type="text/javascript">
//window.onload will wait for images
window.onload = function() {
//find element with id='progress' and hide it
$('progress').hide();
}
</script>
</head>
<body>
<img id="progress" src="https://forums.embarcadero.com/servlet/JiveServlet/download/2-21014-135909-1751/progress2.gif" style="display:show;">
<h1="">This is a solar eclipse</h1>
<img src="http://www.zam.fme.vutbr.cz/~druck/eclipse/Ecl2008m/Tse2008_1250_mo1/Hr/Tse2008_1250_mo1.png" width="50%" style="display:show;">
<p>Pretty and large enough to have to wait for</p>
</body>
</html>
I hope this helps

JavaScript question

It is possible not to show html page in user browser until some JavaScript(built-in or in separate file) will be loaded and executed(for page DOM manipulation)?
The easiest thing to do is to set the css variable
display: none;
to the whole page.
then when everything is loaded you can set the display to
display: block; // or something else that suits.
If you make sure that piece of CSS is loaded at the very start of your document it will be active before any html is shown.
if you use a javascript library like jQuery you'll have access to the $(document).ready() function, and can implement a switch over like this:
<html>
<head>
<title>test</title>
<style type="text/css">
body > div {
display: none;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
$('body > div').css('display', 'block');
});
</head>
<body>
<div>
This will initially be hidden.
</div>
</body>
</html>
Not in the classical way you'd distribute a page. Browsers will (usually) start to display chunks of the base HTML file as it arrives.
Of course, you could simulate this by generating all the HTML on the fly from some included Javascript file. But that doesn't sound like a good plan as it will degrade horribly for people without JS enabled, or if you have a minor bug in your script. A better option might be to style the body tag to display: none and restyle it from the script to make certain parts visible again.
What is it you're actually trying to achieve? It sounds like there's likely to be a better way to do this...
Place the content of HTML page in a DIV, make its diplay none and on load of body diplay it.
<script type="text/javascript">
function showContent() {
var divBody=document.getElementById('divBody');
divBody.style.display= 'block';
}
</script>
<body onload="showContent()">
<div id="divBody" style="display: none;">
<--HTML of the page-->
</div>
</body>
Examples of what you might want to do:
Facebook's "BigPipe": http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919
This method allows you to load JS first then ASYNC+inject all DOM content.
GMail
Zimbra (open-source web app similar to MS Outlook/Exchange)
My understanding is that you want to run some javascript code before you load the page. In the js file you write your init function and add the eventlistener to the window on "load" event. This will ensure that the init code gets executed first and then you can start displaying the HTML content.
var Yourdomain = {};
YourDomain.initPage = function(){
/* Your init code goes here*/
}
window.addEventListener("load", YourDomain.initPage, false);
All You really need to do is give your element an ID or CLASS and use the dislay: none; property. When your ready to show it just delete it.
CSS:
#div_1 {
display: none;
}
HTML:
<div id="div_1">
<p>This will be the hidden DIV element until you choose to display it.</p>
<p id="js_1"></p>
<script>
var x = "Some Test ";
var y = "Javascript";
document.getElementById("js_1").innerHTML = x + y;
</script>
</div>

Categories