0

Hi I have an issue with onclick events being writen using innerHTML I have tried doing it two ways and both have not work

the function it needs to call is

function loadnewsstory()
{
    alert("123456");
}

at the moment it should show the alert box with 123456 but it is not firing.

the function loading it is the following

function newsstories()
{
    document.getElementById("activecontent").innerHTML = "<h1 class='newsheader'>Latest News</h1>";

    xmlhttp=new XMLHttpRequest();
    xmlhttp.open("POST","test.com?uri=loadnews",false);
    xmlhttp.send();
    var newsreponse = JSON.parse(xmlhttp.responseText);

    var countstories = 0;
    for (var i = 0, len = newsreponse.length; i < len; ++i) {
     var news = newsreponse[i];
     if(i % 2 == 0){
       cssclass = "even";
     }
     else
     {
       cssclass = "odd";
     }

      //  alert(news.featured_image);
     document.getElementById("activecontent").innerHTML += "<div class='news " + cssclass + "'><div class='newstitle'><div class='newstitlecolor'><a href='#' onclick='loadnewsstory();'>" + news.post_title + "</a></div></div><div class='base' style='background: url('" + news.featured_image + "');'><img src='" + news.featured_image + "'  style='width:100%; height:100%;' id='news_"+ countstories +"'/></div></div>";


        document.getElementById("news_"+countstories).onclick = function(){ loadnewsstory();}


        countstories++;
    }
}

as you can see I have also ran document.getElementById("news_"+countstories).onclick = function(){ loadnewsstory();} because i read that onclick events could not be written by javascript innerHTML which I know I have been able to do before. If someone else knows of a fix to this issue that would be great. this is for a cordova iphone app

Thanks

EDIT

I have found that this

document.getElementById("activecontent").innerHTML += "<div class='news " + cssclass + "'><a href='javascript:openextlink();'><img src='" + news.featured_image + "'  style='width:100%; height:100%;'/></a></div>";

works but it seems to only work on the last news story, am I missing something.

RussellHarrower
  • 6,470
  • 21
  • 102
  • 204

3 Answers3

0

I suspect it's because your request is attempting to read/parse the response from the server too soon here:

xmlhttp.send();
var newsreponse = JSON.parse(xmlhttp.responseText);

Because this is an asyncronus (Ajax) request you need to give the script time to wait for the server to respond. You do this by creating an event handler that waits for the response.

xmlhttp.onreadystatechange=function() { // checks if the state of the request has changed
    if (xmlhttp.readyState==4 && xmlhttp.status==200) { // checks that the response is ready
        // code to handle the response here
        var newsreponse = JSON.parse(xmlhttp.responseText);
        // etc.
    }
}

Also note that you should create this handler before calling xmlhttp.send();

Matthew
  • 8,183
  • 10
  • 37
  • 65
  • changing to what you suggested has only not loaded the xmlhttp – RussellHarrower Oct 20 '13 at 12:42
  • also I don't see the reason for adding this code, as the json has been returning fine, and every thing else has been working, it is only when I want to add a link to each of the news articals – RussellHarrower Oct 20 '13 at 12:44
  • So all your links are there but onclick is not working. I see. I'm not sure then. – Matthew Oct 20 '13 at 12:52
  • I had more success with my script before adding this code, now it wont even run your code, sadly I cant debug it either due to iOS and cordova don't have a debugger built in – RussellHarrower Oct 20 '13 at 12:55
0

First of all, appending to innerHTML is usually very bad. If you run the code like something.innerHTML += 'lots of html' in a loop, browser has to update the DOM tree and re-render the page on every iteration. This may greatly slow down the things. Use the buffer string instead.

I also suspect that this might have caused issues with event attachment. Try attaching events after all the divs have been attached to the tree. The code in this case would be something like this:

function newsstories()
{
    // Use a variable that would store the newly generated HTML:
    var html = "<h1 class='newsheader'>Latest News</h1>";

    xmlhttp=new XMLHttpRequest();
    xmlhttp.open("POST","test.com?uri=loadnews",false);
    xmlhttp.send();
    var newsreponse = JSON.parse(xmlhttp.responseText);

    for (var i = 0, len = newsreponse.length; i < len; ++i) {
        var news = newsreponse[i];
        // Notice the 'var' keyword!
        if(i % 2 == 0){
            var cssclass = "even";
        } else {
            var cssclass = "odd";
        }

        // Append to our buffer variable
        html += "<div class='news " + cssclass + "'><div class='newstitle'><div class='newstitlecolor'><a href='#' onclick='loadnewsstory();'>" + news.post_title + "</a></div></div><div class='base' style='background: url('" + news.featured_image + "');'><img src='" + news.featured_image + "'  style='width:100%; height:100%;' id='news_"+ i +"'/></div></div>";
    }

    // Now that new html is ready, insert it into the tree
    // and attach events
    document.getElementById("activecontent").innerHTML = html;
    for (var i = 0, len = newsreponse.length; i < len; ++i) {
        var img = document.getElementById('news_'+i);
        if(img) img.addEventListener('click', loadnewsstory);
    }
}
Dmitry
  • 4,232
  • 2
  • 15
  • 13
  • I am starting to think that the issue maybe related to something totally separate, like the iOS, because even tho i have done everything you have said it still does not want to work. I know nothing code wise is wrong so I am scratching my head could the issue be iOS7 – RussellHarrower Oct 20 '13 at 21:30
  • I've just got an idea: what if we try to bind a `mousedown` event handler? I've read that `click` does not work in PhoneGap by default. You can read more [there](http://www.tricedesigns.com/2012/06/04/getting-rid-of-the-gray-box-in-phonegap-for-windows-phone/). – Dmitry Oct 21 '13 at 09:45
  • it was a CSS issue don't z-index:-1 that is what I did and it made this issue happen but thanks @Dmitry – RussellHarrower Oct 21 '13 at 10:35
0

it was due to z-index in my css that this was not working, I have fixed this by removing z-index:-1 and now all works fine, it is interesting that it was due to a css error that this bug come to alight

RussellHarrower
  • 6,470
  • 21
  • 102
  • 204