javascript document.getElementById not working - javascript

Following is my javascript program. I am trying to get all child tags of parent div tag but when I am running the program document.getElementById('abc') returning null.
function init(){
// currentDiv = document.getElementById("intro");
alert("working");
count = 0;
divs = document.getElementById('abc').getElementsByTagName("div");
alert("HI " + divs)
currentDiv = divs[count];
nextDiv = divs[count + 1]
count = count + 1;
}
window.onload = init();
Following is my div tag definitions:
<div id='abc'>
<div></div>
</div>
thanks.

The problem is in this line:
window.onload = init();
You are running init and setting the return value as the value of window.onload. My guess is that the code is being executed before the DOM is ready, i.e. before the divs exist.
Try this instead:
window.onload = init;

I suggest you start using jQuery instead, then you have much more powerful tools for this kind of DOM search/traversing

<body onload="init()">
<div id='abc'>
<div></div>
</div>
</body>
this probably solves your problem

Related

How to call a function in external script file from HTML

I'm trying to call a javascript function in my HTML index file and I can't get it to work.
This is my html file that I'm trying to call a function from.
<div class="main">
<h1 class="header-main" onload="HeaderTyper('Welcome', this)">
<noscript>no javascript</noscript>
</h1>
</div>
<script type="text/javascript" src="script.js"></script>
And this is the script.
function HeaderTyper(message, element){
var i = 0;
var speed = 50;
if (i < message.length) {
element.innerHTML += message.charAt(i);
//play keystroke sound
i++;
setTimeout(HeaderTyper, speed);
}
}
I'm trying to get a typewriter effect style header. I'm planning to add some keystroke sounds, but first I need to figure out how to actually type it out in the header tag. The code won't type out the message I'm passing in argument. What did I do wrong ? Thank you for any help.
After the HTML page ends (As #johannchopin explained), import the file and then add an event listener (as #aaronburrows explained).
<body>
<div class="main">
<h1 class="header-main">
<noscript>no javascript</noscript>
</h1>
</div>
</body>
</html>
<script type="text/javascript" src="script.js"></script>
<script>
let h1 = document.querySelector('.header-main');
h1.addEventListener('load', HeaderTyper("Welcome", h1, false));
</script>
Also, I fixed the function, it was missing the parameters.
function HeaderTyper(message, element, i) {
var speed = 50;
if (i < message.length) {
console.log(message.charAt(i))
element.innerHTML += message.charAt(i);
//play keystroke sound
setTimeout(function(){ HeaderTyper(message,element,++i)}, speed);
}
}
You're attempting to bind a function call before it is loaded into the browser. Remove the onload from the HTML and add an event listener to the script.
According to this solution, The onload event can only be used on the document(body) itself. Best way to achieve this is to call the function in a <script> tag just before the </body> closing tag:
<div class="main">
<h1 class="header-main">
<noscript>no javascript</noscript>
</h1>
</div>
<script>
function HeaderTyper(message) {
var i = 0;
var speed = 50;
var element = document.querySelector('.header-main');
if (i < message.length) {
element.innerHTML += message.charAt(i);
//play keystroke sound
i++;
setTimeout(HeaderTyper, speed);
}
}
HeaderTyper('Welcome');
</script>
Ok, hi there.
function HeaderTyper(message, element){
alert('script loaded') //<---
var i = 0;
I put this line at the beginning of the script to make sure it works. And it's not.
Why?
Because you just made your function but doesn't call it.
First way to solve this - put ur function in the "script" of HTML doc. And call it after, like
<script>
function HeaderTyper(message) {
let i = 0
let speed = 50
let element = document.querySelector('.header-main')
if (i < message.length) {
element.innerHTML += message.charAt(i)
i += 1
setTimeout(HeaderTyper, speed)
}
}
HeaderTyper('Welcome') //<---
</script>
Second way - put HeaderTyper() at the end of script.js file, so the function start, but you need to make a link for "message" and "element".
setTimeout(HeaderTyper, speed);
}
}
HeaderTyper(someMessage, someElement) //<---

Passing a variable into a DOM function in Javascript

