9 Replies - 9676 Views - Last Post: 06 May 2014 - 06:10 PM

#1 EdNolan  Icon User is offline

  • D.I.C Regular

Reputation: 5
  • View blog
  • Posts: 423
  • Joined: 22-September 13

TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 03:13 PM

I don't understand why I am getting this error, I have () defined?

css
#b1{             /* banner 1 */
position: absolute;
left:1090px;
top:500px;
width:200px;
height:30px;
}



html
<div id="b1"></div>



JavaCcript
gfx[0]="images/ss.png";
lnk[0]="http://www.blabla.com";
wdh[0]="200";
hgt[0]="30";

function banner1() {
rnd0=Math.floor(Math.random()*6);
// document.writeln('<a target="_blank" href="'+lnk[rnd0]+'"><IMG SRC="'+gfx[rnd0]+'" border=0 width='+wdh[0]+' height='+hgt[0]+'><\/a>');
 document.getElementById("b1").innerHTML =('<a target="_blank" href="'+lnk[rnd0]+'"><IMG SRC="'+gfx[rnd0]+'" border=0 width='+wdh[0]+' height='+hgt[0]+'><\/a>');
}



The 'document.writeln' worked but I want 'document.getElementById("b1")' What the heck am I doing wrong? Why is it null?

Is This A Good Question/Topic? 0
  • +

Replies To: TypeError: document.getElementById(...) is null

#2 ArtificialSoldier  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1830
  • View blog
  • Posts: 5,761
  • Joined: 15-January 14

Re: TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 03:42 PM

Never use document.write or document.writeln. In certain cases it will remove everything else on the page.

The error message means that document.getElementById("b1") is not returning an element. Maybe an element with that ID doesn't exist when that code executes.
Was This Post Helpful? 1
  • +
  • -

#3 EdNolan  Icon User is offline

  • D.I.C Regular

Reputation: 5
  • View blog
  • Posts: 423
  • Joined: 22-September 13

Re: TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 03:56 PM

I only did document.writeln to make sure it would post, I was checking the <a>stuff</a>, :)
I tried this code below, the page loads everything just fine and everything functions, but the banner never shows up?

function addTextNode(text) {
  var newtext = document.createTextNode(text),
      p1 = document.getElementById("b1");

  p1.appendChild(newtext);
}
text = document.createTextNode('<a target="_blank" href="'+lnk[rnd0]+'"><IMG SRC="'+gfx[rnd0]+'" border=0 width='+wdh[0]+' height='+hgt[0]+'><\/a>');



Was This Post Helpful? 0
  • +
  • -

#4 ArtificialSoldier  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1830
  • View blog
  • Posts: 5,761
  • Joined: 15-January 14

Re: TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 03:59 PM

I don't think a text node is going to render HTML content, it's just going to display it as text. I haven't tested that though. You can use document.createElement if you want to create and append an HTML element.
Was This Post Helpful? 0
  • +
  • -

#5 EdNolan  Icon User is offline

  • D.I.C Regular

Reputation: 5
  • View blog
  • Posts: 423
  • Joined: 22-September 13

Re: TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 04:07 PM

I tried that too ...
document.createElement("b1").innerHTML =('<a target="_blank" href="'+lnk[rnd0]+'"><IMG SRC="'+gfx[rnd0]+'" border=0 width='+wdh[0]+' height='+hgt[0]+'><\/a>');


The banner still never shows up. Can you tell me more about ...
'Maybe an element with that ID doesn't exist when that code executes./
Thanks!
Was This Post Helpful? 0
  • +
  • -

#6 ArtificialSoldier  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1830
  • View blog
  • Posts: 5,761
  • Joined: 15-January 14

Re: TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 04:10 PM

You should really look this stuff up if you don't know how to use it. You're not using createElement correctly, there is no <b1> element. You pass it the name of the element you want to create, and it returns the new element. You set whatever properties you want on the new element, and then append it to a parent element already on the page. You can append it to the body element, for example, or any other element that allows child elements.

https://developer.mo...t.createElement
Was This Post Helpful? 0
  • +
  • -

#7 andrewsw  Icon User is online

  • the case is sol-ved
  • member icon

Reputation: 6380
  • View blog
  • Posts: 25,779
  • Joined: 12-December 12

Re: TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 04:23 PM

Does your JS code run after 'b1' is rendered, and is available, on the page?
gfx[0]="images/ss.png";

Is there more than one element in this array?

Is b1 visible on the page? You've pushed it absolutely across and down. It may even be behind something. Put some text in it, or set a background colour or outline, so you can see it.
Was This Post Helpful? 1
  • +
  • -

#8 EdNolan  Icon User is offline

  • D.I.C Regular

