I was able to make onmousesenter work correctly when I included the reference to the function directly in the html, but read that was bad form and wanted to improve my code- but now I can't get it to run, despite my code showing it does trigger the function, I'm just not sure why the rest of it fails to run now:
<DOCTYPE! html>
<head>
<link rel="stylesheet" type="text/css" href="index.css">
<title>Sexism in Silicon Valley</title>
<script src="index.js"></script>
</head>
<body id="body1">
<div class="parent">
<img src="kstartup.png" class="logos" id="id1"></img>
<img src="uber.png" class="logos" id="id2"></img>
<img src="kpcb.png" class="logos" id="id3"></img>
<img id="id4" src="r1startup.png" class="logos"></img>
</div>
Javascript (index.js):
function mouseenter() {
alert("hey");
var z = document.getElementsByClassName("parent");
for (var i = 0; i < z.length; i++) {
z[i].style.background = "black";
}
var bod = document.getElementById("body1");
bod.style.background = "black";
}
document.getElementById("id1").onmouseenter = mouseenter();
The alert goes off as soon as I load the page instead of when my mouse enters the id1. Why isn't it triggered by my mouse entering the id?
Your document DOM is not ready when you try to access the ID id1 Element.
document.getElementById("id1").onmouseenter = mouseenter; // Don't execute()
// Since this code is inside HEAD, JS does not know about any #id1 Element yet.
cause you're calling the <script> tag inside <head> instead of at the bottom before the closing </body> tag.
<script src="index.js"></script> <!-- Makes sure parser readed all the elements -->
</body>
</html>
document.getElementById("id1").onmouseenter = mouseenter; // << no ()
// Assign, don't execute.
There are quite a number of issues here:
The doctype is incorrect
Image tags do not have a closing equivalent in HTML5, i.e. </img> does not exist (was a thing in XHTML)
You have not wrapped you JavaScript in <script> tags so it is being interpreted as HTML
You are calling the mouseenter function when you are assigning it, so you actually assigning the result. In other words you should just assign a reference to the function: document.getElementById("id1").onmouseenter = mouseenter
Working example here: http://plnkr.co/edit/fmBIM7U6QSS0cl7vqdlQ?p=preview (obviously the images will not load, as you only provided relative paths)
Related
This question already has answers here:
How can I make the browser wait to display the page until it's fully loaded?
(16 answers)
Closed 4 years ago.
Both Firefox and Chrome is rendering my pages way too early, which results in my a couple of frames where you first see the header, then the content, and then the footer. It's a very very unpleasant page loading experience.
The way I get around this right now is this, which is such a silly workaround I would like to avoid. It also causes the page to flash white in Chrome.
<!DOCTYPE html>
<html>
<head>...</head>
<body>
<div id="render-all-at-once" style="opacity:0; min-height:100%;">
content
</div>
<script>
document.getElementById("render-all-at-once").style.opacity = 1;
</script>
</body>
</html>
The problem is basically this:
<script>
function sleep(millis) {
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while (curDate - date < millis);
}
</script>
<div>
This will be rendered in the first frame.
</div>
<script>
sleep(3000);
</script>
<div>
And only after that first frame has been rendered will you see this line. You don't see the first line for 3 seconds as
you might, but you do see it flash, right before both lines are displayed.
</div>
<!---
I would like the browser to not render anything until
the entire entire document has been processed.
--->
In isolated tests, the above code seem to work as expected - both lines will be rendered at the same time after 3 seconds. But as soon I start adding a couple of random style-sheets to the page, the problem starts occurring.
I can't seem to narrow it down to any particular style-sheet or style. I can't figure out what's causing it. I've both tried loading all styles sheets from , or just having all of them inlined in a style element. This doesn't make any difference. I'm testing this using Chrome as it seems to happen more frequently there.
Does anyone have any experience with this sort of problem, or have any ideas what's causing it, and know of any way to prevent it?
What I like to do is wrap my content in a div and set it to display:none.
Then, I defer my CSS loading and in my CSS file, and set that wrap div to display:block.
I also compress all my CSS files into one single file (for better loading).
<!DOCTYPE html>
<html>
<head>
<style>
.wrap {
display: none;
}
</style>
</head>
<body>
<div class="wrap">
content
</div>
<noscript id="deferred-styles">
<link rel="stylesheet" type="text/css" href="compressed.css" />
</noscript>
<script>
var loadDeferredStyles = function() {
var addStylesNode = document.getElementById("deferred-styles");
var replacement = document.createElement("div");
replacement.innerHTML = addStylesNode.textContent;
document.body.appendChild(replacement);
addStylesNode.parentElement.removeChild(addStylesNode);
};
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if(raf) {
raf(function() {
window.setTimeout(loadDeferredStyles, 0);
});
} else {
window.addEventListener('load', loadDeferredStyles);
}
</script>
</body>
</html>
Use the network tab in developer tools to see the process & response of each request. First, the HTML is fully received and parsed by the browser which then looks for remote objects to load top-down: stylesheets, images, javascript, etc.
So, to have complete control over how things appear, send an HTML document that looks exactly as you'd like the initial view to be (ex: a blank white document, achieved with inline CSS or a <style> tag that targets <body>). Then use a line of Javascript to listen for the load event and update your display, for example:
<!doctype html>
<html>
<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/stackoverflow/primary.css">
<body style="display: none;">
<h1>Headline</h1>
</body>
<script>
window.addEventListener("load", function(event) {
document.querySelector("body").style.display = "block";
});
</script>
</html>
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 7 years ago.
Rookie alert!
Would you tell me why my Javascript code doesn't update the message. The browser runs HTML but ignores the Javascript code. What am I doing wrong?
<!DOCTYPE html>
<html>
<head>
<title>Basic Function </title>
<script type="text/javascript">
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
updateMessage();
</script>
</head>
<body>
<h1> Travel Worthy </h1>
<div id="message">Welcome to our site! </div>
</body>
</html>
You're running the Javascript before you've loaded the body, the message element doesn't exist yet. Either move the script to the end of the <body>, or change the last line to:
window.onload = updateMessage;
so that the function will be loaded after the HTML is loaded.
If the <script> tag is in the <head> element, it gets executed before the HTML elements in the <body> are created. You can put your script tag inside the <body> element, at the end of it, to solve the issue.
Assuming you don't simply have javascript disabled, you could add a window.onload=function(){ surrounding your code.
window.onload=function(){
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
updateMessage();
}
The reason for doing this is because your javascript code is inside your <head>. Thus, the javascript is loaded before the body. When the browser attempts to execute the javascript code, the message element isn't loaded yet and doesn't exist. By adding window.onload=function(){ to surround your code, your entire code will wait until the body is loaded before executing.
When you call your javascript code, the 'message' element isn't already there. I would suggest one of the following two things:
+Put your javascript code at the end of the body ( note that it only need to be after 'message', but putting it at the end is generally the best option )
+Replace your call with window.onload = updateMessage, which will wait until all the page is loaded to execute your javascript
There are already lots of duplicate answers here but there is another way, especially if you want to keep your Javascript code in a script tag in the head. And that is, wrap your Javascript function call in setTimeout -- this causes the function to be executed after the DOM has been parsed, but before the entire window has been loaded.
It's a neat little trick that can be used when you don't have a framework's (such as jQuery) document/ready functionality. window.onload or putting the script at the bottom might cause significant delays if there is lots of heavyweight content (large images?) in the page.
<!DOCTYPE html>
<html>
<head>
<title>Basic Function </title>
<script type="text/javascript">
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
setTimeout(updateMessage);
</script>
</head>
<body>
<h1> Travel Worthy </h1>
<div id="message">Welcome to our site!</div>
<img src="http://cdn.spacetelescope.org/archives/images/publicationjpg/heic1502a.jpg" />
</body>
</html>
Notice I have added a very large image to the page, but the updated message displays before the image fully loads.
If however instead of setTimeout(updateMessage); you use window.onload = updateMessage; as suggested in the currently accepted answer, your message will not get updated until the entire image loads (if you try this out, make sure you do a hard refresh after the first time so you are not getting it from your cache). Same goes for moving the script too far down the page (below the very large image for instance) as below. I honestly think, if you don't have a framework's document/ready functionality, using setTimeout in a script block in the head is the best solution.
MESSAGE NOT UPDATED UNTIL AFTER IMAGE LOADS:
<!DOCTYPE html>
<html>
<head>
<title>Basic Function </title>
</head>
<body>
<h1> Travel Worthy </h1>
<div id="message">Welcome to our site!</div>
<img src="http://cdn.spacetelescope.org/archives/images/publicationjpg/heic1502a.jpg" />
</body>
<script type="text/javascript">
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
updateMessage();
</script>
</html>
You are trying to make the changes before the DOM is loaded. See the code below,
<!DOCTYPE html>
<html>
<head>
<title>Basic Function </title>
</head>
<body>
<h1> Travel Worthy </h1>
<div id="message">Welcome to our site! </div>
</body>
<script type="text/javascript">
var msg = 'Sign up to receive our newsletter for 10% off!';
function updateMessage() {
var el = document.getElementById('message');
el.textContent = msg;
}
updateMessage();
</script>
</html>
In the following example the flash in my HTML would not show after moving it's parent element in DOM. I use appendChild on enclosing div of my object element to move it somewhere else in the DOM hierarchy, but after the move is complete the containing flash would not show.
I get this error in IE 10 and firefox, in Chrome there seems to be no problem.
This error happened in much larger project, but I managed to distill it to the following little example.
<html>
<head>
<script>
window.onload = function() {
var copy = document.getElementById("s");
document.getElementById("newparent").appendChild(copy); //if I comment out this line, example works
}
</script>
</head>
<body>
<div id="newparent"> <!-- here will the object be appended -->
</div>
<div id="s">
<object width="50%" height="50%" data="http://www.w3schools.com/tags/helloworld.swf">SWF Not shown</object>
</div>
</body>
</html>
If I comment out the second line of my onload function, the flash shows properly (but it is not moved around). I am not able to google anything. Perhaps I am not able to describe my problem, I am pretty new to HTML. Thanks in advice.
OK, so thanks to you guys, I had an idea of what to look for and I stumbled upon this article.
The problem I have seems to be that for some ?security? reasons the flash would not load after being moved. I devised this dirty workaround, simply I force browser to parse and recalculate the object tag. Is it so? I hope I understand well what am I doing.
<html>
<head>
<script>
window.onload = function() {
var copy = document.getElementById("s");
document.getElementById("newparent").appendChild(copy);
copy.innerHTML = copy.innerHTML; //dirty workaround
}
</script>
</head>
<body>
<div id="newparent"> <!-- here will the object be appended -->
</div>
<div id="s">
<object width="50%" height="50%" data="http://www.w3schools.com/tags/helloworld.swf">SWF Not shown</object>
</div>
</body>
</html>
I have this function which is trying to change the src property of an img. Here's the Javascript:
function transition(){
document.getElementById("firstfirst").src = marray[currArrayValue];
currArrayValue++;
if(currArrayValue == array.length-1){
currArrayValue = 0;
}
setTimeout(transition(), 1000);
}
My google chrome console is saying document.getElementById("firstfirst") doesn't exist, but it definitely does. Here's the HTML:
<div id="banners-container">
<div id="banners">
<img src="images/banners/top-banner-one.png" id="firstfirst" alt="Subscribe now to get access to thousands of vintage movies!" border="0">
</div>
</div>
What gives?
Javascript is executed as soon as it has been parsed.
If your JS is included in the <head> of your webpage, it will be executed before the document body has been parsed and the DOM has been built.
As such, you need to engineer your code so that it is not executed until the DOM has been loaded. You might want to look at the MDN docs on the DomContentLoaded event. Alternatively, you can use one of the many JavaScript libraries out there which wrap this up for you.
if chrome says the element is null it is null. Perhaps you are calling function before the element loaded in DOM. like calling the function in head tag prior the element tag.
so try something like this.
<html>
<head>
<script>
function F () { /*reach element*/ }
</script>
</head>
<body>
//The element
</body>
<script>
F ();
</script>
</html>
I'm trying to write a javascript function that adds some DOM nodes to the document in the place it was called, like this:
...
<div>
<script type="text/javascript">
pushStuffToDOMHere(args);
</script>
</div>
...
i try to do it 'cleanly', without using node id property of the div, or innerHTML string manipulation. for that I need to know where in the document the script tag is located.
is there a way to do it?
Talking about cleanly, I don't think your approach is particularly clean. It is a much better idea to give the div a unique id and execute your javascript when the DocumentReady-event fires.
Do you have an overriding reason for doing it this way? If not the suggestion to use a unique id makes the most sense. And you can always use a library like jQuery to make this even easier for yourself.
However, the following quick test shows that if you use document.write() in the function then it writes the value into the place where the function was called from.
<html>
<head>
<script type="text/javascript">
function dosomething(arg){
document.write(arg);
}
</script>
</head>
<body>
<div>The first Div</div>
<div>The
<script type="text/javascript">
dosomething("Second");
</script>
Div
</div>
<div>The
<script type="text/javascript">
dosomething("Third");
</script>
Div
</div>
</body>
</html>
But, again the question, are you sure this is what you want to do?
Although I agree with n3rd and voted him up, I understand what you are saying that you have a specific challenge where you cannot add an id to the html divisions, unless by script.
So this would be my suggestion for inlining a script aware of its place in the DOM hierarchy, in that case:
Add an id to your script tag. (Yes, script tags can have ids, too.)
ex. <script id="specialagent" type="text/javascript">
Add one line to your inline script function that gets the script element by id.
ex. this.script = document.getElementById('specialagent');
...And another that gets the script element's parentNode.
ex. var targetEl = this.script.parentNode;
Consider restructuring your function to a self-executioning function, if you can.
Ideally it executes immediately, without the necessity for an 'onload' call.
see summary example, next.
SUMMARY EXAMPLE:
<script id="specialagent" type="text/javascript">
var callMe = function(arg1,arg2,arg3) {
this.script = document.getElementById('specialagent');
var targetEl = this.script.parentNode.nodeName=="DIV" && this.script.parentNode;
//...your node manipulation here...
}('arg1','arg2','arg3');
</script>
The following TEST code, when run, proves that the function has identified its place in the DOM, and, importantly, its parentNode. The test has division nodes with an id, only for the purpose of the test. They are not necessary for the function to identify them, other than for testing.
TEST CODE:
<html>
<head>
<title>Test In place node creation with JS</title>
</head>
<body>
<div id="one">
<h2>Child of one</h2>
<div id="two">
<h2>Child of two</h2>
<script id="specialagent" type="text/javascript">
var callMe = function(arg1,arg2,arg3) {
this.script = document.getElementById('specialagent');
var targetEl = this.script.parentNode;
/*BEGIN TEST*/
alert('this.script.id: ' + this.script.id);
alert('targetEl.nodeName: ' + targetEl.nodeName + '\ntargetEl.id: '+targetEl.id);
alert('targetEl.childNodes.length: ' + targetEl.childNodes.length);
var i = 0;
while (i < targetEl.childNodes.length) {
alert('targetEl.childNodes.'+i+'.nodeName = ' + targetEl.childNodes[i].nodeName);
++i;
}
/*END TEST - delete when done*/
//...rest of your code here...to manipulate nodes
}('arg1','arg2','etc');
</script>
</div>
</div>
</body>
</html>
Not really sure what your trying to achieve but this would pass the dom element to the function when clicked. You could then use jquery in the function to do what you wanted like so
...
<script type="text/javascript">
function pushStuffToDOMHere(element)
{
$(element).append("<p>Hello</p>"); // or whatever
}
</script>
<div onclick="pushStuffToDOMHere(this);">
</div>
...
my solution is a compbination of the (good) answers posted here:
as the function is called, it will document.write a div with a unique id.
then on document.onload that div's parent node can be easily located and appended new children.
I chose this approach because some unique restrictions: I'm not allowed to touch the HTML code other than adding script elements. really, ask my boss...
another approach that later came to mind:
function whereMI(node){
return (node.nodeName=='SCRIPT')? node : whereMI(node.lastChild);
}
var scriptNode = whereMI(document);
although, this should fail when things like fireBug append themselves as the last element in the HTML node before document is done loading.