doubleJ
doubleJ

Reputation: 1216

Javascript - document.write() is working but document.innerHTML isn't

I have a page with a javascript countdown. The countdown is working, just fine, but, when it reaches the countdown time, it starts counting backwards. It should change the content of #nextinternetbroadcast. It does change the content, if I use document.write(), but it overwrites the page (so I know the if is working). For some reason, it simply is ignoring the clearTimeout() and innerHTML portion.

HTML (edited for terseness):

<div id="nextinternetbroadcast" class="link"></div>
<!-- page specific javascripts -->
<script>
// set a global javascript variable
var nextlivebroadcast;
// tell the function where the JSON data is
fetchJSONFile('http://www.flcbranson.org/api/livebroadcast', function(data){
    // do something with your data
    // alert(JSON.stringify(data));
    // alert(data.datetime + ', ' + data.status);
    nextlivebroadcast = data.nextbroadcast;
});
// see if the global variable is still set (would say "undefined" if using an asychronous connection)
//alert(nextlivebroadcast);

// live broadcast countdown
cdtd(nextlivebroadcast);
</script>

JavaScript (edited for terseness):

// generic get JSON data function
function fetchJSONFile(path, callback) {
    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState === 4) {
            if (httpRequest.status === 200) {
                var data = JSON.parse(httpRequest.responseText);
                if (callback) callback(data);
            }
        }
    };
    // false tells it to be synchronous instead of asynchronous
    httpRequest.open('GET', path, false);
    httpRequest.send(); 
}

// start javascript countdown (http://www.developphp.com/view.php?tid=1248)
// don't forget to pass the broadcast variable
function cdtd(broadcast) {
    // just about any standard date format is accepted
    var nextinternetbroadcast = new Date(broadcast);
    var now = new Date();
    var timeDiff = nextinternetbroadcast.getTime() - now.getTime();
    if (timeDiff <= 0) {
        clearTimeout(timer);
        document.getElementById('nextinternetbroadcast').innerHTML = '<a href="javscript:openVideo(' + livepublishingpoint + ');">Join live service now<\/a>';
        // document.innerHTML isn't working but document.write is (but it overwrites the whole page)
        //document.write('Something');
    }
    var seconds = Math.floor(timeDiff / 1000);
    var minutes = Math.floor(seconds / 60);
    var hours = Math.floor(minutes / 60);
    var days = Math.floor(hours / 24);
    hours %= 24;
    minutes %= 60;
    seconds %= 60;
    document.getElementById('nextinternetbroadcast').className += " disabled";
    document.getElementById('nextinternetbroadcast').innerHTML = '<span class="days">' + days + '</span><span class="hours">' + hours + '</span><span class="minutes">' + minutes + '</span><span class="seconds">' + seconds + '</span>';
    // loop the function every second
    var timer = setTimeout(function() { cdtd(broadcast); }, 1000);
}

Am I doing something incorrectly? I, certainly, am not seeing it.

Edit (showing the fix in the JavaScript - thanks to Bergi)...

// start javascript countdown (http://www.developphp.com/view.php?tid=1248)
// don't forget to pass the broadcast variable
function cdtd(broadcast) {
    // just about any standard date format is accepted
    var nextinternetbroadcast = new Date(broadcast);
    var now = new Date();
    var timeDiff = nextinternetbroadcast.getTime() - now.getTime();
    if (timeDiff <= 0) {
        document.getElementById('nextinternetbroadcast').innerHTML = '<a href="javscript:openVideo(' + livepublishingpoint + ');">Join live service now<\/a>';
        // document.innerHTML isn't working but document.write is (but it overwrites the whole page)
        //document.write('Something');
    } else {
        var seconds = Math.floor(timeDiff / 1000);
        var minutes = Math.floor(seconds / 60);
        var hours = Math.floor(minutes / 60);
        var days = Math.floor(hours / 24);
        hours %= 24;
        minutes %= 60;
        seconds %= 60;
        document.getElementById('nextinternetbroadcast').className += " disabled";
        document.getElementById('nextinternetbroadcast').innerHTML = '<span class="days">' + days + '</span><span class="hours">' + hours + '</span><span class="minutes">' + minutes + '</span><span class="seconds">' + seconds + '</span>';
        // loop the function every second
        setTimeout(function() { cdtd(broadcast); }, 1000);
    }
}

Upvotes: 0

Views: 288

Answers (1)

Bergi
Bergi

Reputation: 664620

Am I doing something incorrectly?

Yes, your timer logic is flawed. Currently you're doing

function fn() {
    if (/* no time left*/) {
        clearTimeout(timer);
        // show end message
    }
    // show countdown
    var timer = setTimeout(fn, 1000);
}

You're trying to clear the timer before you've started it. And actually you don't have to do that at all, since at that time no timer is running. What you have to do instead is ensure that the timer is not restarted. So change the logic to

function fn() {
    if (/* no time left*/) {
        // show end message
    } else {
        // show countdown
        setTimeout(fn, 1000);
    }
}

Of course that doesn't really explain why your innerHTML assignment is not working (unless the flawed timer-cancelling led to some exception).

Upvotes: 1

Related Questions