Reputation: 5
  • View blog
  • Posts: 423
  • Joined: 22-September 13

Re: TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 04:25 PM

I figured it out, I wrapped it in a separate function and then called it using ...
document.getElementById("b1").innerHTML =('<a target="_blank" href="'+lnk[rnd0]+'"><IMG SRC="'+gfx[rnd0]+'" border=0 width='+wdh[0]+' height='+hgt[0]+'><\/a>');


Thanks for your help. When I posted my question I had spent 2 hours trying different ways through research I did do, sorry, i posted that hastily. You did make me think though so thank you for that, and again thank you, for the posts, I take everything everyone says to heart!
Was This Post Helpful? 0
  • +
  • -

#9 Blindman67  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 138
  • View blog
  • Posts: 615
  • Joined: 15-March 14

Re: TypeError: document.getElementById(...) is null

Posted 05 May 2014 - 08:43 PM

Hi EdNolan..

I see you worked it out. I personally prefer writing HTML directly to the page rather than using create element. The problem with create element is that when you add it to the page it makes a copy of it which is a waste, and you are left to query the DOM (Document Object Model, the browsers internal representation of the page) to get the element you just added, if you want to manipulate it, though by adding HTML you have to do that as well. But with Direct HTML you can add complete pages and easily make templates.

Here is a tip for adding Strings as HTML to the page. It follows an important rule. "Always minimize interaction with the DOM"

Say you want to add a list of images. You would create a loop and add the images one at a time.

Like so
for(var i = 0; i < 20; i ++){
    document.getElementById("imageDiv").innerHTML = "<img src='imagename"+i+".png'>";
}

That is perfectly fine and works well but it suffers from some inefficiencies. Each time you add to the DOM it must parse the new HTML and make adjustments to the whole page. plus finding "imageDiv" each time. Above, that is done 20 times. Ok for small jobs but say you are making a table with a hundred rows and 10 columns with images, links.. etc. Then you will start to notice a slow down.

The Tip one. Minimize your DOM interaction by concatenating content insertion. Or put it in a string then when done add it to the DOM.

eg.
var str = "";                   // create a blank string
for(var i = 0; i < 20; i ++){   // loop
     str += "<img src='imagename"+i+".png'>"; //add to the string
}                               // when done add all the new content 
document.getElementById("imageDiv").innerHTML = str;  // in one go.


This is almost 2 orders of magnitude (100*) faster (depending on the browser) than the previous loop.

Sub Tip one. When a javascript function is called any modification you make to the DOM will not be displayed until it returns.
ie.
element.onclick = runMe();
function runMe(){  // starting point User will not see anything till
                   // this function returns
    ..do stuff..
    .. add to the DOM ...
    andMe();   // call anothe function
    // the User still will not see any changes
    ... add more to the DOM ...
} // end point
// the function has returned only now does the user see
// the new stuff you have added to the DOM
function andMe(){
    ... add more to the dom ...
    // when this return nothing will
    // be displayed as it must be the
    // top most call returning that
    // triggers the redraw.

}


Tip two. Again following the minimize interaction rule. If you are repeatedly interacting with the same element, don't use getElementById or any of the DOM query methods each time. Do it once at load time and store the element in a variable for easy and quick interaction.
var myElement;      // variable to hold the element
function onloaded(){  // called at page load
    // get the element from DOM for use when you need it.
    myElement = document.getElementById("myDiv")
}
  
function someOtherStuff(){
    myElement.innerHTML = "The stuff I want to add";
}
function somethingElse(){
    myElement.innerHTML = "and more stuff I want to add";
}


That is much better than asking the DOM to find the same element each time. "The DOM is a slow ugly monster ready to bite off a hand if it can." that's from a programmers point of view. You want to keep it locked up and interact with it only if you absolutely have to. Keeping that in mind will improve the speed and quality of your Javascript.

Arrays and Objects

Moving on from the arrays that I see you are using now. Javascript has two types of array like data storage that are very similar but have slightly different ways of using them. Each has an advantage over the other. Selecting which to use is a skill that you will learn over time.

Arrays (as you are already using) and Objects.
var myArray = [];  // creates a new empty array.
var myObject = {}; // creates a new empty Object


Both arrays and objects can hold collections of data. Arrays are best used when using only one type of data many times, objects are best used when you are using different types of data a few times.

