0

I've got a very simple function, of replacing the innerHTML of a element. I've been trying to debug this for hours but simply can't, and it's infuriating.

When called from a button press the JavaScript (as follows) works well, but when called from another function it doesn't work. I am totally lost as to why this might be, and its a fairly core part of my app

  // This loaded function in my actual code is a document listener
  // checking for when Cordova is loaded which then calls the loaded function
  loaded();

  function loaded() {
alert("loaded");
changeText();
  }

  function changeText() {
   alert("started");
   document.getElementById('boldStuff').innerHTML = 'Fred Flinstone';
  }

Button press and HTML to replace

 <div id="main">
  <input type='button' onclick='changeText()' value='Change Text'/>
  <p>Change this text >>  <b id='boldStuff'> THIS TEXT</b> </p> 
 </div>

It is also here in full on JSFiddle

tim.baker
  • 2,807
  • 4
  • 24
  • 48
  • 2
    `Uncaught TypeError: Cannot set property 'innerHTML' of null `. It does not seem like your code is executed when something is loaded, you execute it straight away. Please read [Why does jQuery or a DOM method such as `getElementByID` not find the element?](http://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element). – Felix Kling Jan 10 '13 at 11:10
  • I saw that in the Chrome Console, but I couldn't understand why it did that. It is executing the alert? I will read up on that though thanks. – tim.baker Jan 10 '13 at 11:14
  • 1
    Because you don't wait for the DOM being ready before the JS executes AND the HTML node your JS refers to is rendered ony AFTER your script runs, for the first time, element doesn't yet exist in the DOM. That's why the reference error. You can put your script after the HTML you want to refer to from you script, or you can use window.onload or jQuery, etc. for your script to wait until all HTML elements are parsed by DOM. – marekful Jan 10 '13 at 11:15
  • The `alert` happens before you try to access the element. If you switch both lines you won't see the alert. – Felix Kling Jan 10 '13 at 11:15
  • In the future, please include in your questions all console error messages etc. that you already know of, thanks! – Dani P. Jan 10 '13 at 11:17

3 Answers3

1

The problem here is, that the element you're trying to manipulate is not yet existing when you are calling the changeText() function.

To ensure that the code is only executed after the page has finished loading (and all elements are in place) you can use the onload handler on the body element like this:

<body onload="loaded();">

Additionally you should know, that it's very bad practice to manipulate values by using the innerHTML property. The correct way is to use DOM Manipulations, maybe this can help you.

s1lence
  • 2,060
  • 2
  • 15
  • 32
  • I'd say setting plain text content is a perfectly valid use case for `.innerHTML` (at least until every browser supports `.textContent`). – Felix Kling Jan 10 '13 at 11:15
  • I do agree, it's not the way I wanted to do it, but it's for a cross platform mobile app with very specific supposes so limited to my options. I have tried the onload="" option before but to no avail will try again – tim.baker Jan 10 '13 at 12:02
1

You script loads before the element (boldStuff) is loaded,

Test Link - 1 - Put the js in a seperate file

Test Link - 2 - put the js at the very end, before closing the <body>

painotpi
  • 6,479
  • 1
  • 32
  • 64
1

You are already changed the innerHTML by calling the function loaded(); on onLoad. Put this in an empty file and same as .html and open with browser and try. I have commented the function loaded();. Now it will be changed in onclick.

<div id="main">
  <input type='button' onclick='changeText();' value='Change Text'/>
  <p>Change this text >>  <b id='boldStuff'> THIS TEXT</b> </p> 
 </div>

<script>

  //loaded();

  function loaded() {
    alert("loaded");
    changeText();
  }

  function changeText() {
   alert("started");
   document.getElementById('boldStuff').innerHTML = 'Fred Flinstone';
  }

</script>
Sahal
  • 3,870
  • 11
  • 35
  • 64