Click for Ancient Greek verb online quizzes
In 2011, I wrote 17 Flash pages for testing users’ knowledge of Ancient Greek verbs.
Unfortunately, Adobe’s support for Flash is slated to conclude at the end of 2020, and browser support will end at the same time as well.
In anticipation of Flash’s obsolescence, I have begun re-writing these Flash pages in JavaScript for Ancient Greek Keyboard.
The entry page for these tests was by-and-large completed in January of 2019, with a few minor changes made in February & March. The HTML & CSS on the entry page utilizes responsive design, and looks very similar to the old Flash page.
Once the entry page was finished, work began on the first quiz (for the verb-endings for Ancient Greek Present Active Indicative verbs). A working copy was completed on February 27th, but refinements continued to be made up to March 11th. (A request was made to Google to index the page on March 2nd, and the request granted on March 3rd).
A few difficulties arose in converting the quiz page to JavaScript. These were as follows:
1) Global variables vs. local variables
For a while, there was an issue with local variables that should have been global (ie: populated arrays were being returned as “undefined”). This was resolved by declaring the variables outside of the functions at the beginning of the first <script>
tag.
2) Grammar review table
Initially, the vertical Grammar Review button opened up the grammar review table using JavaScript. However, there were 3 identical tables placed in the HTML, which added unnecessarily to the length of the file.
JavaScript code was found to generate this table into divs on the fly. See the link for further details.
3) Animated GIFs
Flash allows developers to export animations as GIFs rather than SWFs, so I attempted to export 3 SWF animations as GIFs. Unfortunately, only one of the three animations (the frowning Medusa) was successfully exported by this method.
One other animation (the winking Owl) was successfully exported using the Thundersoft SWF to GIF converter. However, the third animation (spinning “Self-Test” text) could not be recovered by either method.
With two of the three animations recovered as animated GIFs, a further problem occurred in which the animations would only play a single time rather than whenever they were called as background images with the following code:
document.getElementById("my-div").style.backgroundImage = "url(images/my-animated-file.gif)";
This was resolved by reloading “my-animated-file.gif” with a random hash based on the date & time. While the concept sounded easy enough, it took some searching to find the correct syntax:
document.getElementById("my-div").style.backgroundImage = "url('images/my-animated-file.gif" + "?" + (new Date()).getTime() + "')";
(From the above, it can be seen that a key part of getting this to work lies in getting all the single and double quotation marks right!)
4) Vertical button
Vertical buttons are easy to make in Flash, and the vertical button for the Present Active Indicative Verb Ending Page was exported as a PNG for use as background image button.
However, I decided that doing this would be too cumbersome for all 17 quizzes. To wit: For each button, I might have to change the text in Flash for the Link, Hover and Active state. Then, the PNG images of the Link, Hover & Active states of the button would have to be exported. Next, the images would have to be cropped with Photoshop, renamed, and moved to the proper image folder. And finally, the background images would have to be referenced correctly on the page’s internal stylesheet.
After all of this, the text on the vertical background image button still wouldn’t be crawlable by the search engines.
A better solution was to create vertical text with the <svg>
tag. I believe that the linear gradient was generated using the online tool provided by CSS3factory.com.
UPDATE (Mar 13, 2019): Added OG meta tags for Facebook for the Present Active Indicative Verb Test page. Added Twitter meta tags as well.
Also fixed Statcounter code for the page. Did this by logging into StatCounter.com and clicking on settings beside the project (the gear icon). Then, clicked “Reinstall Code” and the large blue “Continue to Default Installation” button. Finally, copied & pasted the HTML and JavaScript code before the end of the page’s </body>
tag.
UPDATE (Mar 15, 2019): Added social media like & share buttons to the quiz page.
Initially planned to add them beneath the <h1>
tag, but found that they changed the desktop layout too much (and were somewhat distracting as well). Therefore, they’ve been added below the main content, before the first Greek meander divider.
Facebook Like & Share button code was generated by the Facebook for Developers page. The code consists of two sections:
1) Immediately following the <body>
tag:
<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.2"></script>
2) Button code (for small button with counter showing number of FB Likes, but not displaying people’s FB profile pictures):
<div class="fb-like" data-href="https://my-url-here.html" data-layout="button_count" data-action="like" data-size="small" data-show-faces="false" data-share="true"></div>
The Twitter Share button code was generated by the Twitter Publish page after clicking on the “Twitter Buttons” icon. The code does not require the URL of the page, and is as follows:
<a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-show-count="false">Tweet</a><script async src="https://platform.twitter.com/widgets.js" ></script>
The LinkedIn Share button code was written according to directions given by ChillyFacts.com. The code is as follows:
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https://my-URL-here.html &title=My%20Web%20Page%20Title&summary=mywebsite.com&source=My%20Website%20Name" id="linkedin-share-button" onclick="window.open(this.href, 'mywin',
'left=20, top=20, width=500, height=500, toolbar=1, resizable=0'); return false;" ><img src="https://my-URL-for-my-LinkedIn-button.gif" alt="" width="54" height="20" /></a>
(On my page, I’ve commented out the <img>
tag & used background images for the <a>
tag instead. This allow a different image to be presented for the HOVER state.)
The Pinterest Share button code was written according to instructions from BrandAidDesignCo.com. This code does not require the URL of the page, and is as follows:
<a href='javascript:void((function()%7Bvar%20e=document.createElement('script');e.setAttribute('type','text/javascript');e.setAttribute('charset','UTF-8');e.setAttribute('src','https://assets.pinterest.com/js/pinmarklet.js?r='+Math.random()*99999999);document.body.appendChild(e)%7D)());' id="pinterest-pin-it-button"><img src='https://my-URL-for-my-Pinterest-button.png'/></a>>
As with the LinkedIn Share button, I’ve commented out the <img>
tag & used background images for the <a>
tag instead. This allows a different image to be presented for the HOVER state.
Note also that I had to change http://assets.pinterest.com/js/pinmarklet.js
to:https://assets.pinterest.com/js/pinmarklet.js
for BrandAidDesignCo’s code to work correctly. (Possibly because my site uses HTTPS instead of HTTP).
UPDATE (Mar 16, 2019): Discovered that the HOVER and ACTIVE states for the NEXT button weren’t being displayed on cell phones. The same was true when the user tried to tap one of the multiple choice options on a cell phone as well.
After 4 or 5 hours, I discovered the problem was that the JavaScript was initiating too quickly for these states to be observable. The solution was to set a 400 ms pause in JavaScript initiation for the NEXT button HOVER / ACTIVE state to be visible, and a 150 ms pause for the multiple choice options.
The HTML code for this was as follows:
<img src="my-relative-URL-for-the-NEXT-button.png" onclick="myFunction()" />
While the JavaScript called when this image button is clicked is:
function myFunction() { //CHECK IF USER IS USING MOBILE (IE: SCREEN WIDTH LESS THAN 768PX) if (window.screen.availWidth lt; 768) { //PAUSE REQUIRED FOR MOBILE. (SET A 400 MS PAUSE BEFORE CALLING THE NEXT FUNCTION) setTimeout( function() { myNextFunction(); }, 400); } //NO PAUSE REQUIRED FOR DESKTOP (IMMEDIATELY CALL THE NEXT FUNCTION) else { myNextFunction(); } } function myNextFunction() { //REQUIRED CODE GOES HERE }
UPDATE (Mar 17, 2019): Upon further consideration, have decided to give the user radio buttons allowing him to turn the animated GIFs off.
This was because in order to get the animations to play from the start, the animated gifs need to be reloaded each time with a random hash. A cell phone user could find himself using a very large amount of bandwidth if he used the page regularly.
Consider: the animated owl is 182 kB in size, so a user who got 10 answers right in a single session would use 1.82 MB. If he did this for 30 days straight, he’d consume about 55 MB.
If instead this cell phone user turned off the animations, he’d only load the static owl image once regardless of how many answers he answered correctly, consuming only 6.15 kB per session. Over 30 days, he’d only use 0.184 MB.
The HTML for the radio buttons:
<form> <fieldset> <legend><i>Enable animation?</i></legend> <input type="radio" name="animatedGIFs" id="animation_yes" value="animationEnabled" checked="checked" /> <label for="animation_yes">Yes</label> <br /> <input type="radio" name="animatedGIFs" id="animation_no" value="animationDisabled" /> <label for="animation_no">No</label> </fieldset> </form>
And the JavaScript code for receiving the radio button data is as follows:
//SET GLOBAL VARIABLE AS A FLAG (ASSUME USER WANTS ANIMATIONS) var useAnimatedGIFs = true; function checkRadioButtonForAnimation() { // FIRST, SEE IF THE USER HAS CHECKED THE ID OF THE RADIO BUTTON ("animation_no") SAYING HE DOESN'T WANT ANIMATION) if(document.getElementById('animation_no').checked) { //CHANGE THE FLAG TO "false" IF THE USER DIDN'T WANT ANIMATION useAnimatedGIFs = false; } // (OTHERWISE, useAnimatedGIFs REMAINS "true") [...] function laterFunction() { //THE STRING FOR THE IMAGE TO BE DISPLAYED FOR CORRECT ANSWERS var rightBackgroundImageStr; // IF THE USER WANTED ANIMATION, LOAD THE ANIMATED GIFS WITH NUMERICAL HASHES if(useAnimatedGIFs === true) { rightBackgroundImageStr = "url('relative-URL-path-to-animated-image.gif" + "?" + (new Date()).getTime() + "')"; } //IF THE USER DOESN'T WANT ANIMATION, LOAD STATIC GIF INSTEAD else { rightBackgroundImageStr = "url('relative-URL-path-to-static-image.gif"; } [...] //IF THE USER ANSWERED CORRECTLY, DISPLAY A CERTAIN IMAGE if (chosenAnswer === correctAnswer { /DISPLAYS THE ANIMATED OR STATIC IMAGE (DEPENDING ON USER'S RADIO BUTTON CHOICE) document.getElementById("background-image-div").style.backgroundImage = rightBackgroundImageStr; } //IF THE USER ANSWERED INCORRECTLY, DISPLAY A DIFFERENT IMAGE else { //CODE TO DISPLAY THE DIFFERENT IMAGE } }
(For people with data plans of 2 GB per month or more, this is probably not a major concern. But for those like myself with 500 MB per month plans, it could be an important consideration.)