0

I am not sure why, but the following stops my JavaScript from working.

I know it is not best practice to do this, But I have no idea where it is breaking.

JavaScript:

function loadmore(id) {
    var xmlhttp;
    if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else { // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            var content;
            var x = JSON.parse(xmlhttp.responseText);
            alert('' + x.length);
            for (i = 0; i < x.length; i++) {
                document.getElementById("content").innerHTML += '<div class="col-lg-4 col-md-4 col-sm-4">';
                document.getElementById("content").innerHTML += '<div class="thumbnail">'
                document.getElementById("content").innerHTML += '<img src="' + x[i].main_image + '" alt="' + x[i].title + '" style="width:300px !important; height:150px; overflow:none;">';
                document.getElementById("content").innerHTML += '<div class="caption">';
                document.getElementById("content").innerHTML += '<h3>' + x[i].title + '</h3>';
                document.getElementById("content").innerHTML += '<p>' + x[i].content;
                document.getElementById("content").innerHTML += '</p>';
                document.getElementById("content").innerHTML += '<p><a href="//russellharrower.com/' + x[i].url + '" class="btn btn-default" role="button">Read More</a></p>'
                document.getElementById("content").innerHTML += '</div>';
                document.getElementById("content").innerHTML += '</div>';
                document.getElementById("content").innerHTML += '</div>';


                id = x._id;
                //document.getElementById("content").innerHTML+=content;

            }
        }
    }


    //xmlhttp.responseText
    xmlhttp.open("GET", "search/json&qid=" + id, true);
    xmlhttp.send();

}
halfer
  • 19,824
  • 17
  • 99
  • 186
RussellHarrower
  • 6,470
  • 21
  • 102
  • 204
  • Ok, ignoring the code style... what error are you getting? – Damb Dec 04 '14 at 13:19
  • what error are you getting ? – Nad Dec 04 '14 at 13:19
  • 2
    Not really an answer but you should take a look at [why innerHTML should be avoided](http://stackoverflow.com/questions/18502238/why-is-it-suggested-to-avoid-innerhtml). More related to the question: Which errors are appearing in your developer tools? And by the way, this would probably be much _easier for you_ if you'd be using jQuery, like you tagged the question as additionally to raw javascript. – Jonast92 Dec 04 '14 at 13:19
  • 1
    @Dhaval js has asi, that semicolon wont make a difference. – Banana Dec 04 '14 at 13:23
  • can you post your json? Please do something like that; console.log(x) – Manu Zi Dec 04 '14 at 13:25
  • You can not do "" with innerHTML! You are not building a string. – epascarello Dec 04 '14 at 13:30
  • It seems your code works as long as you have correspondant json – asdf_enel_hak Dec 04 '14 at 13:40
  • Russell, are you able to accept one of the answers below? – halfer Oct 05 '17 at 20:19

2 Answers2

2

As a general rule, the correct order of operations is:

  1. new XMLHttpRequest
  2. .open()
  3. .onreadystatechange =
  4. .send()

In some browsers, especially those that allow re-using the same object for multiple requests, calling .open() will clear your .onreadystatechange handler.

As an additional note, please DO NOT mix .innerHTML and +=. Here's how the browser sees it:

document.getElementById("content").innerHTML += '<div class="col-lg-4 col-md-4 col-sm-4">';

Oh, there's a missing end tag, better add that in. </div> added automatically.

document.getElementById("content").innerHTML += '<div class="thumbnail">'

Oh, there's a missing end tag, better add that in. </div> added automatically.

document.getElementById("content").innerHTML += '<img src="' + x[i].main_image + '" alt="' + x[i].title + '" style="width:300px !important; height:150px; overflow:none;">';

Okay, added an image. Note that we are not inside the <div><div> you expect!

document.getElementById("content").innerHTML += '<div class="caption">';

Oh, there's a missing end tag, better add that in. </div> added automatically.

document.getElementById("content").innerHTML += '<h3>' + x[i].title + '</h3>';

Okay, added the <h3>. Still not in the <div><div><div> you think!

document.getElementById("content").innerHTML += '<p>' + x[i].content;

Missing </p> tag, need to add that in.

document.getElementById("content").innerHTML += '</p>';

There was no <p> here... better add one to make this </p> valid. Empty paragraph added.

document.getElementById("content").innerHTML += '<p><a href="//russellharrower.com/' + x[i].url + '" class="btn btn-default" role="button">Read More</a></p>'

Okay, paragraph with link added.

document.getElementById("content").innerHTML += '</div>';

Ah! I didn't have an open <div>! Better add one. Empty <div> added. (repeat x3)

Can you see how this step-by-step approach is leading to issues because it keeps on thinking that you're done and correcting your "bad" HTML accordingly?

Community
  • 1
  • 1
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
1

There are several minor changes that can be made to simplify this. Try ...

var content = document.getElementById("content");
var build_html = [
  "<div>",
  "Content Here",
  "</div>"
  ].join("\n");
content.innerHTML = build_html;

Obviously, your HTML content is more robust than what I have here, but with this you aren't slamming the DOM over and over.

rfornal
  • 5,072
  • 5
  • 30
  • 42
  • In short, `innerHTML` and `+=` do *not* mix. – Niet the Dark Absol Dec 04 '14 at 13:22
  • I would certainly agree with that ... I'm not 100% sure they don't mix technically, but it is definitely a bad practice at best. – rfornal Dec 04 '14 at 13:23
  • 2
    They do not mix technically. Every time you read from `innerHTML` it serialises the DOM to HTML. So you cannot write partial elements as the code in the question is trying to do. – Quentin Dec 04 '14 at 13:25