I took this example from w3schools and modify it to this. The code below is not working.
What I intend to do is hide the div with id "demo1". It is not working. What is the problem?
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction(div_id)
{
//here the div_id variable seems to unparsable by the DOM event
document.getElementById(div_id).innerHTML = hello;
}
</script>
</head>
<body>
<p>Click the button to trigger a function.</p>
<button onclick="myFunction('demo1')">Click me</button>
<div id="demo1"></div>
<div id="demo2"></div>
</body>
</html>
The variable hello is not defined. You were probably looking to set the innerHTML as a String:
function myFunction(div_id) {
document.getElementById(div_id).innerHTML = "hello";
// -----------------------------------------^-----^
}
DEMO: http://jsfiddle.net/uzuKp/1/
Even though you took an example from W3Schools and modified it, I'd suggest binding events separate from the HTML and storing associated data in data-* attributes. In your example, it can be as something like this:
<p>Click the button to trigger a function.</p>
<button data-div-id="demo1">Click me</button>
<button data-div-id="demo2">Click me</button>
<button data-div-id="demo1">Click me</button>
<div id="demo1">demo1</div>
<div id="demo2">demo2</div>
And the JS:
function clickHandler() {
var targetDivId, targetDiv;
targetDivId = this.getAttribute("data-div-id");
targetDiv = document.getElementById(targetDivId);
targetDiv.innerHTML = "Hello" + new Date().getTime();
}
function loadHandler() {
var buttons, i, j, cur;
buttons = document.getElementsByTagName("button");
for (i = 0, j = buttons.length; i < j; i++) {
cur = buttons[i];
cur.onclick = clickHandler;
}
}
window.onload = loadHandler;
DEMO: http://jsfiddle.net/3K4RD/
Although I would also suggest looking at the following article to see different ways to bind events: addEventListener vs onclick
One final suggestion I have is to not set the innerHTML property. You may have a simple example here, but it's usually a better idea to use DOM methods like appendChild (to add a node) and document.createTextNode (to create text that can be appended). Of course, that would require the contents to be cleared out first, something like:
while (targetDiv.firstChild) {
targetDiv.removeChild(targetDiv.firstChild);
}
targetDiv.appendChild(document.createTextNode("Hello"));
DEMO: http://jsfiddle.net/52Kwe/
You could also store the specific string that needs to be set as the innerHTML as a data-* attribute (especially if it differs between buttons).
UPDATE:
Per your recent edit, the style property is a special property, which is actually a special object with style properties that you need to set. So for your example, you have to set the .style.display value, like:
document.getElementById(div_id).style.display = "none";
document.getElementById(div_id).style.display = 'none';
document.getElementById(div_id).style.visibility= 'hidden';

append child after the node of the script that made the call

When the call bellow is done the class creates a set of elements (a form) and then I want to append them right after the script that called it.
I have been looking at various similar questions but the best of them simply append it after the last script on the page.
It would work nicely in the head but not the body.
<script type="text/javascript">
new exampleClass();
</script>
You should have some type of unique identification to find and append elements after the script. You can use document.getElementById() if you have id, or document.getElementsByTagName("script") to get script elements and get the required script element and then use appendChild()
Ok, here is the horrible hack mentioned.
HTML
<div>Stuff</div>
<script type="text/javascript">
noop();
</script>
<div>More stuff</div>
<script type="text/javascript">
new ExampleClass();
</script>
<div>More stuff</div>
<script type="text/javascript">
noop();
</script>
<div>More stuff</div>
Javascript
function noop() {}
function appendAfter(node, newNode) {
if (node.nextSibling) {
node.parentNode.insertBefore(newNode, node.nextSibling);
} else {
node.parentNode.appendChild(newNode);
}
}
function ExampleClass() {
window.addEventListener("load", function () {
var scripts = document.getElementsByTagName("script"),
div = document.createElement("div"),
length = scripts.length,
i = 0,
script;
div.appendChild(document.createTextNode("Inserted"));
while (i < length) {
script = scripts[i];
if (script.firstChild && script.firstChild.nodeValue.indexOf("ExampleClass()") !== -1) {
appendAfter(script, div);
}
i += 1;
}
}, false);
}
On jsfiddle
Based on some of your comments and some other similar I have thought of doing something like this and it seems to work.
// Generate random string we can use as element id
var rs = Math.random().toString(36).substring(2);;
// Document write an empty div with the above string as id
document.write('<div id="' + rs + '"></div>');
// Get the element to use for append
var ip = document.getElementById(rs);
Please feel free to comment if you think it may have a fatal flaw.

move node from second to first

