Simple Machines Community Forum

Customizing SMF => SMF Coding Discussion => Topic started by: Biology Forums on May 21, 2016, 01:33:19 PM

Title: Javascript loading issue, where's the problem?
Post by: Biology Forums on May 21, 2016, 01:33:19 PM
I have this great code that displays a greeting based... It's a very plug-in-play type of script, but the issue is, the greeting message loads AFTER the page has loaded, so it appears awkward having to wait for the greeting. What can I do to make it load first?

<script type="text/javascript">
/*<![CDATA[*/
function clock()
{
// Generate time
var time = new Date();
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();

// Add preceding 0s, if required
var hours = (hours < 10 ? \'0\' : \'\')+hours;
var minutes = (minutes < 10 ? \'0\' : \'\')+minutes;
var seconds = (seconds < 10 ? \'0\' : \'\')+seconds;

// Generate formated time
var time = hours+\':\'+minutes+\':\'+seconds;

// Get where abouts in the day it is
if(hours >= 6 && hours < 12)
{
var greeting = \'Good morning\';
}
else if(hours >= 12 && hours < 18)
{
var greeting = \'Good afternoon\';
}
else if(hours >= 18 && hours < 21)
{
var greeting = \'Good evening\';
}
else
{
var greeting = \'Hello\';
}

// Display Greeting
document.getElementById(\'clock\').innerHTML = greeting;

//document.getElementById(\'clock\').innerHTML = time+\'<br />\'+greeting;
}
//init clock
window.onload = function()
{
clock();
setInterval(\'clock()\', 1000);
}
/*]]>*/
</script>
<span id="clock"></span>


I believe the problem lies here:

window.onload = function()
Title: Re: Javascript loading issue, where's the problem?
Post by: nend on May 21, 2016, 02:59:57 PM
Just put the JavaScript below the container and remove the onLoad function.

This //init clock
window.onload = function()
{
clock();
setInterval(\'clock()\', 1000);
}

To
//init clock
clock();
setInterval(\'clock()\', 1000);
Title: Re: Javascript loading issue, where's the problem?
Post by: Biology Forums on May 24, 2016, 01:51:10 PM
I tried what you recommended, and nothing showed up :(
Title: Re: Javascript loading issue, where's the problem?
Post by: Wellwisher on May 27, 2016, 12:56:04 AM
window.onload = function()

Is not the problem, all that's telling the browser is once html loads, execute the script. It's responsible for triggering the entire script, without a trigger, your script will not load (as you've found out using Nends code).

The problem is how you've set-up the script and @Nend is partially correct.

Here's how you should set up the script:



<script>
function clock()
{
// Generate time
var time = new Date();
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();
setInterval(\'clock()\', 1000);

// Add preceding 0s, if required
var hours = (hours < 10 ? \'0\' : \'\')+hours;
var minutes = (minutes < 10 ? \'0\' : \'\')+minutes;
var seconds = (seconds < 10 ? \'0\' : \'\')+seconds;

// Generate formated time
var time = hours+\':\'+minutes+\':\'+seconds;

// Get where abouts in the day it is
if(hours >= 6 && hours < 12)
{
var greeting = \'Good morning\';
}
else if(hours >= 12 && hours < 18)
{
var greeting = \'Good afternoon\';
}
else if(hours >= 18 && hours < 21)
{
var greeting = \'Good evening\';
}
else
{
var greeting = \'Hello\';
}

// Display Greeting
document.getElementById(\'clock\').innerHTML = greeting;

//document.getElementById(\'clock\').innerHTML = time+\'<br />\'+greeting;
}
</script>



Now you need to trigger this code and this is how to do it:



<span id="clock" onload="clock();"></span>



Make sure you add the script before the opening <span> tag otherwise it will not work.

Title: Re: Javascript loading issue, where's the problem?
Post by: nend on May 27, 2016, 01:19:30 AM
Yeah JavaScript needs a trigger, my mistake there.

@Wellwisher, the code you suggested with the span doesn't solve the problem as it just replicates the onLoad event in a tag. ;)

I don't see any optimal solution, I do have one but it would be bad SEO wise, render blocking JavaScript.

It may be best to do this server side. ;)

Sorry can't be much assistant here, no computer access.
Title: Re: Javascript loading issue, where's the problem?
Post by: Wellwisher on May 27, 2016, 01:40:11 AM
@Nend, that's an overkill man. Your two choices are:

a. wait for the entire webpage to load
b. wait for that one element to load

Now you buzz-in and tell me which will be the quickest?  :P You can have multiple onloads and it's not a problem. JS based sites use them the most. Pinterest being a good example, also many major e-com sites rely on using them and they'd use dozens.  ;D

"Onloads" basically tell Mr.Browser, once something "loads", do something.
Title: Re: Javascript loading issue, where's the problem?
Post by: nend on May 27, 2016, 08:01:43 AM
Quote from: Wellwisher on May 27, 2016, 01:40:11 AM
@Nend, that's an overkill man. Your two choices are:

a. wait for the entire webpage to load
b. wait for that one element to load

Let me quote the author.

Quote from: Stylus on May 21, 2016, 01:33:19 PM
.What can I do to make it load first?

HTML standard for onLoad.
QuoteSupported HTML tags:   <body>, <frame>, <iframe>, <img>, <input type="image">, <link>, <script>, <style>

Doing this server side isn't overkill. Unless you have a hamster powered box, until January 2038 I don't see this as an issue.
Title: Re: Javascript loading issue, where's the problem?
Post by: Biology Forums on May 27, 2016, 03:02:46 PM
You can do server-side but there's no simple way of obtaining the user's current time zone. Server side uses the server's time zone, so someone in Australia will read good morning when it's midnight, given that the server is in North America
Title: Re: Javascript loading issue, where's the problem?
Post by: Arantor on May 27, 2016, 06:10:17 PM
But you know the user's time offset... if they set it.
Title: Re: Javascript loading issue, where's the problem?
Post by: Wellwisher on May 27, 2016, 06:50:46 PM
Quote from: nend on May 27, 2016, 08:01:43 AM

HTML standard for onLoad.
Supported HTML tags:   <body>, <frame>, <iframe>, <img>, <input type="image">, <link>, <script>, <style>


Well I'll be damned, @Nend. This is weird and interesting. So check this: I ran some tests on the lastest browser versions of firefox and chrome.
If I use the mark-up @Stylus provided on my production site, I see a delayed greeting. Now if I use my own mark-up (be it not html standard), I see the result during the page load and see the greeting instantly. I have no idea why it's working, but it's working folks.
I also have jquery running, maybe that's doing some weird voodoo? Tbh, I am a little confused why my mark-up works.  ???
Title: Re: Javascript loading issue, where's the problem?
Post by: Biology Forums on May 30, 2016, 01:38:05 AM
Wellwisher, I put your code before the <body> and it didn't show anything. Is it possible you made a mistake?
Title: Re: Javascript loading issue, where's the problem?
Post by: Wellwisher on May 30, 2016, 08:55:41 PM
Quote from: Stylus on May 30, 2016, 01:38:05 AM
Wellwisher, I put your code before the <body> and it didn't show anything. Is it possible you made a mistake?

That's interesting, it was working when I was testing it. Did you add the script in the head tag?

The following code, you need to place where you want the greeting to show up:

<span id="clock" onload="clock();"></span>

Try that and let me know.
Title: Re: Javascript loading issue, where's the problem?
Post by: leghorn23 on May 31, 2016, 12:29:47 PM
You are indeed correct. The window.onload part is unnecessary since those lines come after the actual code you're running. Remove the function and just run the things within that and you're good to go.
Title: Re: Javascript loading issue, where's the problem?
Post by: Biology Forums on May 31, 2016, 05:03:29 PM
Just tested it again and it did not work, nothing appears.
Title: Re: Javascript loading issue, where's the problem?
Post by: SychO on June 01, 2016, 08:06:30 AM
did you load jquery ?
Title: Re: Javascript loading issue, where's the problem?
Post by: Chris68 on June 01, 2016, 09:37:06 AM
does span element have a onload event ?
According to w3schools.com <body>, <frame>, <iframe>, <img>, <input type="image">, <link>, <script>, <style> can fire such on event.

Have a try with <img id="clock" onload="clock();" /> to test this reason.
Title: Re: Javascript loading issue, where's the problem?
Post by: Wellwisher on June 01, 2016, 12:33:37 PM
My apologies. This is one of those days... sooooo I remember getting it working. I remember testing the script, it was loading first and displaying the greeting without a problem. Today, I re-ran the code I gave you above and the greeting (as you mentioned @Stylus) is not displaying.  ;D

I made a jsfiddle to prove it works but once I add this to my production and escape the script using "back-slash", it won't display the darn greeting.

https://jsfiddle.net/9155q0w6/4/

I have a feeling I am missing something really small and stupid which is preventing it to display. Anyway have a look at the jsfiddle, hopefully one of you nerds can figure out this cursed script.  :P I love the puzzle though.
Title: Re: Javascript loading issue, where's the problem?
Post by: Biology Forums on June 01, 2016, 07:38:06 PM
See, I'm not crazy ;)
Title: Re: Javascript loading issue, where's the problem?
Post by: Wellwisher on June 02, 2016, 01:05:46 AM
Quote from: Stylus on June 01, 2016, 07:38:06 PM
See, I'm not crazy ;)

@Stylus never said you were mate.  :P Ok so fingers crossed, try the following code. Treat it like "one snippet", add it where you want the greeting to show up. I made a div tag and put the script inside it but if you want to put it in a span tag, that should also work.

In this unorthodox method, we can be sure the html element is loaded first, and the next item to load is the script itself. This rules out any conflicts and things should work:



<div id="clock" onload="clock()">
<script>
function clock()
{
// Generate time
var time = new Date();
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();

// Add preceding 0s, if required
var hours = (hours < 10 ? \'0\' : \'\')+hours;
var minutes = (minutes < 10 ? \'0\' : \'\')+minutes;
var seconds = (seconds < 10 ? \'0\' : \'\')+seconds;

// Generate formated time
var time = hours+\':\'+minutes+\':\'+seconds;

// Get where abouts in the day it is
if(hours >= 6 && hours < 12)
{
var greeting = \'Good morning\';
}
else if(hours >= 12 && hours < 18)
{
var greeting = \'Good afternoon\';
}
else if(hours >= 18 && hours < 21)
{
var greeting = \'Good evening\';
}
else
{
var greeting = \'Hello\';
}

// Display Greeting
document.getElementById(\'clock\').innerHTML = greeting;

//document.getElementById(\'clock\').innerHTML = time+\'<br />\'+greeting;
}
//init clock

{
clock();
setInterval(\'clock()\', 1000);
}
</script>
</div>

Title: Re: Javascript loading issue, where's the problem?
Post by: nend on June 02, 2016, 01:27:07 AM
Quote from: Wellwisher on June 02, 2016, 01:05:46 AM
In this unorthodox method, we can be sure the html element is loaded first, and the next item to load is the script itself. This rules out any conflicts and things should work:

Quote from: nend on May 21, 2016, 02:59:57 PM
Just put the JavaScript below the container and remove the onLoad function.

This //init clock
window.onload = function()
{
clock();
setInterval(\'clock()\', 1000);
}

To
//init clock
clock();
setInterval(\'clock()\', 1000);

Sounds familiar.  ::)
Title: Re: Javascript loading issue, where's the problem?
Post by: Wellwisher on June 02, 2016, 01:54:07 AM
Quote from: nend on June 02, 2016, 01:27:07 AM
Sounds familiar.  ::)

I said you were partly right. :P Still, it feels like this script has a mind of its own. I feel spooked by it now. :laugh:
Title: Re: Javascript loading issue, where's the problem?
Post by: Biology Forums on June 02, 2016, 12:41:36 PM
It works now, great!

Thanks all for helping
Title: Re: Javascript loading issue, where's the problem?
Post by: leghorn23 on August 18, 2016, 03:15:49 AM
Quote from: nend on June 02, 2016, 01:27:07 AM
Quote from: Wellwisher on June 02, 2016, 01:05:46 AM
In this unorthodox method, we can be sure the html element is loaded first, and the next item to load is the script itself. This rules out any conflicts and things should work:

Quote from: nend on May 21, 2016, 02:59:57 PM
Just put the JavaScript below the container and remove the onLoad function.

This //init clock
window.onload = function()
{
clock();
setInterval(\'clock()\', 1000);
}

To
//init clock
clock();
setInterval(\'clock()\', 1000);

Sounds familiar.  ::)

This could potentially introduce a race condition. Running code within a timeout should be a last resort IMO
Title: Re: Javascript loading issue, where's the problem?
Post by: Biology Forums on August 18, 2016, 11:17:52 AM
How would you change it
Title: Re: Javascript loading issue, where's the problem?
Post by: leghorn23 on August 19, 2016, 11:47:50 AM
You simply need to place the Javascript after the block that its adding the content to. This is because Javascript is referencing that div, so if it doesn't exist yet it will throw an error

Try this:


<span id="clock"></span>
<script type="text/javascript">
/*<![CDATA[*/
function clock()
{
// Generate time
var time = new Date();
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();

// Add preceding 0s, if required
var hours = (hours < 10 ? \'0\' : \'\')+hours;
var minutes = (minutes < 10 ? \'0\' : \'\')+minutes;
var seconds = (seconds < 10 ? \'0\' : \'\')+seconds;

// Generate formated time
var time = hours+\':\'+minutes+\':\'+seconds;

// Get where abouts in the day it is
if(hours >= 6 && hours < 12)
{
var greeting = \'Good morning\';
}
else if(hours >= 12 && hours < 18)
{
var greeting = \'Good afternoon\';
}
else if(hours >= 18 && hours < 21)
{
var greeting = \'Good evening\';
}
else
{
var greeting = \'Hello\';
}

// Display Greeting
document.getElementById(\'clock\').innerHTML = greeting;

//document.getElementById(\'clock\').innerHTML = time+\'<br />\'+greeting;
}

clock();
/*]]>*/
</script>
Title: Re: Javascript loading issue, where's the problem?
Post by: nend on August 19, 2016, 03:18:55 PM
Quote from: leghorn23 on August 19, 2016, 11:47:50 AM
You simply need to place the Javascript after the block that its adding the content to. This is because Javascript is referencing that div, so if it doesn't exist yet it will throw an error

Quote from: nend on May 21, 2016, 02:59:57 PM
Just put the JavaScript below the container and remove the onLoad function.