I know
"Onload executes when DOM fully loaded.This means it is executed after
end of your page. This is useful when you want to do some task when
document is fully loaed."
but why these code don't work in chrome(spBodyOnLoadWrapper is a function defined in "init.debug.js" , this function was not called ):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:o="urn:schemas-microsoft-com:office:office" lang="en-us" dir="ltr">
<head>
<script type="text/javascript">
document.write('<script type="text/javascript" src="/_layouts/1033/init.debug.js?rev=Cn3X2qRiBI8U52EFeStGwg%3D%3D"></' + 'script>');
</script>
</head>
<body scroll="no" onload="if (typeof(_spBodyOnLoadWrapper) != 'undefined') _spBodyOnLoadWrapper();" class="v4master">
</body>
These HTML is generated by a Microsoft product named "SharePoint 2010", ugly, and not "best practices" , but i have to make it work in chrome...
document.write() is JavaScript code, so it must be included within a script element.
I see a few mistakes/bad practices in your HTML:
First of all, you must wrap the document.write statement in script tags,
Second, using document.write is not necessary (and should be considered as a bad practice).
You can simply add the script to your page by placing the script tags in head or body:
<script type="text/javascript" src="/_layouts/1033/init.debug.jsrev=Cn3X2qRiBI8U52EFeStGwg%3D%3D"></script>
If you want to specify the script source dynamically, you can create a script element, set its source and add it to your document:
<script type="text/javascript">
var headElement = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.setAttribute('src', '/_layouts/1033/init.debug.jsrev=Cn3X2qRiBI8U52EFeStGwg%3D%3D');
script.setAttribute('type', 'text/javascript');
headElement.appendChild(script);
</script>
Instead of using onload attribute, it's better to add an EventListener for load event with JavaScript:
window.addEventListener('load', function () {
if (typeof(_spBodyOnLoadWrapper) != 'undefined') {
_spBodyOnLoadWrapper();
}
});
Just put the script tags in the head without document.write. Secondly, I suggest you put the code which you want to execute in a separate function as well in your head section but anywho, below example might work as well (see also JS Bin):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:o="urn:schemas-microsoft-com:office:office" lang="en-us" dir="ltr">
<head>
<script type="text/javascript" src="/_layouts/1033/init.debug.js?rev=Cn3X2qRiBI8U52EFeStGwg%3D%3D"></script>
</head>
<body scroll="no" onload="javascript:if (typeof(_spBodyOnLoadWrapper) != 'undefined'){ _spBodyOnLoadWrapper();}" class="v4master">
</body>
I'll suggest to use the following script:
window.onload = function() {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function () {
if(this.readyState == 'complete') {
if (typeof(_spBodyOnLoadWrapper) != 'undefined') {
_spBodyOnLoadWrapper();
}
}
}
script.src = '/_layouts/1033/init.debug.js?rev=Cn3X2qRiBI8U52EFeStGwg%3D%3D';
head.appendChild(script);
}
The usage of document.write is not a good idea. The code above dynamically adds a new script tag into the header of the current page. It detects when this script is loaded and executes your function.
I ran into this problem and tried the solutions suggested here but they didn’t work. Some more searching indicates that this is a bug in Chrome that appears to go back at least to 2009:
http://productforums.google.com/forum/#!topic/chrome/7VIpByhmU3U
The issue is that body.onload (and also window.onload) are firing before the web page has completely loaded, apparently in my case because I’m loading large images whose time-to-load varies with net traffic. The work around is to put your JavaScript into the page after any referenced HTML, but before the end tag:
<script type="text/javascript">
if (typeof(_spBodyOnLoadWrapper) != 'undefined') _spBodyOnLoadWrapper();
</script>
This also had the effect for me of producing a substantially more immediate update of the page content in the other browsers (Firefox, Safari) where the bug doesn’t occur.
check if you have 2 onload events.
Related
My goal is to load javascript in the <head> only if a certain element exists in the <body>.
However, I have a problem: I am loading a Web Component, which is just a <script> hosted elsewhere and is pulled in as:
<script src="https://someurl.com/some-web-component.min.js"></script>
This web component file is huge, so I don't want to pull it in unless it is inserted into body by our Content Management System (CMS).
The constraints I am working under are:
• The <head> is shared between pages, so I need conditional logic
• I have no control over the <body> inserted by the CMS, which will potentially contain the <my-web-component> tag
• I NEED the script to load the web component, so I can't use jQuery's $(document).ready, at least I think I can't - an error will be thrown because the browser won't know the element exists
This plunker partially shows my problem, minus all the web component complexity:
https://plnkr.co/edit/GGif2RNHX1iLAvSk1nUw?utm_source=next&utm_medium=banner&utm_campaign=next&p=preview
Any way around this?
You can use DOMContentLoaded event.
The DOMContentLoaded event is fired when the initial HTML document has
been completely loaded and parsed, without waiting for stylesheets,
images, and subframes to finish loading.
In this case you can look for the Component and add the script with something like the following
document.addEventListener("DOMContentLoaded", function(event) {
if(document.querySelector('Component')){
var script = document.createElement('script');
script.src = 'https://someurl.com/some-web-component.min.js';
document.head.appendChild(script)
}
});
Probably a better approach though would be to add the script in the head with async attribute and later remove it if the component is not found.
Something like this
<script async src = "https://someurl.com/some-web-component.min.js"> </script>
<script >
document.addEventListener("DOMContentLoaded", function(event) {
if (document.querySelector('Component') == null) {
var script = document.querySelector('script[src="https://someurl.com/some-web-component.min.js"]')
document.head.removeChild(script)
}
});
</script>
More about DOM lifecycle events
More about async script loading
I am using $(document).ready and inside this method checking if element exists or not. It is working completely fine for me. Below is code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery Test Element Exists or Not</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var elem = document.querySelector('h1');
var isElemPresent = !!elem;
console.log('Is the element present: ', isElemPresent);
});
</script>
</head>
<body>
<h1>Hello Plunker!</h1>
<script>
var elem = document.querySelector('h1');
var isElemPresent = !!elem;
console.log('Oh NOW it works...: ', isElemPresent);
</script>
</body>
</html>
I am not sure where you are facing issue while using jQuery. There might be some other issue. Above approach is good enough to load script after checking if element is present.
Plunker link:
https://run.plnkr.co/preview/cjgczwlzt000knneldv5d52ea/
I'm working on a simple page that uses only <canvas> within the <body> of the page. All of the content is to be loaded through javascript. I am having trouble with using the document in my javascript and I was wondering if anyone could point me in the right direction of using <script> tags. Here is my main question:
What is the appropriate placement of <script> for a function loaded with window.onload
Here is the code I am working with:
index.html
----
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="window.js" type="text/javascript"></script>
</head>
<body>
<canvas>Canvas is not supported by your browser!</canvas>
</body>
window.js
----
Window = function(doc, win)
{
this.doc = doc;
this.win = win;
this.initialize();
}
Window.prototype =
{
initialize: function()
{
this.doc.documentElement.style.overflow = 'hidden';
this.doc.body.scroll = "no";
this.resize();
this.win.addEventListener('resize', this.resize.bind(this));
},
resize: function()
{
_canvas = this.doc.querySelector('canvas');
_canvas.width = this.win.innerWidth;
_canvas.height = this.win.innerHeight;
}
};
window.onload = new Window(document, window);
In all the tests of this script I have run, the only instance where it works is when the <script> is placed after the initial <body> tag. When I place the <script> in the <head> it gives me an error saying:
Uncaught TypeError: Cannot set property 'value' of null
Is it not a possibility for the sake of a clean looking document to have <script> be in the <head>?
Any clarification or direction on what the proper practice is would be greatly appreciated!
Script tags should go at the bottom of the page typically. This ensures all content has loaded and is ready for interaction...
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<canvas>Canvas is not supported by your browser!</canvas>
<script src="window.js" type="text/javascript"></script>
</body>
</html>
If you don't put the script in after the element, as far as your script is concerned, that element does not exist. It needs to be in the bottom, or at least after the canvas element.
In your case, it should be in the bottom, after the <canvas> element.
It really doesn't matter where your JS files are loaded. Your problem is that the JS files could possibly load before your DOM is fully drawn. I've had pages where JS at the bottom of the page was executing before the browser was done loading the middle. That's why every JS framework contains something to check if the DOM is ready or not. in jQuery you would use ready
$(document).ready(function() { alert('My DOM is loaded!'); });
Outside of jQuery, you could use DOMContentLoaded. Put this at the bottom of your window.js file and you can load it in your header without issue.
document.addEventListener("DOMContentLoaded", function(event) {
new Window(document, window);
});
I'm using a tumblr theme which is structured like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<style>
</style>
<body>
</body>
</html>
There are no head tags which I thought was strange but it works fine; because when you run the site it places head tags automatically. However, since I'm using plugins I added the head tags myself to give me better control as some required me to place it in <head>. This worked fine in chrome and safari but it disabled one of my scripts in firefox and IE:
$(document).ready(function () {
var speed = 25,
timer;
$("#hoverscroll").hover(function () {
$(this).css({cursor: 'none'});
$(this).css({opacity: '0'});
var div = $('body');
(function startscrolling(){
timer = setTimeout(function () {
var pos = div.scrollTop();
div.scrollTop(pos + 1);
startscrolling();
}, speed);
})();
},
function () {
$("#hoverscroll").css({opacity: '1'});
clearTimeout(timer);
speed = 25;
})
.click(function(){
speed = 1;
});
});
It's a simple script where it scrolls the page when an element is hovered.
I reproduced the problem in these 2 demo-sites:
http://testmycode.tumblr.com/ This site has head tag, scrolls in chrome, does not scroll in Firefox.
http://testmycode2.tumblr.com/ This site has no head tag, works perfectly and scrolls in all browsers.
you can add code to your head tag using JQuery like below
$("head").append("<script src=\"mypluginscript.js\"></script>");
this will let you add any new code to it without having to write the head tag
an example!
'However, since I'm using plugins I added the head tags myself to give
me better control'
What you mean by that?
Most of the times there is an alternative solution.
A proper html needs a html tag a head tag and a body tag
inside the head tag you put meta,script and style tags
minimal structure is
<html>
<head>
</head>
<body>
</body>
</html>
Else it's not a html file.
Almost TEN years html5 was launched....
and as it is similar to the basic structure it works on all browsers.
<!doctype html> // html5
<html lang="en"> // language set to english
<head>
<meta charset="utf-8"> // can decode almost al charachters éçàò..
<style></style>
<script></script>
<title>Title</title>
</head>
<body>
</body>
</html>
now reguarding your code.
<script>
goes inside head (or at the end of the body [or just after each element])
if you put the code in the head..
to handle elements inside the body
you need to add a window.onload // DOMContentLoaded
else you have no access to the dom elements.
Now looking at your code from Chrome the errors starts on the html tag..
Why the html has a webkit animation?
Then your talking about the doctype tag and not the head tag.
So if you tell us why you need that we can probably find a solution.
I believe that I've identified a bug in Opera (version 12.01 running on Windows 7), but am looking for assistance with a possible workaround (presuming that others can confirm that this is a bug).
If I have an HTML page containing the following:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" />
</head>
<body onload="window.alert(0);">
</body>
</html>
The "onload" event is never fired. Oddly, if I close the script tag instead of self closing it, and change:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" />
to:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
(which unfortunately I can't do), the event will fire and my alert will be shown.
Had anyone else run into this problem? If so, have they found a way around it besides changing the script tag from <script /> to <script></script>?
NOTE: Yes, I have opened a bug report with Opera. No response back from them yet.
This "bug" exists in all browsers, not only in Opera (I've tested Chrome, FF and IE).
Self-closing script tags just don't work. See this question on SO: Why don't self-closing script tags work?
EDIT:
I have no idea why you can't close the script tag with </script>, but one possible workaround would be loading the scripts with JavaScript:
var newScript = document.createElement("script");
newScript.type = "text/javascript";
newScript.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js";
newScript.onload = function(){
// jQuery code...
};
document.getElementsByTagName("head")[0].appendChild(newScript);
(OK, admittedly this actually forces you to use </script> somewhere, but at least the part between <script> and </script> now isn't empty... :P)
What Opera does is correct per HTML5. To understand why the onload doesn't run, you need to remember that the contents of a SCRIPT tag with SRC set should be ignored. Since /> is not a correct way to close the first SCRIPT tag, the subsequent end-of-head and start-of-body tags end up inside the SCRIPT tag. It would be a bit like writing this:
<script src="foo.js">
</head><body><p>This doesn't appear anywhere, does it?</p></body>
</script>
So onload is never set in the first place because the BODY inside the SCRIPT tag will be ignored.
I think this is a very simple question, but I can't seem to get it to work. I need to use JavaScript (specifically jQuery, apparently) to grab some content from a page, and pull it into another page. I've researched this quite a bit, but can't seem to get even a very simple example to work.
Here is the page I'm trying to get content from:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Test</title>
</head>
<body>
<p>This is the test html page.</p>
</body>
</html>
Here is the page I'm trying to use to pull the content:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>PullData</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">
</head>
<body>
<ol id="result"></ol>
<script type="text/javascript">
$('#result').load('test.html');
</script>
</body>
</html>
When I open the page it doesn't seem to do anything. I'm basically trying to follow the examples from jquery.com: http://api.jquery.com/load/
Both html pages are in the same folder somewhere on my C drive.
What am I missing?
Thanks in advance for your help!
What browser are you using?
Because of same-origin policy, some browsers won't permit AJAX requests to file:/// URLs, even if the original file was loaded that way. I know this is true of Chrome, but haven't tested others.
What does your .load() error handler say? Oh...
It seems to make logical sense.
Checking the API on load you may want to see if it actually loads, or if it encoutners an error
$("#result").load("/not-here.php", function(response, status, xhr) {
if (status == "error") {
var msg = "Sorry but there was an error: ";
$("#result").html(msg + xhr.status + " " + xhr.statusText);
}
});
API LINK: http://api.jquery.com/load/
sometimes the debugging information is a good first step to any solution.
You have your script tags at the end of your page, which means the enclosed JS will be invoked as soon as the browser reaches it, which may not be before the DOM is ready (which means the <ol> might not be set up to get the content of test.html). Try enclosing your load in a $(document).ready() callback as follows:
<script type="text/javascript">
$(document).ready(function() {
$('#result').load('test.html');
});
</script>
Also why are you inserting a full HTML page into an ordered list? You should try an HTML snippet (no head & body tags) into a content holder such as <div> or <span> where it will be semantically correct.
If none of these things work, attach a callback as follows:
$('#result').load('test.html', null, function(responseText, textStatus, xhr) {
alert(textStatus); // see what the response status is
});
Where is the closing script tag?
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">
</head>
Your code needs to be
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>
You must first check if your HTML is ready.
$(document).ready(function() {
$('#result').load('test.html');
});
To ensure #result1 is loaded, you need a document.ready event handler:
<script type="text/javascript">
$(document).ready(function(){
$('#result').load('test.html');
});
</script>
Hope this helps. Cheers