Just want a function that move second node to be a first node.But it not working, any suggestion?
var node = document.getElementById("ir");
var cx = node.childNodes[1];
function der(){
node.insertBefore(cx,node.firstChild);
}
fullcode:
<div id="ir">
<p id="ie">test</p>
<img src="test.gif">
</div>
<script type="text/Javascript">
var node = document.getElementById("ir");
img.setAttribute("onclick","der()");
var cx = node.childNodes[1];
function der(){
node.insertBefore(cx,node.previousSibling);
}
http://jsfiddle.net/joeframbach/JSZPy/
The issue with the html in that fiddle is the spaces. childNodes[0] matches the first set of spaces, and childNodes[1] matches the first element. Perhaps this is your issue.
<div id="ir">
<p>First</p>
<p>Second</p>
</div>
var node = document.getElementById("ir");
var first = node.childNodes[1];
var second = node.childNodes[3];
node.insertBefore(second,first);
I'm a bit slow today, but I think your use of previousSibling is wrong. I think it should relate to the child node cx not the parent node .. so you should be using cx.previousSibling not node.previousSibling - I've edited mt previous example to remove my original dumb response ... try this ...
<div id="ir">
<p id="ie">test</p>
<img src="test.gif">
</div>
<script type="text/Javascript">
var node = document.getElementById("ir");
img.setAttribute("onclick","der()");
var cx = node.childNodes[1];
function der(){
node.insertBefore(cx,cx.previousSibling);
}
Two Days Later Edit !!! ....
Of course the example I gave above will not swap the P element and the image because the image's true previousSibling is a newline character between the /P tag closure and the image. More importantly from a coding perspective, it won't work because there isn't an object called 'img' defined anywhere ... so I offer this as a working alternative :
<script>
function swapDivs(obj) {
if(obj.previousSibling){ // if it's null, then it's already the first element //
obj.parentNode.insertBefore(obj, obj.previousSibling);
}
}
</script>
<div id="ir">
<p id="ie">test</p><img src="http://i2.ifrm.com/4639/142/emo/drool.gif" onclick="swapDivs(this);" />
</div>
It doesn't address the newline issue, I just reformatted the HTML.
However, it does resolve the img issue, and provides a generic way of adding the function to any clickable DOM object without having to customise the function.
I'll leave it to you to work out how to get over the problem with the newline/whitespace sibling, but it shouldn't be to difficult. Here's the fiddle to play with if you want to test your attempts ... http://jsfiddle.net/radiotrib/ps9XZ/
You've got an answer but i recommend doing something like:
var node = document.getElementById("ir");
var childs = node.getElementsByTagName("div");
var cx = childs[1];
function der()
{
node.removeChild(cx);
node.insertBefore(cx, childs[0]);
}
der();
I advise you not to put spaces or breaklines when working with childnodes, because they are considering like child of text type. I hope this code will help you:
Javascript code:
function change(){
var parent = document.getElementById("ir");
var img = parent.childNodes[1];
parent.removeChild(img);
parent.insertBefore(img, parent.firstChild);
}
HTML code:
<div id="ir"><p id="ie">test</p><img src="test.gif"></div>
<button onclick="change()">Change</button>

Why Doesn't This Javascript Work? Style Change

I cant for the life of me figure out why this doesn't work:
javascript:
//==================================//
// resize_middle //
//----------------------------------//
// Resizes the content and left //
// navigation div to make up the //
// remains of available space. //
//==================================//
function resize_middle()
{
min_height = (window.innerHeight - 276) + "px";
middle_left = document.getElementById("middle_left");
middle_right = document.getElementById("middle_right");
alert("its not going to work!");
alert("here goes...");
alert(min_height);
middle_left.style.minHeight = min_height;
alert("it works!");
middle_right.style.minHeight = min_height;
}
//==================================//
// event handlers //
//==================================//
window.onload = resize_middle();
window.onresize = resize_middle();
html(body & javascript bit in head shown only):
<script src="javascript.js" type="text/javascript" charset="utf-8"></script>
<body>
<div id="container">
<div id="central_column">
<div id="top_left">
<img src="./images/icon.png" alt="icon" style="width:100%;height:auto;" />
</div>
<div id="top_right">
top right
</div>
<div id="middle_left">
middle left
</div>
<div id="middle_right">
middle right
</div>
<div id="bottom">
bottom
</div>
</div>
</div>
</body>
I'v used this before and have a working copy of some only slightly different code, but it works perfectly. I get the debugging alerts up until "it works!", which I don't get. Thanks in advance, ell.
You need this instead:
window.onload = resize_middle;
window.onresize = resize_middle;
Because as having it resize_middle() the function is processed immediately and the result is added to the event. You want the function itself to be added to the event so you leave off the () unless your function returns a function for the event to use.
You need this instead:
window.onload = resize_middle;
window.onresize = resize_middle;
Currently you're calling those functions and assigning their return value to the event. What you want is to assign the functions themselves to the events, and let the events call them.
Side note:
Unless the variables in resize_middle are defined elsewhere and you intend for them to be accessible to the outer scope, it is good practice to use the var keyword when defining new variables.
function resize_middle()
{
// Changed to use "var"
var min_height = (window.innerHeight - 276) + "px";
var middle_left = document.getElementById("middle_left");
var middle_right = document.getElementById("middle_right");
alert("its not going to work!");
alert("here goes...");
alert(min_height);
middle_left.style.minHeight = min_height;
alert("it works!");
middle_right.style.minHeight = min_height;
}
window.onload = resize_middle;
Read this resource on assigning event handlers.

Categories

Resources