0

My code works on localhost, but when I implement it on my site, it doesnt. The error log says it's calling for an element that doesn't exist. I've reach to the conclusion that it can't see the element because the element is loaded dynamically.

The element is the class .newsitem_text, it's a div that contains a blog post. I believe that the jquery is calling for the class before the class is being loaded by the page.

Here is one example fiddle: http://jsfiddle.net/ku6L240c

The error: Uncaught TypeError: Cannot read property 'html' of null 47-ganhe-dinheiro-atraves-de-downloads:1093 Uncaught SyntaxError: Unexpected token ILLEGAL

The code:

<javascript>
            var wordList = $(".newsitem_text").html().split(' ');
            var newHtml = '';

            $.each(wordList, function(index, word){
              newHtml += ' ' + word;
              if (index == 50) {
                newHtml += '<div>Some HTML</div>'     
              }        
            })
            ;

            $(".newsitem_text").html(newHtml);


</javascript>

How can I make the script wait until the class is loaded by the page, then it gets executed or something?

Matheus Lopes
  • 315
  • 3
  • 14
  • Need more information for this. It's not clear what the error is or what this code interacts with. – Twisty Nov 04 '15 at 18:22
  • _How can I make the script wait until the class is loaded by the page_ -- Move your script to the bottom of the body block or wrap your script in `$(document).ready(function() { // your code })` – Jasen Nov 04 '15 at 18:26
  • Are you using `` tag in your real page? – fuyushimoya Nov 04 '15 at 18:28
  • The code is already at the bottom. the `` tag is there and this is the error I've got: `Uncaught TypeError: Cannot read property 'html' of null 47-ganhe-dinheiro-atraves-de-downloads:1093 Uncaught SyntaxError: Unexpected token ILLEGAL` – Matheus Lopes Nov 04 '15 at 19:09

3 Answers3

1

You can try to execute this function at window load or at document ready

just put ur function inside this:

$(window).load(function(){
    //your function here
});

or here

$(document).ready(function(){
  //your function here
});
1

Seems you are doing dynamic HTML within JS code and immediately trying to get the just added tags. If that is the case, your code will have to wait and keep checking until browser rendered your new HTML and add the nodes to DOM, then you can query them or do something about.

The only way I found works is usint setTimeOut and keep checking then execute your last statement. I create a function below that checks wait and check for certain condition then execute a call back function.

//A function to wait until either times up, or until a pass in "funct" returns "true", which ever occured first.
//funct - callback function, to be returned true or false.
//done - an optional callback function for notify when waiting is over.
//timeout - the amount of time in million-second to wait.
//caller - optional string of caller for monitoring if multiple waiting session.
function waitToSync(funct, done, timeout, caller) {
  //This is  a hack synchronize to wait until funct() returns true or timeout becomes < 0.
  caller = caller || '';
  if ((funct === undefined) || typeof (funct) != 'function') return;
  function waiting() {
    if (!funct()) {
      var dt = new Date();
      console.log(caller + " waiting: " + dt.format('yyyy-mm-dd h:MM:ss'));
      if ((timeout - 1000) > 0)
        setTimeout(waiting, 1000); //1 second.
      else {

        console.log(caller + ': waitToSync timed out!!!');
        document.body.style.cursor = 'default';
      }
      timeout -= 1000;
    }
    else {
      if (done !== undefined && (typeof done === 'function'))
        done();
    }
  }
  waiting();
}

Do all you dynamic or anything to want to wait. Then call the WaitToSync

 $.each(wordList, function(index, word){
     newHtml += ' ' + word;
     if (index == 50) {
        newHtml += '<div>Some HTML</div>'     
     }        
  });

  waitToSync(
     function wait() { return document.getElementsByClassName("newsitem_text").length > 0; }, 
     function dosomething() { $(".newsitem_text").html(newHtml); },
     10000, //wait up to 10 seconds.
     'dynamic add HTML');
Leng
  • 51
  • 3
  • Won't it depend on page load? Like conection speed? – Matheus Lopes Nov 04 '15 at 19:27
  • No. It just a setTimeout helper function. This function can be use when you are loading whole page dynamically too. The function solved a lot problem when dealing with synchronizing the nature of asynchronize in javascript. It doesn't block execution. – Leng Nov 04 '15 at 19:52
  • The "timeout" waiting time can be set to something big like 100000 for 10 minutes. It will wait for 10 minutes if no condition was met. It terminates the waiting function once a condition is met. funct() has return true. – Leng Nov 04 '15 at 20:00
  • `Uncaught ReferenceError: wordList is not defined(anonymous function) @ 47-ganhe-dinheiro-atraves-de-downloads:1303` http://lucrebem.com.br/blog/emponline/47-ganhe-dinheiro-atraves-de-downloads – Matheus Lopes Nov 04 '15 at 20:06
  • Solved the error, but the code is not working and now I don't get any errors at all. – Matheus Lopes Nov 04 '15 at 20:13
  • The problem may be in the first call back function passed to "waitToSync" where $(".newsitem_text") always return an array and will not be true ever. Instead change that to document.getElementByClass() or getElementById() should work. – Leng Nov 04 '15 at 20:25
  • No can do, look what I tried: `function getBannerafterwords(){ var wordList = document.getElementByClass(".newsitem_text").html().split(' ');` now I get no error whatsoever, but it's still not working. – Matheus Lopes Nov 04 '15 at 21:47
  • The error is generated from the second "dosomething" callback function? – Leng Nov 04 '15 at 23:46
  • What you need to do is call waitToSync at the beginning of your script code. Then do a call getBannerafterwords() and other operations inside the "dosomething" callback function. Even your script comes after you HTML code, it is not guarantee that those HTML nodes are available. Your script may be executed before DOM has a chance to render the HTML stuff. – Leng Nov 04 '15 at 23:58
  • Oops, duplicate deleted. – Leng Nov 04 '15 at 23:59
  • solved, just had to get the initial code that I posted and insert the function `jQuery(function($) { ` in the beginning, then closing the function after the code. – Matheus Lopes Nov 05 '15 at 01:21
0

It is way to better to put the code in the end of the body tag after all your content so javascript can run after everything is loaded !

Noctisdark
  • 350
  • 3
  • 17