Arrays are indexed usually by a number and are optimized for quick access and large sizes (arrays can store up to 232-1 that's just over 4.29Billion elements)

Object store data by named pairs, they have the same limits but you should never create very large objects.

In your code above you are using different arrays to store different types of information. This can become fiddly. You want to use a combination of an array and objects.

var imgLinked = []; // array to hold each image and link.
// now we can add objects to that array
imgLinked[0] = {  // notice the curly brace says we are creating an object
          imageUrl: "imageA.png",            // named item followed by : "colon"
                                             // then by the data of any type
                                             // followed by a comma
          siteUrl: "www.some.net/place.html",
          width: 20,
          height:20     // last item does not have a comma. Be careful as 
                        // leaving it there can create problems and different
                        // versions (browsers) treat it differently. Just Make
                        // sure its not on the last item
          };            //close the Object. Dont forget the ; semicolon 


Now to get the data there are many options but simplest

var myData = imgLinked[0]; // get the object from the array
var str  ='<a target="_blank" href="';
str += myData.siteUrl;
str += '"><IMG SRC="'
str += myData.imageUrl;
str +=  '" border=0 width='
str += mydata.width;
str +=  ' height=';
str += myData.height;
str += '><\/a>';



You can mix and match arrays and objects.
var data = [{}]; // array containing an empty object.
var data = [{},{}]; // array containing two empty object.
var data = {names:[]}; // object with names as empty array
var data = [[]]; // array inside and array Two dimensional array
                 // access data[first dimension][second dimension]
                 // data[4][9] gets the tenth item of the fifth array 
                 // Remember first element is 0
var data = [[[]]]; // 3 dimensions data[0][1][2] third item of the second array
                   // of the first array
var data = [[],{},"data"]; // 3 items empty array, empty object, string;
var data = [0,0,0,0,0,0];// array with 6 zeros


You can nest them any way you can imagine.

Both Arrays and Objects can be added to and indexed via "Bracket notation"
var arr = [];
arr[0] = "new data"; // adds new data to array at element 0
var obj = {};
obj["data"] = "new data"; // adds new data to object name "data".


Arrays can not be accessed via "Dot notation" while objects can.
var arr = [];
arr[0] = "new data"; // adds new data to array at element 0
var a = arr.0;       // this creates an error

// getting from object via Dot notation
var obj = {};
obj["data"] = "new data"; // adds new data to object name data.
var a = obj.data;         // works just fine


Objects can be added too via "Dot notation" as well
var obj = {};
obj.name = "new data";   //adds new data to object data "name"

// DON'T use dot notation on arrays 
// It does not create an error but it does not work as
// expected.
var arr = [];
arr.a = "data";  // DON'T do this.


Arrays always have a length property that you can use to iterate the array in loops.
var arr = [0,0,0,0,0];
console.log(arr.length); // sends 5 to the console. 


length can be written to as well
var arr = [0,0,0,0,0];
arr.length = 10; // adds 5 more items to the array
                 // each new item is undefined
var arr = [0,0,0,0,0];
arr.length = 3; // removes last to items from the array


Object do not have a length property but can still be iterated through with via (for i in obj) {obj[i];} but do not use this for now as there are problems associated with this as your objects become more complex or you start to use pre existing objects,


Oh dear time flys and I have gone on.

Hope that all helps with your coding.

This post has been edited by Blindman67: 05 May 2014 - 08:47 PM

Was This Post Helpful? 1
  • +
  • -

#10 EdNolan  Icon User is offline

  • D.I.C Regular

Reputation: 5
  • View blog
  • Posts: 423
  • Joined: 22-September 13

Re: TypeError: document.getElementById(...) is null

Posted 06 May 2014 - 06:10 PM

Blindman67, thanks for that lesson, I was wondering about some of these things so I'm glad you stepped in and gave the lesson. I particularly like this bit of code you posted since it fits my first need very well.

Quote

var str = ""; // create a blank string
for(var i = 0; i < 20; i ++){ // loop
str += "<img src='imagename"+i+".png'>"; //add to the string
} // when done add all the new content
document.getElementById("imageDiv").innerHTML = str; // in one go.

The commercial code you gave in one of my other posts, needs 9 cards drawn right away, and then 28 turns of play thereafter so this code I see could fill that void.

I would like you and everyone to know that the way I learn is first off being here at DreamInCode, and the second is when I know I want to ad something, I do generally search the net, study a bit, try somethings, and then ask. Sometimes though, even though I search and read and look at code I still don't understand where I should start when I want to add something. I have noticed my site slowing down so I am thankful you notice too and freely advise.

I have a mental block many times, and repetition is how I learn best. Sometimes it takes me 3 attempts at the same thing to get it down completely. So this banner code I was working on was my way of implementing some of the things everyone has mentioned. Baby step I know but if I can't really understand the small stuff I will never retain the big stuff, like the commercial version.

So in closing, your lesson also helps me understand more about the commercial version. Thank you for being there for me and helping me learn even though inside I wanted everything done 2 months ago, :). This is my first Javascript experience even though it's on a large scale, but I wouldn't want it any other way, I have a big appetite and little time however to learn like I really want and need to.

Thank You!!!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1