Tabular Single Row Radio Play Tutorial

Tabular Single Row Radio Play Tutorial

Tabular Single Row Radio Play Tutorial

We do not expect many readers to have thought yesterday’s YouTube Audio Only Mobile Looping Tutorial that little bit different. It was long in the making, and difficult (at least for us), but a brief tutorial. Too brief for interested parties, and we intended it as a seminal discussion, but it’s meaning got subsumed, if you will, with the goings on of the blog posting thread last talked about with the day before’s Tabular Single Row Image Gallery Linking Tutorial.

You see, the YouTube audio stream only inhouse looping control is an essential thing we needed to tie down for today’s progress in this blog posting thread, that being the first incarnation of …

Radio Play

… sequenced modes of play we’re offering today, as a start, for …

  • non-mobile users
  • using audio stream only button option clicks

So what was (most) …

difficult (at least for us)

… about getting this first Radio Play idea happening? In a word …

Focus

You find yourself wanting to do lots of …


[element].click();

… and …


[element].blur();

… types of work, which work best with focus (and boy, did we need to “focus”?!) We’ve minimised this where we could, but what we highly recommend users of this functionality doing is …

  • be presented with the solo web browser full screen (initial) window with the radio emoji
  • click desired first song link when the song link emojis appear … then …
  • it’s best to make this window small and away from other web browser windows but not overlapping for the best chance of …
  • songs play in sequence and loop back through the list

… within changed swipe_media.html Tabular Single Row Media Gallery helped out by ytaudioonly.js external Javascript helper.


Previous relevant Tabular Single Row Image Gallery Linking Tutorial is shown below.

Tabular Single Row Image Gallery Linking Tutorial

Tabular Single Row Image Gallery Linking Tutorial

After yesterday’s Tabular Single Row YouTube Audio or Video Buttons Tutorial work mainly regarding audio and video media, today we return to those …

  • background WordPress Blog random tutorial images … and link them via a modified 404.php creator’s …
    <?php

    if (strpos(('?' . $_SERVER['QUERY_STRING']), '?rand=') !== false) {
    $huht=@file_get_contents('http://www.rjmprogramming.com.au/HTMLCSS/select_palette.php?putrandom=' . urlencode('?rand=' . $_GET['rand'] . '.' . $pnumis . $ptitle));
    }

    ?>
    … calling on …
  • a modified select_palette.php helper …
    <?php

    if (isset($_GET['putrandom'])) {
    $contis=str_replace(' ','++',str_replace('+',' ',urldecode($_GET['putrandom']))) . "\n";
    $xcurgmt=gmdate("Ymd");
    if (!file_exists($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm')) {
    foreach (glob($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . '*.htm') as $dfilename) {
    unlink($dfilename);
    }
    file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm', $contis);
    } else {
    file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm', file_get_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm') . $contis);
    }
    exit;
    } else if (isset($_GET['getrandom'])) {
    $xcurgmt=gmdate("Ymd");
    $imode=0;
    $contis="";
    $idp="";
    $jdp="";
    $pfix="";
    $sfix="";
    if (file_exists($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm')) {
    $contis=file_get_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm');
    if (strlen($_GET['getrandom']) > 0) {
    $relstuffs=explode(str_replace(' ','++',str_replace('+',' ',strtolower(urldecode($_GET['getrandom'])))) . '.', $contis);
    if (sizeof($relstuffs) > 1) {
    $isub=0;
    $jdp=str_replace('rand=','',str_replace(' ','++',str_replace('+',' ',strtolower(urldecode($_GET['getrandom'])))));
    $imode=1;
    while (substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1) >= '0' && substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1) <= '9') {
    if ($imode == 0) {
    $jdp.=substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1);
    } else {
    $idp.=substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1);
    }
    $isub++;
    if (substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1) == '.') {
    $imode=1;
    $isub++;
    }
    }
    if (isset($_GET['via'])) {
    $pfix=" if (parent.document.getElementById('" . $_GET['via'] . "')) { parent.document.getElementById('" . $_GET['via'] . "').style.width='100%;'; parent.document.getElementById('" . $_GET['via'] . "').innerHTML+='<iframe style=width:100%;height:800px; src=!!!></iframe>'; } else { ";
    $sfix=" } ";
    }
    if (strtolower(urldecode($_GET['getrandom'])) != urldecode($_GET['getrandom'])) { // Cut to the Chase
    echo "<html><body onload=\"" . str_replace('!!!','/slideshow.html?title=' . explode(" (", explode("\n", explode('=' . $jdp . '.' . $idp, $contis)[1])[0])[0],$pfix) . " parent.window.open('/slideshow.html?title=" . explode(" (", explode("\n", explode('=' . $jdp . '.' . $idp, $contis)[1])[0])[0] . " " . $sfix . " ','_blank','top=200,left=200,width=600,height=600');\"></body></html>";
    exit;
    } else { // WordPress Blog Posting
    echo "<html><body onload=\"" . str_replace('!!!','/ITblog/?p=' . $idp . '#content',$pfix) . " parent.window.open('/ITblog/?p=" . $idp . "#content','_blank','top=200,left=200,width=600,height=600'); " . $sfix . " \"></body></html>";
    exit;
    }
    }
    }
    }
    echo "<html><body><pre>" . $contis . '</pre></body></html>';
    exit;
    }

    ?>
    … called at the parent window by …
  • changed swipe_media.html Tabular Single Row Media Gallery

    function checkmeout(evt, iscuttothechase) {
    if (evt.target.outerHTML.split('>')[0].indexOf('url(') != -1) {
    if (evt.target.outerHTML.split('>')[0].split('url(')[1].split(')')[0].indexOf('?rand=') != -1) {
    if (iscuttothechase) {
    document.getElementById('sparepal').src='/HTMLCSS/select_palette.php?getrandom=' + encodeURIComponent('RAND=' + evt.target.outerHTML.split('>')[0].split('url(')[1].split(')')[0].split('?rand=')[1].split("'")[0].split('"')[0].split(')')[0].split('"')[0]); // + ('&viJUNKa=' + evt.target.id).replace('td','div')
    } else {
    document.getElementById('sparepal').src='/HTMLCSS/select_palette.php?getrandom=' + encodeURIComponent('rand=' + evt.target.outerHTML.split('>')[0].split('url(')[1].split(')')[0].split('?rand=')[1].split("'")[0].split('"')[0].split(')')[0].split('"')[0]); // + ('&viJUNKa=' + evt.target.id).replace('td','div')
    }
    }
    }
    }

… web application, now accepting …

  1. click on one of these WordPress Blog random tutorial images to open window to relevant WordPress Blog posting … or …
  2. right click on one of these WordPress Blog random tutorial images to open window to relevant Cut to the Chase web application or presentation media regarding that blog posting above


Previous relevant Tabular Single Row YouTube Audio or Video Gallery Tutorial is shown below.

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Today we’ve connected …

… which now have three new functionality options …

  • <–> … link to align the (previously) “Brady Bunch” YouTube iframes into a single row in the same web browser tab
  • <–>A+V … call of yesterday’s Media Gallery web application playing our “inhouse” YouTube iframe video playing web application in a new web browser tab
  • <–>A-V … link to our “inhouse” audio stream only YouTube iframe playing functionality in a new web browser tab

… involving changes to …

  • our changed

    var ytlist='';

    if (('' + document.URL + ('' + location.hash)).indexOf('onerow=') != -1) {
    setTimeout(function(){
    var inis='';
    var iwis=document.getElementById('vplayer1').getBoundingClientRect().width;
    var ifsare=document.getElementsByTagName('iframe');
    for (var jtt=0; jtt<ifsare.length; jtt++) {
    //alert(ifsare[jtt].src);
    if (ifsare[jtt].src.indexOf('/embed/') != -1) {
    if (ytlist == '') {
    ytlist='' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    } else {
    ytlist+=',' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    }
    }
    ifsare[jtt].style.width='' + iwis + 'px';
    }
    var toho=document.getElementsByTagName('table')[0];
    var tih=toho.innerHTML;
    var newtih=tih;
    //alert(tih);
    var thingos=tih.split('<tr');
    for (var itt=3; itt>=1; itt--) {
    if (itt == 1) {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('</tr>','<!--/tr-->'));
    } else if (itt == 3) {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('<tr>','<!--tr-->'));
    } else {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('<tr>','<!--tr-->').replace('</tr>','<!--/tr-->'));
    }
    }
    toho.innerHTML=newtih;
    toho.style.width='1000%';
    }, 4000);
    }

    setTimeout(function(){
    var antwo='';
    if (ytlist == '') {
    var ifsare=document.getElementsByTagName('iframe');
    for (var jtt=0; jtt<ifsare.length; jtt++) {
    //alert(ifsare[jtt].src);
    if (ifsare[jtt].src.indexOf('/embed/') != -1) {
    if (ytlist == '') {
    ytlist='' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    } else {
    ytlist+=',' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    }
    }
    }
    }
    if (ytlist != '') {
    antwo+=' <a title="Audio and video plays of YouTube videos" target=_blank href="/HTMLCSS/swipe_media.html?youtube=' + encodeURIComponent(ytlist) + '"><--><sup>A+V</sup></a>';
    antwo+=' <a title="Audio only plays of YouTube videos" target=_blank href="/HTMLCSS/swipe_media.html?audioyoutube=' + encodeURIComponent(ytlist) + '"><--><sub>A-V</sub></a>';
    }
    if (document.URL.indexOf('?') != -1) {
    document.getElementById('wshuffle').innerHTML+=' <a title="Present in one table row" target=_self href="' + document.URL.replace('?', '?onerow=' + Math.floor(Math.random() * 1989786)) + '"><--></a>' + antwo + ' ';
    } else {
    document.getElementById('wshuffle').innerHTML+=' <a title="Present in one table row" target=_self href="' + document.URL + '?onerow=' + Math.floor(Math.random() * 1989786) + '"><--></a>' + antwo + ' ';
    }
    }, 9000);

    youtube_brady_bunch.js being used in our inhouse Disco web application “peer to peer suite” web application “grandparent” level example …
  • “second draft” swipe_media.html Tabular Single Row Image Gallery web application


Previous relevant Tabular Single Row Image Gallery Primer Tutorial is shown below.

Tabular Single Row Image Gallery Primer Tutorial

Tabular Single Row Image Gallery Primer Tutorial

“Tabular Single Row Image Gallery” …

Smabular Single Row Image Gallery

… we’re sure is the reaction of some readers out there, to today’s “starting draft” for an idea we had. Today’s part of the jigsaw we want to explore may be “ho hum” and “so non-mobile”, but we’re hoping the thread appeals to more modern ideas as we go along.

So much for the apologies, and so let’s now look at the basis to this start …

  • media (so far just image) …
  • gallery … presented in …
  • table … HTML element … in …
  • single tr row
  • deliberately overflowing to the right of the screen view of the webpage … and so …
  • scrollable (ie. window scrollable) to … those right hand parts …
  • only “media loaded” …
  • as “scrolled to” or “stumbled upon”

So far the window scrollable detection goes (thanks to this useful link) …


window.onscroll = function (e) {
// called when the window is scrolled.
vspos4=document.body.scrollTop;
vspos3=document.body.scrollLeft;
var vstdn=Math.ceil(eval('' + vspos3) / eval('' + amin));
if (curtdn != vstdn) {
checkthen(vstdn);
}
}

… and the CSS produced “wording (ie. non-media) content” is produced down the bottom left of “inhouse WordPress Blog image cell background” ( possible because of background-size:contain ) we think is interesting …


<style>
td {
border: 1px dotted green;
}

.inhouse {
vertical-align: bottom;
padding-bottom: 20px;
}

.inhouse::after {
content: 'Media Gallery \a RJM Programming \a August, 2025 \a Thanks to Lorem Picsum at https://picsum.photos/ \a ' attr(alt);
white-space: pre-wrap;
}

</style>

… in a “first draft” Tabular Single Row Image Gallery web application for your perusal. Thanks to Lorem Picsum regarding, as so often happens for us, when we’d like beautiful random images to be involved with web applications!

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

YouTube Audio Only Mobile Looping Tutorial

YouTube Audio Only Mobile Looping Tutorial

YouTube Audio Only Mobile Looping Tutorial

Further to the recent External Javascript YouTube Audio of Video Research Tutorial

  • we have made the textarea text stand out more
  • the loop lines up to any looping tick presented
  • we’ve improved the looping logic

… in the changed karaoke_youtube_api.htm inhouse YouTube video interfacer calling the modified and further improved stop_start_youtube.html YouTube API caller.


Previous relevant External Javascript YouTube Audio of Video Research Tutorial is shown below.

External Javascript YouTube Audio of Video Research Tutorial

External Javascript YouTube Audio of Video Research Tutorial

In the same line of thinking as yesterday’s External Javascript YouTube Audio of Video Switch Tutorial we probably have a little more room in that textarea (user interactions menu) for a couple more switch/class hotkey options, in the research line of thinking, we’ll call …

G=Google
W=Wikipedia

… the first having an obvious connection, where the title of a YouTube video is likely to resonate with Google.

But do you ever “go fishing” in Wikipedia? It won’t give up on you even if you are asking for strange information, that is, suggesting other avenues to research using “words, basically”.

And so, like with yesterday (and it’s work augmented a bit), we’ve got to say the Javascript function playingvideo‘s switch and case based logic stuck out because the coding involves words that relate to functionality far better than an if code structure. And so all we needed to do for our change, between the Javascript’s switch and first case was add …


case 'Y':
if (document.URL.indexOf('start=') != -1 && document.URL.indexOf('start=0') == -1) {
window.open('//www.youtube.com/watch?v=' + vid + '&t=' + document.URL.split('start=')[1].split('&')[0].split('#')[0] + 's', '_blank', 'top=100,left=100,width=600,height=600');
} else {

window.open('//www.youtube.com/watch?v=' + vid, '_blank', 'top=100,left=100,width=600,height=600');
}
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
break;

case 'G':
window.open('//www.google.com/search?q=' + encodeURIComponent(parent.document.getElementsByTagName('h1')[0].innerHTML), '_blank', 'top=110,left=110,width=600,height=600');
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
break;


case 'W':
window.open('//wikipedia.org/wiki/' + encodeURIComponent(parent.document.getElementsByTagName('h1')[0].innerHTML), '_blank', 'top=120,left=120,width=600,height=600');
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
break;


… still only involving changes to the modified stop_start_youtube.html YouTube API caller to make happen.


Previous relevant External Javascript YouTube Audio of Video Switch Tutorial is shown below.

External Javascript YouTube Audio of Video Switch Tutorial

External Javascript YouTube Audio of Video Switch Tutorial

If we say …

  1. switch … and then …
  2. case

… related to Javascript coding, what’s the reaction around here? Well, we’d say …

One of the most relatable and easily revisited modus operandi, within Javascript, to pick up where you left off or add more

Doesn’t exactly “roll off the tongue”, but we’ll leave that for you should you read this blog posting, and agree?!

In a similar line of thinking as External Javascript YouTube Audio of Video Snippet Tutorial, what did we want to achieve with today’s modification to YouTube Audio of Video Stream Play Only web application, is, once the user is into the YouTube play and you get to that textarea menu that works like a hotkey (and we can thank that for what must have been clear and relatable thinking that day) is to add a Y hotkey possibility to open a popup window back to a YouTube based play of the video concerned.

We’ve got to say the Javascript function playingvideo‘s switch and case based logic stuck out because the coding involves words that relate to functionality far better than an if code structure. And so all we needed to do for our change, between the Javascript’s switch and first case was add …


case 'Y':
window.open('//www.youtube.com/watch?v=' + vid, '_blank', 'top=100,left=100,width=600,height=600');
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
break;


… and only involving changes to the modified stop_start_youtube.html YouTube API caller to make happen.


Previous relevant External Javascript YouTube Audio of Video Snippet Tutorial is shown below.

External Javascript YouTube Audio of Video Snippet Tutorial

External Javascript YouTube Audio of Video Snippet Tutorial

Given the current Play Audio Stream of Selected YouTube Video In Place functionality talked about, last, at External Javascript YouTube Audio of Video Numericals Tutorial occurs “in place” there’s a good chance what the user may want to describe is either …

  • audio starting at a given timed position …
  • audio starting at a given timed position and ending at another timed position … ie. an audio snippet

. Well, today, we’re allowing for either possibility above to value add to our work.

So, YouTube URLs are already possible in the first of the modes above, such as the URL …


https://www.youtube.com/watch?v=cLsgc8S33dE&t=21m25s

… and we augment that possibility by stopping the videoaudio starting at that same starting point but making use of hashtag thinking to add …


https://www.youtube.com/watch?v=cLsgc8S33dE&t=21m25s#d=5

… used by this link or …


https://www.youtube.com/watch?v=cLsgc8S33dE&t=21m25s#e=21m30s

… means …


altend='22223';
spos='0';
if (('' + audioonlyas[iuhg].href).split('>')[0].split('youtube.com/watch?v=')[1].replace('#t','&t').indexOf('&t=') != -1) { // &t=2m37s
sposspare=('' + audioonlyas[iuhg].href).split('>')[0].split('youtube.com/watch?v=')[1].replace('#t','&t').split('&t=')[1].split('&')[0].split('#')[0].split('"')[0].split("'")[0].split('>')[0];
if (sposspare.indexOf(':') != -1) {
for (idel=eval(-1 + sposspare.split(':').length); idel>=0; idel--) {
spos='' + eval(eval('' + spos) + eval(deltv[idel] * eval('' + sposspare.split(':')[idel] )));
}
} else {
//alert(sposspare);
for (idel=3; idel>=0; idel--) {
if (sposspare.indexOf(delts[idel]) != -1) {
spos='' + eval(eval('' + spos) + eval(deltv[idel] * eval('' + sposspare.split(delts[idel])[0].slice(-3).replace(delts[0],'').replace(delts[1],'').replace(delts[2],'').replace(delts[3],'') )));
} else if (idel == 3 && sposspare.indexOf(delts[2]) == -1 && sposspare.indexOf(delts[1]) == -1 && sposspare.indexOf(delts[0]) == -1) {
spos='' + sposspare;
}
}
}
}
if (('' + audioonlyas[iuhg].href).split('>')[0].split('youtube.com/watch?v=')[1].indexOf('#e=') != -1) { // &t=2m37s
sposspare=('' + audioonlyas[iuhg].href).split('>')[0].split('youtube.com/watch?v=')[1].split('#e=')[1].split('&')[0].split('#')[0].split('"')[0].split("'")[0].split('>')[0];
if (sposspare.indexOf(':') != -1) {
altend='0.000';
for (idel=eval(-1 + sposspare.split(':').length); idel>=0; idel--) {
altend='' + eval(eval('' + altend) + eval(deltv[idel] * eval('' + sposspare.split(':')[idel] )));
}
} else {
altend='0.000';
for (idel=3; idel>=0; idel--) {
if (sposspare.indexOf(delts[idel]) != -1) {
altend='' + eval(eval('' + altend) + eval(deltv[idel] * eval('' + sposspare.split(delts[idel])[0].slice(-3).replace(delts[0],'').replace(delts[1],'').replace(delts[2],'').replace(delts[3],'') )));
} else if (idel == 3 && sposspare.indexOf(delts[2]) == -1 && sposspare.indexOf(delts[1]) == -1 && sposspare.indexOf(delts[0]) == -1) {
altend='' + eval(eval('' + altend) + eval('' + sposspare));
}
}
}
}
if (('' + audioonlyas[iuhg].href).split('>')[0].split('youtube.com/watch?v=')[1].indexOf('#d') != -1) { // &t=2m37s
if (('' + audioonlyas[iuhg].href).split('>')[0].split('youtube.com/watch?v=')[1].split('#d')[1].indexOf('=') != -1) { // &t=2m37s
sposspare=('' + audioonlyas[iuhg].outerHTML).split('>')[0].split('youtube.com/watch?v=')[1].split('#d')[1].split('=')[1].split('&')[0].split('#')[0].split('"')[0].split("'")[0].split('>')[0];
if (sposspare.indexOf(':') != -1) {
altend=spos.split('.')[0] + '.000';
for (idel=eval(-1 + sposspare.split(':').length); idel>=0; idel--) {
altend='' + eval(eval('' + altend) + eval(deltv[idel] * eval('' + sposspare.split(':')[idel] )));
}
} else {
altend=spos.split('.')[0] + '.000';
for (idel=3; idel>=0; idel--) {
if (sposspare.indexOf(delts[idel]) != -1) {
altend='' + eval(eval('' + altend) + eval(deltv[idel] * eval('' + sposspare.split(delts[idel])[0].slice(-3).replace(delts[0],'').replace(delts[1],'').replace(delts[2],'').replace(delts[3],'') )));
} else if (idel == 3 && sposspare.indexOf(delts[2]) == -1 && sposspare.indexOf(delts[1]) == -1 && sposspare.indexOf(delts[0]) == -1) {
altend='' + eval(eval('' + altend) + eval('' + sposspare));
}
}
}
}
//alert('spos=' + spos + ' and altend=' + altend);
}

… by which you can define a 5 second snippet of YouTube cLsgc8S33dE audio stream (of video) starting at 21m 25s be played, perhaps looping, in our changed external Javascript ytaudioonly.js external Javascript supports the changed karaoke_youtube_api.htm inhouse YouTube video interfacer calling the modified stop_start_youtube.html YouTube API caller in our quest to play YouTube audio “in place” in useful ways via …


<script type='text/javascript' src='//www.rjmprogramming.com.au/ytaudioonly.js'></script>

… within the head section of a webpage massaging how a link such as


<a target="_blank" class="audioytplay" title="https://www.youtube.com/watch?v=cLsgc8S33dE" href="https://www.youtube.com/watch?v=cLsgc8S33dE&t=21m25s#d=5" rel="noopener">this link</a>

… behaves.


Previous relevant External Javascript YouTube Audio of Video Numericals Tutorial is shown below.

External Javascript YouTube Audio of Video Numericals Tutorial

External Javascript YouTube Audio of Video Numericals Tutorial

Regarding yesterday’s External Javascript YouTube Audio of Video Fallback Tutorial 📻🎶 (&#128251;&#127926;) emoji (non-mobile showing) title attribute now goes something like …

Right click opens in new window the video and audio but normal click just plays audio in place. Numerical only entry in textarea seeks that audio timing position. Numerical space search text does YouTube search of search text to create the numerical number of audio only YouTube video links. Eg. 7 octopus anatomy

… and the purple functionality has been going two days now, because we found it convenient debugging the fallback logic, while the blue is today’s new functionality which opens the door to a user creating their own dynamically created audio stream part of YouTube video playing links presented close to yesterday’s textarea element information … perhaps three doors down from MacArthur Park?

This new hierarchical layer had us questioning, again, our “grandchild” logic penchant of referring to the layer containing these link references like …


top.document.getElementById('ajaxxx_myajaxxx').placeholder

… when, now, it could be the case, sandwiched between, can be this new hierarchical layer. And so, the awkward feeling …


parent.parent.document.getElementById('ajaxxx_myajaxxx').placeholder

… is the better and more precise way a “grandchild” can refer to a “grandparent” exclusively. Of course, in hindsight, on a project, these hierarchy possibilities would probably be mapped out for every eventuality, and the penchant for a programmer to willy-nilly use top.document everywhere, could be put under the microscope. But, please don’t declare war on all top.document reference thinking … for instance, to share data among many such layers of web application functionality, it can be effectively shared in …


top.document.title

… as just one example of effective top.document referencing. There is also the issue that parent.parent.document type references can make someone maintaining the code later suspect the codeline as a bug (and maybe a codeline comment could help).

The new Javascript function needed for this goes …


function ytsearch(intysidea) {
var afternums='', isanum=true, beforenums='', wasph='';
for (var ihj=0; ihj<intysidea.length; ihj++) {
if (isanum) {
if (intysidea.substring(ihj).substring(0,1) < '0' || intysidea.substring(ihj).substring(0,1) > '9') {
isanum=false;
if (intysidea.substring(ihj).substring(0,1) != ' ') {
afternums+=intysidea.substring(ihj).substring(0,1);
}
} else {
beforenums+=intysidea.substring(ihj).substring(0,1);
}
} else {
afternums+=intysidea.substring(ihj).substring(0,1);
}
}
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
if (afternums.trim() != '') {
if (parent.parent.document.getElementById('yts' + location.hash.replace(/\#/g,'').substring(3).split('_')[0])) {
wasph=parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder;
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='';
parent.parent.document.getElementById('yts' + location.hash.replace(/\#/g,'').substring(3).split('_')[0]).src='//www.rjmprogramming.com.au/HTMLCSS/karaoke_youtube_api.htm?youtubeid=++++++++++++' + encodeURIComponent(afternums) + '&audioonlys=' + (beforenums.trim() == '' ? '5' : beforenums) + '&paridis=' + ouraidis + '&wasph=' + encodeURIComponent(wasph) + '#tonlyaudios';
parent.parent.document.getElementById('' + location.hash.replace(/\#/g,'').substring(3).split('_')[0]).scrollIntoView();
} else if (top.document.getElementById('ldi' + location.hash.replace(/\#/g,'').substring(3).split('_')[0])) {
wasph=parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder;
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='';
parent.parent.document.getElementById('ldi' + location.hash.replace(/\#/g,'').substring(3).split('_')[0]).innerHTML+='<iframe style=height:250px; id="yts' + + ouraidis + '" src="' + '//www.rjmprogramming.com.au/HTMLCSS/karaoke_youtube_api.htm?youtubeid=++++++++++++' + encodeURIComponent(afternums) + '&audioonlys=' + (beforenums.trim() == '' ? '5' : beforenums) + '&paridis=' + ouraidis + '&wasph=' + encodeURIComponent(wasph) + '#tonlyaudios"></iframe>';
parent.parent.document.getElementById('' + location.hash.replace(/\#/g,'').substring(3).split('_')[0]).scrollIntoView();
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder=wasph;
} else {
wasph=parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder;
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='';
parent.parent.document.getElementById('' + location.hash.replace(/\#/g,'').substring(3).split('_')[0]).innerHTML+='<iframe style=height:250px; id="yts' + + ouraidis + '" src="' + '//www.rjmprogramming.com.au/HTMLCSS/karaoke_youtube_api.htm?youtubeid=++++++++++++' + encodeURIComponent(afternums) + '&audioonlys=' + (beforenums.trim() == '' ? '5' : beforenums) + '&paridis=' + ouraidis + '&wasph=' + encodeURIComponent(wasph) + '#tonlyaudios"></iframe>';
parent.parent.document.getElementById('' + location.hash.replace(/\#/g,'').substring(3).split('_')[0]).scrollIntoView();
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder=wasph;
}
}
}

… and connected to that non-onblur event approach …


function playingvideo() {
inplaying=true;
if (thatisit) { inplaying=false; return ''; }
psuf='';
if (startagain) {
if (1 == 6 && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
psuf=' via button reclick ' + String.fromCodePoint(10004);
} else {
psuf=' ' + String.fromCodePoint(10004);
}
}
if (('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/\#/g,'') != '') {
if (eval('' + duration) == 0 && Math.round(player.getCurrentTime()) < 1) {
if (one == 1 || onepause != 1) {
if (1 == 4) { player.pauseVideo(); }
} else {
player.playVideo();
}
if (!inplaying) { inplaying=true; setTimeout(playingvideo, 1000); }
} else {
if (parent.parent.document.getElementById(location.hash.replace(/\#/g,''))) {
if (('' + parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).getAttribute('data-val')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value= parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).getAttribute('data-val');
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-val','');
}
switch (('' + parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value.toUpperCase() + ' ').substring(0,1)) {
case 'L':
if (numericalssamecount <= 0) {
startagain=true;
if (('' + window.sessionStorage.getItem('loop_' + vid.split(',')[0])).replace(/^undefined/g,'').replace(/^null/g,'').trim() == '') {
setInterval(retry, 5000);
} else {
window.sessionStorage.removeItem('loop_' + vid);
}
window.sessionStorage.setItem('loop_' + vid, 'y');
psuf='';
if (startagain) {
psuf=' ' + String.fromCodePoint(10004);
}
dostumps=false;
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
} else {
numericalssamecount++;
}
break;

case 'S':
if (numericalssamecount <= 0) {
startagain=false;
psuf='';
if (startagain) {
psuf=' ' + String.fromCodePoint(10004);
}
dostumps=true;
player.stopVideo();
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
try {
window.sessionStorage.removeItem('loop_' + vid);
} catch(hdgf) { }
} else {
numericalssamecount++;
}
break;

case 'P':
if (numericalssamecount <= 0) {
if (one == 1 || onepause != 1) {
player.pauseVideo();
} else {
player.playVideo();
}
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
} else {
numericalssamecount++;
}
break;

case 'M':
if (numericalssamecount <= 0) {
player.mute();
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).removeAttribute('data-mute');
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-mute', 'y');
mletter='M';
uletter='u';
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
} else {
numericalssamecount++;
}
break;

case 'U':
if (numericalssamecount <= 0) {
player.unMute();
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).removeAttribute('data-mute');
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-mute', '');
mletter='m';
uletter='U';
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
} else {
numericalssamecount++;
}
break;

case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':

if (2 == 2 || !navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
if (numericals == '') {
numericalssamecount=1;
numericals=parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value;
setTimeout(sanitycheck, 12000);
} else if (parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value == numericals) {
numericalssamecount++;
if (numericalssamecount >= 10) {
if (numericals.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'').trim() == '') {
if (eval(numericals) >= 0 && eval(numericals) <= eval('' + duration)) {
player.seekTo(eval(numericals.trim()));
}
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value='';
numericals='';
numericalssamecount=0;
//top.document.title='ZerO';
} else {
ytsearch(parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value);
numericals='';
numericalssamecount=0;
//top.document.title='ZeRO';
}

}
} else {
numericalssamecount=1;
numericals=parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).value;
setTimeout(sanitycheck, 12000);
}
}
break;

default:
if (numericalssamecount > 0) {
numericalssamecount++;
}
break;
}
if (parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder.replace('/p','').indexOf('/') != -1) {
if (startagain && eval(2.2 + Math.round(player.getCurrentTime())) > Math.floor(eval('' + duration)) && eval('' + duration) > 0) {
thatisit=true;
lastokn=0;
//alert(4);
if (('' + window.sessionStorage.getItem('loop_' + vid.split(',')[0])).replace(/^undefined/g,'').replace(/^null/g,'').trim() != '') {
//alert(44);
window.sessionStorage.removeItem('loop_' + vid.split(',')[0]);
}
window.sessionStorage.setItem('loop_' + vid.split(',')[0], 'y');
//alert(444);
secscnt=eval(0.001 + duration);
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-loop','y');
setTimeout(function(){
if (1 == 11) {
setTimeout(startVideo, playtime + delay);
thatisit=false; setTimeout(playingvideo, 1900);
} else {
var huhc=false;
// huhc=confirm('Okay to loop?');
if (huhc && 1 == 7) {
player.seekTo(0.01);
secscnt=0.01;
oursecscnt=0.01;
player.playVideo();
thatisit=false; setTimeout(playingvideo, 1900);
} else if (9 == 5) {
window.parent.focus();
parent.location.href=parent.document.URL.split('&random=')[0] + '&random=' + Math.floor(Math.random() * 1987865) + '&startagain=y' + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/^\#$/g,'');
window.parent.scrollTo(0,0);
} else {
player.seekTo(1);
thatisit=false; setTimeout(playingvideo, 3000);
setTimeout(retry, 5000);
//alert(4444);
}
} }, 1500);
inplaying=false;
return '';
} else {
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-loop','y');
setTimeout(function(){ window.top.focus(); parent.parent.document.getElementById(location.hash.replace(/\#/g,'').substring(3).split('_')[0]).click(); }, 1500);
inplaying=false;
return '';
}
}
if (one == 1 || onepause != 1) {
if (eval('' + duration) == 0) { duration=player.getDuration(); }
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='' + Math.round(player.getCurrentTime()) + '/' + duration + ' ... ' + 'P=pause/play S=stop M=' + mletter + 'ute U=' + uletter + 'nmute L=loop' + psuf;
} else {
if (eval('' + duration) == 0) { duration=player.getDuration(); }
parent.parent.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='' + Math.round(player.getCurrentTime()) + '/' + duration + ' ... ' + 'P=play/pause S=stop M=' + mletter + 'ute U=' + uletter + 'nmute L=loop' + psuf;
setTimeout(addablank, 3000);
}
setTimeout(playingvideo, 1000);
}
}
}
}
}

… in our changed external Javascript ytaudioonly.js external Javascript supports the changed karaoke_youtube_api.htm inhouse YouTube video interfacer calling the modified stop_start_youtube.html YouTube API caller in our quest to play YouTube audio “in place” in a useful way.


Previous relevant External Javascript YouTube Audio of Video Fallback Tutorial is shown below.

External Javascript YouTube Audio of Video Fallback Tutorial

External Javascript YouTube Audio of Video Fallback Tutorial

Further to yesterday’s External Javascript YouTube Audio of Video Looping Tutorial work regarding the Play Audio Stream of Selected YouTube Video In Place functionality we’re currently working on …

  • the timing of getting some mobile platform looping going is fortunate … and it means, with far less complication, we can organize …
  • the “red button” (mobile) or “link” (non-mobile) can serve as a fallback option when the user is in looping mode of YouTube Audio Stream Part of Video play and there is an interruption to that playing

… because there are a million and one reasons your YouTube video can get interrupted, such as …

  • window focus leaves the window of the playing YouTube video
  • seems like some mobile time limit is going on too
  • dormancy to sleep screen
  • focus regarding the textarea elements, we suspect

… etcetera etcetera etcetera … and there will could be good reasons the operating system behaves the way it does (as well as, as far as it goes here, we’ve been known to have “bad hair days”, even “very little hair days”).

But with a fallback option there, to re-click that originating “red button” (mobile) or “link” (non-mobile) is the chance to continue on with looping, so far not always back where you were, but who knows what the future brings?!

Also, organization wise, what has made all this easier, was to


function playingvideo() {
psuf='';
if (startagain) {
if (1 == 6 && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
psuf=' via button reclick ' + String.fromCodePoint(10004);
} else {
psuf=' ' + String.fromCodePoint(10004);
}
}
if (('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/\#/g,'') != '') {
if (eval('' + duration) == 0 && Math.round(player.getCurrentTime()) < 1) {
if (one == 1 || onepause != 1) {
if (1 == 4) { player.pauseVideo(); }
} else {
player.playVideo();
}
setTimeout(playingvideo, 1000);
} else {
if (top.document.getElementById(location.hash.replace(/\#/g,''))) {
if (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).getAttribute('data-val')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
top.document.getElementById(location.hash.replace(/\#/g,'')).value= top.document.getElementById(location.hash.replace(/\#/g,'')).getAttribute('data-val');
top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-val','');
}
switch (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).value.toUpperCase() + ' ').substring(0,1)) {
case 'L':
if (numericalssamecount <= 0) {
startagain=true;
if (('' + window.sessionStorage.getItem('loop_' + vid.split(',')[0])).replace(/^undefined/g,'').replace(/^null/g,'').trim() == '') {
setInterval(retry, 5000);
} else {
window.sessionStorage.removeItem('loop_' + vid, 'y');
}
window.sessionStorage.setItem('loop_' + vid, 'y');
psuf='';
if (startagain) {
psuf=' ' + String.fromCodePoint(10004);
}
dostumps=false;
top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
} else {
numericalssamecount++;
}
break;

case 'S':
if (numericalssamecount <= 0) {
startagain=false;
psuf='';
if (startagain) {
psuf=' ' + String.fromCodePoint(10004);
}
dostumps=true;
player.stopVideo();
top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
try {
window.sessionStorage.removeItem('loop_' + vid);
} catch(hdgf) { }
} else {
numericalssamecount++;
}
break;

case 'P':
if (numericalssamecount <= 0) {
if (one == 1 || onepause != 1) {
player.pauseVideo();
} else {
player.playVideo();
}
top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
} else {
numericalssamecount++;
}
break;

case 'M':
if (numericalssamecount <= 0) {
player.mute();
mletter='M';
uletter='u';
top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
} else {
numericalssamecount++;
}
break;

case 'U':
if (numericalssamecount <= 0) {
player.unMute();
mletter='m';
uletter='U';
top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
} else {
numericalssamecount++;
}
break;

case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (2 == 2 || !navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
if (numericals == '') {
numericalssamecount=1;
numericals=top.document.getElementById(location.hash.replace(/\#/g,'')).value;
setTimeout(sanitycheck, 12000);
} else if (top.document.getElementById(location.hash.replace(/\#/g,'')).value == numericals) {
numericalssamecount++;
if (numericalssamecount >= 10) {
if (numericals.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'').trim() == '') {
if (eval(numericals) >= 0 && eval(numericals) <= eval('' + duration)) {
player.seekTo(eval(numericals.trim()));
}
top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
numericals='';
numericalssamecount=0;
}
}
} else {
numericalssamecount=1;
numericals=top.document.getElementById(location.hash.replace(/\#/g,'')).value;
setTimeout(sanitycheck, 12000);
}
}
break;

default:
if (numericalssamecount > 0) {
numericalssamecount++;
}
break;
}
if (top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder.indexOf('/') != -1) {
if (startagain && eval(2 + Math.round(player.getCurrentTime())) > eval('' + duration) && eval('' + duration) > 0) {
secscnt=eval(0.001 + duration);
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-loop','y');
setTimeout(function(){
if (1 == 11) {
setTimeout(startVideo, playtime + delay);
setTimeout(playingvideo, 1900);
} else {
var huhc=false;
// huhc=confirm('Okay to loop?');
if (huhc && 1 == 7) {
player.seekTo(0.01);
secscnt=0.01;
oursecscnt=0.01;
player.playVideo();
setTimeout(playingvideo, 1900);
} else if (9 == 5) {
window.parent.focus();
parent.location.href=parent.document.URL.split('&random=')[0] + '&random=' + Math.floor(Math.random() * 1987865) + '&startagain=y' + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/^\#$/g,'');
window.parent.scrollTo(0,0);
} else {
player.seekTo(1);
setTimeout(playingvideo, 3000);
setTimeout(retry, 5000);
}
} }, 1500);
return '';
} else {
top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-loop','y');
setTimeout(function(){ window.top.focus(); top.document.getElementById(location.hash.replace(/\#/g,'').substring(3).split('_')[0]).click(); }, 1500);
return '';
}
}
if (one == 1 || onepause != 1) {
if (eval('' + duration) == 0) { duration=player.getDuration(); }
top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='' + Math.round(player.getCurrentTime()) + '/' + duration + ' ... ' + 'P=pause/play S=stop M=' + mletter + 'ute U=' + uletter + 'nmute L=loop' + psuf;
} else {
if (eval('' + duration) == 0) { duration=player.getDuration(); }
top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='' + Math.round(player.getCurrentTime()) + '/' + duration + ' ... ' + 'P=play/pause S=stop M=' + mletter + 'ute U=' + uletter + 'nmute L=loop' + psuf;
setTimeout(addablank, 3000);
}
setTimeout(playingvideo, 1000);
}
}
}
}
}

… start using the web browser’s session storage smarts as an overseeing data source we can better rely on. With this in place it was so much more robust to work out when to invoke our fallback thinking new Javascript function …


function retry() {
if (top.document.getElementById(location.hash.replace(/\#/g,''))) {
if (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder).indexOf('0/0 ...') == 0) {
if (top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder.indexOf(' to continue looping') == -1) {
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder+=' try click of red button to continue looping';
} else {
top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder+=' try click of link to continue looping';
}
window.parent.focus();
parent.location.href=parent.document.URL.split('&random=')[0] + '&random=' + Math.floor(Math.random() * 1987865) + '&startagain=y' + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/^\#$/g,'');
window.parent.scrollTo(0,0);
}
} else if (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder).indexOf('P=pause/play') != -1) {
if (prevretry == '') {
prevretry=top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder;
} else if (prevretry == top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder) {
if (top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder.indexOf(' to continue looping') == -1) {
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder+=' ... try click of red button to continue looping';
} else {
top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder+=' ... try click of link to continue looping';
}
}
} else {
prevretry=top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder;
}
} else if (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder).indexOf('P=play/pause') != -1) {
if (prevretry == '') {
prevretry=top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder;
} else if (prevretry == top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder) {
if (top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder.indexOf(' to continue looping') == -1) {
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder+=' ... try click of red button to continue looping';
} else {
top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder+=' ... try click of link to continue looping';
}
}
} else {
prevretry=top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder;
}
}
}
}

… for our so far in the day unchanged external Javascript ytaudioonly.js external Javascript supports the changed karaoke_youtube_api.htm inhouse YouTube video interfacer calling the modified stop_start_youtube.html YouTube API caller in our quest to play YouTube audio “in place” in a useful way.


Previous relevant External Javascript YouTube Audio of Video Looping Tutorial is shown below.

External Javascript YouTube Audio of Video Looping Tutorial

External Javascript YouTube Audio of Video Looping Tutorial

Of yesterday’s External Javascript YouTube Audio of Video Emoji Tutorial

  1. pause
  2. play
  3. loop
  4. stop
  5. progress perhapsyes

… list of suggested “controls” for our Play Audio Stream of Selected YouTube Video In Place functionality, am sure of most interest was the loop one. Well, it certainly was for us, anyway.

We weren’t sure whether we could get around the actual tap needed on mobile platforms to just apply …


player.seekTo(0);
player.playVideo();

… as we near the end of the video. Alas, no, we need the red button (ie. the transparent YouTube video) to be retapped to get anywhere … so sad.

But non-mobile platform usages can loop effectively, and might help out users, who, like me, occasionally get obsessed with a YouTube music video (such as Morricone – Gabriel’s Oboe from The Mission, Maja Łagowska – oboe, conducted by Andrzej Kucybała) … hence the radio and musical note emojis 📻🎶 (&#128251;&#127926;) we started using yesterday.

Another plan we had to ask for menu operations via a window.prompt a lot of users will be relieved to hear, didn’t work either, and so we had to redesign, finally settling on HTML textarea elements whereby …

  • information and instructions are placed in its placeholder attribute … and …
  • like a hotkey (but not needing onkeydown or onkeyup or onkeypress event logic intervention) user audio control instructions are unique regarding first character, so way down at the grandchild level we have …

    function playingvideo() {
    psuf='';
    if (startagain) {
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    psuf=' via button reclick ' + String.fromCodePoint(10004);
    } else {
    psuf=' ' + String.fromCodePoint(10004);
    }
    }
    if (('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/\#/g,'') != '') {
    if (eval('' + duration) == 0 && Math.round(player.getCurrentTime()) < 1) {
    if (one == 1 || onepause != 1) {
    if (1 == 4) { player.pauseVideo(); }
    } else {
    player.playVideo();
    }
    setTimeout(playingvideo, 1000);
    } else {
    if (top.document.getElementById(location.hash.replace(/\#/g,''))) {
    if (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).getAttribute('data-val')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
    top.document.getElementById(location.hash.replace(/\#/g,'')).value= top.document.getElementById(location.hash.replace(/\#/g,'')).getAttribute('data-val');
    top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-val','');
    }
    switch (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).value.toUpperCase() + ' ').substring(0,1)) {
    case 'L':
    startagain=true;
    psuf='';
    if (startagain) {
    psuf=' ' + String.fromCodePoint(10004);
    }
    dostumps=false;
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;

    case 'S':
    startagain=false;
    psuf='';
    if (startagain) {
    psuf=' ' + String.fromCodePoint(10004);
    }
    dostumps=true;
    player.stopVideo();
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;

    case 'P':
    if (one == 1 || onepause != 1) {
    player.pauseVideo();
    } else {
    player.playVideo();
    }
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;

    case 'M':
    player.mute();
    mletter='M';
    uletter='u';
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;

    case 'U':
    player.unMute();
    mletter='m';
    uletter='U';
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;


    default:
    break;
    }

    if (top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder.indexOf('/') != -1) {
    if (startagain && eval(2 + Math.round(player.getCurrentTime())) > eval('' + duration) && eval('' + duration) > 0) {
    secscnt=eval(0.001 + duration);
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-loop','y');
    setTimeout(function(){
    if (1 == 11) {
    setTimeout(startVideo, playtime + delay);
    setTimeout(playingvideo, 1900);
    } else {
    var huhc=false;
    // huhc=confirm('Okay to loop?');
    if (huhc && 1 == 7) {
    player.seekTo(0.01);
    secscnt=0.01;
    oursecscnt=0.01;
    player.playVideo();
    setTimeout(playingvideo, 1900);
    } else {
    window.parent.focus();
    parent.location.href=parent.document.URL.split('&random=')[0] + '&random=' + Math.floor(Math.random() * 1987865) + '&startagain=y' + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/^\#$/g,'');
    }
    } }, 1500);
    return '';
    } else {
    top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-loop','y');
    setTimeout(function(){ window.top.focus(); top.document.getElementById(location.hash.replace(/\#/g,'').substring(3).split('_')[0]).click(); }, 1500);
    return '';
    }
    }
    if (one == 1 || onepause != 1) {
    if (eval('' + duration) == 0) { duration=player.getDuration(); }
    top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='' + Math.round(player.getCurrentTime()) + '/' + duration + ' ... ' + 'P=pause/play S=stop M=' + mletter + 'ute U=' + uletter + 'nmute L=loop' + psuf;
    } else {
    if (eval('' + duration) == 0) { duration=player.getDuration(); }
    top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='' + Math.round(player.getCurrentTime()) + '/' + duration + ' ... ' + 'P=play/pause S=stop M=' + mletter + 'ute U=' + uletter + 'nmute L=loop' + psuf;
    }
    setTimeout(playingvideo, 1000);
    }
    }
    }
    }
    }

    … does a good job acting like those keyboard events

… for today’s fourth draft external Javascript ytaudioonly.js external Javascript supports the changed karaoke_youtube_api.htm inhouse YouTube video interfacer calling the modified stop_start_youtube.html YouTube API caller in our quest to play YouTube audio “in place” in a useful way.

Stop Press

UnLess attended mobile looping can work with the kludge (we suspect our bug or code design flaw) …


player.seekTo(1);
player.playVideo();

… and we hope nobody’s playing “Name That Sound” with the replays.


Previous relevant External Javascript YouTube Audio of Video Looping Tutorial is shown below.

External Javascript YouTube Audio of Video Looping Tutorial

External Javascript YouTube Audio of Video Looping Tutorial

Of yesterday’s External Javascript YouTube Audio of Video Emoji Tutorial

  1. pause
  2. play
  3. loop
  4. stop
  5. progress perhapsyes

… list of suggested “controls” for our Play Audio Stream of Selected YouTube Video In Place functionality, am sure of most interest was the loop one. Well, it certainly was for us, anyway.

We weren’t sure whether we could get around the actual tap needed on mobile platforms to just apply …


player.seekTo(0);
player.playVideo();

… as we near the end of the video. Alas, no, we need the red button (ie. the transparent YouTube video) to be retapped to get anywhere … so sad.

But non-mobile platform usages can loop effectively, and might help out users, who, like me, occasionally get obsessed with a YouTube music video (such as Morricone – Gabriel’s Oboe from The Mission, Maja Łagowska – oboe, conducted by Andrzej Kucybała) … hence the radio and musical note emojis 📻🎶 (&#128251;&#127926;) we started using yesterday.

Another plan we had to ask for menu operations via a window.prompt a lot of users will be relieved to hear, didn’t work either, and so we had to redesign, finally settling on HTML textarea elements whereby …

  • information and instructions are placed in its placeholder attribute … and …
  • like a hotkey (but not needing onkeydown or onkeyup or onkeypress event logic intervention) user audio control instructions are unique regarding first character, so way down at the grandchild level we have …

    function playingvideo() {
    psuf='';
    if (startagain) {
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    psuf=' via button reclick ' + String.fromCodePoint(10004);
    } else {
    psuf=' ' + String.fromCodePoint(10004);
    }
    }
    if (('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/\#/g,'') != '') {
    if (eval('' + duration) == 0 && Math.round(player.getCurrentTime()) < 1) {
    if (one == 1 || onepause != 1) {
    if (1 == 4) { player.pauseVideo(); }
    } else {
    player.playVideo();
    }
    setTimeout(playingvideo, 1000);
    } else {
    if (top.document.getElementById(location.hash.replace(/\#/g,''))) {
    if (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).getAttribute('data-val')).replace(/^undefined/g,'').replace(/^null/g,'') != '') {
    top.document.getElementById(location.hash.replace(/\#/g,'')).value= top.document.getElementById(location.hash.replace(/\#/g,'')).getAttribute('data-val');
    top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-val','');
    }
    switch (('' + top.document.getElementById(location.hash.replace(/\#/g,'')).value.toUpperCase() + ' ').substring(0,1)) {
    case 'L':
    startagain=true;
    psuf='';
    if (startagain) {
    psuf=' ' + String.fromCodePoint(10004);
    }
    dostumps=false;
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;

    case 'S':
    startagain=false;
    psuf='';
    if (startagain) {
    psuf=' ' + String.fromCodePoint(10004);
    }
    dostumps=true;
    player.stopVideo();
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;

    case 'P':
    if (one == 1 || onepause != 1) {
    player.pauseVideo();
    } else {
    player.playVideo();
    }
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;

    case 'M':
    player.mute();
    mletter='M';
    uletter='u';
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;

    case 'U':
    player.unMute();
    mletter='m';
    uletter='U';
    top.document.getElementById(location.hash.replace(/\#/g,'')).value='';
    break;


    default:
    break;
    }

    if (top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder.indexOf('/') != -1) {
    if (startagain && eval(2 + Math.round(player.getCurrentTime())) > eval('' + duration) && eval('' + duration) > 0) {
    secscnt=eval(0.001 + duration);
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-loop','y');
    setTimeout(function(){
    if (1 == 11) {
    setTimeout(startVideo, playtime + delay);
    setTimeout(playingvideo, 1900);
    } else {
    var huhc=false;
    // huhc=confirm('Okay to loop?');
    if (huhc && 1 == 7) {
    player.seekTo(0.01);
    secscnt=0.01;
    oursecscnt=0.01;
    player.playVideo();
    setTimeout(playingvideo, 1900);
    } else {
    window.parent.focus();
    parent.location.href=parent.document.URL.split('&random=')[0] + '&random=' + Math.floor(Math.random() * 1987865) + '&startagain=y' + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'').replace(/^\#$/g,'');
    }
    } }, 1500);
    return '';
    } else {
    top.document.getElementById(location.hash.replace(/\#/g,'')).setAttribute('data-loop','y');
    setTimeout(function(){ window.top.focus(); top.document.getElementById(location.hash.replace(/\#/g,'').substring(3).split('_')[0]).click(); }, 1500);
    return '';
    }
    }
    if (one == 1 || onepause != 1) {
    if (eval('' + duration) == 0) { duration=player.getDuration(); }
    top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='' + Math.round(player.getCurrentTime()) + '/' + duration + ' ... ' + 'P=pause/play S=stop M=' + mletter + 'ute U=' + uletter + 'nmute L=loop' + psuf;
    } else {
    if (eval('' + duration) == 0) { duration=player.getDuration(); }
    top.document.getElementById(location.hash.replace(/\#/g,'')).placeholder='' + Math.round(player.getCurrentTime()) + '/' + duration + ' ... ' + 'P=play/pause S=stop M=' + mletter + 'ute U=' + uletter + 'nmute L=loop' + psuf;
    }
    setTimeout(playingvideo, 1000);
    }
    }
    }
    }
    }

    … does a good job acting like those keyboard events

… for today’s fourth draft external Javascript ytaudioonly.js external Javascript supports the changed karaoke_youtube_api.htm inhouse YouTube video interfacer calling the modified stop_start_youtube.html YouTube API caller in our quest to play YouTube audio “in place” in a useful way.

Stop Press

UnLess attended mobile looping can work with the kludge (we suspect our bug or code design flaw) …


player.seekTo(1);
player.playVideo();

… and we hope nobody’s playing “Name That Sound” with the replays.


Previous relevant External Javascript YouTube Audio of Video Emoji Tutorial is shown below.

External Javascript YouTube Audio of Video Emoji Tutorial

External Javascript YouTube Audio of Video Emoji Tutorial

Onto yesterday’s External Javascript YouTube Audio of Video Mobile Helper Tutorial, today, we’ve …

  • further shored up the mobile platform playing of the audio stream of a YouTube video, as requested …
  • added display (usefulness only, so far) emojis 📻🎶 (&#128251;&#127926;) into the “underlay” button displays, as today’s work, leading up to, tomorrow …
  • the emoji tap/clicks will lead the user to a menu of further options (as often displayed with video controls) …
    1. pause
    2. play
    3. loop
    4. stop
    5. progress … perhaps

… where today’s third draft external Javascript ytaudioonly.js external Javascript supports the changed karaoke_youtube_api.htm inhouse YouTube video interfacer in our quest to play YouTube audio “in place” in a useful way.


Previous relevant External Javascript YouTube Audio of Video Mobile Helper Tutorial is shown below.

External Javascript YouTube Audio of Video Mobile Helper Tutorial

External Javascript YouTube Audio of Video Mobile Helper Tutorial

After the start yesterday’s External Javascript YouTube Audio of Video Helper Tutorial gave us with our External Javascript YouTube Audio of Video Helper we’ve progressed making the mobile platform interfacing less flaky, but more testing is needed.

Introducing a general delay into our changed karaoke_youtube_api.htm inhouse YouTube video interfacer part of the solution turned things around here.

To delay, say by 13.5 seconds, even great swathes of code …


setTimeout(function(){
// Start of "great swathes of code"
// ...
// End of "great swathes of code"
}, 13500);

… is one of those ideas we’re still pinching ourselves about how effective it can be (let alone passing in arguments at the function() bit). We’re forever filling “great swathes of code” with global Javascript variables but today’s “great swathe” works okay with non global Javascript variables in there, and we’re thinking we have to be more trusting of the brilliant setTimeout (and setInterval) Javascript techniques of introducing a delay into the flow of your Javascript. Of course, we could also delay the work until the document.body onload event, but we wanted to get in early with what the code is trying to achieve here … we’ll see.

Perhaps a good adage here is …

Trust the process.
Trust the wonders of (in the case of iOS, Safari) Web Browser Web Inspector debugging to test ideas you start out being unsure of.

… with our ongoing second draft external Javascript ytaudioonly.js external Javascript ongoing current project … so Wake Me Up Before You Go-Go.


Previous relevant External Javascript YouTube Audio of Video Helper Tutorial is shown below.

External Javascript YouTube Audio of Video Helper Tutorial

External Javascript YouTube Audio of Video Helper Tutorial

It is not that surprising that the next step onto the progress of yesterday’s Making of Clickaround Maps Google Chart Geo Chart Mobile Integration Tutorial would involve us developing…

  • an external Javascript …
  • helper for “in place” …
  • audio play …
  • of that stream of a YouTube video … via …
  • user linked script call …

    <script type='text/javascript' src='//www.rjmprogramming.com.au/ytaudioonly.js'></script>

    … helping out …
  • HTML “a” link with class=audioytplay and a mention of https://www.youtube.com/watch?v=[YouTubeID] … eg.

    <p>Oops, <a class="audioytplay" target="_blank" title="?" href='https://www.youtube.com/watch?v=gBzJGckMYO4' rel="noopener"><strike>that's all</strike>sorry, folks</a></p>
  • to be, via onclick event, playing “in place” the audio part of that YouTube referenced [YouTubeID] video

Developing this is definitely more than a one day job (especially getting mobile platforms working), but today’s “first draft” ytaudioonly.js external Javascript, along with the help of …

… is our start to this project. Try it yourself below …

Oops, that's allsorry, folks


Previous relevant Making of Clickaround Maps Google Chart Geo Chart Mobile Integration Tutorial is shown below.

Making of Clickaround Maps Google Chart Geo Chart Mobile Integration Tutorial

Making of Clickaround Maps Google Chart Geo Chart Mobile Integration Tutorial

As far as CSS styling goes with our web application work, personally speaking, it is one of …

Give it a bit of oompha!

… moments in coding we think we learn more from, than reading about CSS. That, and, usually StackOverflow, thanks, where examples of achieving some styling ambition teach us a lot too.

Yesterday, with Clickaround Maps Google Chart Geo Chart Mobile Integration Tutorial, we decided to “put a bit of oompha” into that “two bell emoji” ( ie. 🔔🔔 ) link “double buzzer” sound “production number”, and wanted to break down what we ended up with, for readers …

Our first try … okay for non-mobile … not as good for mobile …

<a id="aja" target="myja" title="" onmouseover="if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { this.title=' '; this.target='myja'; } " onclick="if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) && this.title == '') { this.title=' '; this.target='myja'; document.getElementById('myja').src=this.href; } setTimeout(function(){ document.getElementById('aja').target='_blank'; },100);" href="//www.rjmprogramming.com.au/HTMLCSS/karaoke_youtube_api.htm?youtubeid=7XMW6Z_Oq38&jusJUNKtaudio=&youtube_duration=2.000&email=&email=&emoji=on&c0=on&i0=0&j0=2&i1=&j1=&i2=&j2=&i3=&j3=&i4=&j4=&i5=&j5=&i6=&j6=&i7=&j7=&i8=&j8=&i9=&j9=&i10=&j10=&i11=&j11=&i12=&j12=&i13=&j13=&i14=&j14=&i15=&j15=&i16=&j16=&i17=&j17=&i18=&j18=&i19=&j19=&i20=&j20=&i21=&j21=&i22=&j22=&i23=&j23=&i24=&j24=&i25=&j25=&i26=&j26=&i27=&j27=&i28=&j28=&i29=&j29=" rel="noopener">&#128276;&#128276;</a>

… begets …

🔔🔔

Our second try … okay for non-mobile … better for mobile …

<a id="aja" target="myja" title="" onmouseover="if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { this.title=' '; this.target='myja'; } " onclick="if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) { this.title == '') { this.title=' '; this.target='myja'; document.getElementById('myja').src=this.href; } setTimeout(function(){ document.getElementById('aja').target='_blank'; },100); }" href="//www.rjmprogramming.com.au/HTMLCSS/karaoke_youtube_api.htm?youtubeid=7XMW6Z_Oq38&justJUNKaudio=&youtube_duration=2.000&email=&email=&emoji=on&c0=on&i0=0&j0=2&i1=&j1=&i2=&j2=&i3=&j3=&i4=&j4=&i5=&j5=&i6=&j6=&i7=&j7=&i8=&j8=&i9=&j9=&i10=&j10=&i11=&j11=&i12=&j12=&i13=&j13=&i14=&j14=&i15=&j15=&i16=&j16=&i17=&j17=&i18=&j18=&i19=&j19=&i20=&j20=&i21=&j21=&i22=&j22=&i23=&j23=&i24=&j24=&i25=&j25=&i26=&j26=&i27=&j27=&i28=&j28=&i29=&j29=" rel="noopener">&#128276;&#128276;</a>
<iframe onload="if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { if (this.src.indexOf('About_Us.') != -1) { document.getElementById('aja').target='myja';
this.src=document.getElementById('aja').href + '&rand=' + Math.floor(Math.random() * 1989786); } } " id="myja" name="myja" src="/About_Us.html" style="display:none;"></iframe>

… begets …

🔔🔔

… working better because of tweaked karaoke_youtube_api.htm
inhouse YouTube video interfacer‘s new


if (window.top) {
if (document.URL.indexOf('youtubeid=7XMW6Z_Oq38&') != -1 && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
setTimeout(function(){
if (document.getElementById('audioejkaraoke')) {
document.getElementById('audioejkaraoke').title=' ' + document.getElementById('audioejkaraoke').title;
document.getElementById('audioejkaraoke').value=String.fromCodePoint(128276) + String.fromCodePoint(128276);
document.getElementById('audioejkaraoke').style.position='absolute';
document.getElementById('audioejkaraoke').style.left='0px';
document.getElementById('audioejkaraoke').style.top='0px';
document.getElementById('audioejkaraoke').style.backgroundColor='transparent';
document.getElementById('audioejkaraoke').style.zIndex='99';
document.getElementById('repeat').value=String.fromCodePoint(128276) + String.fromCodePoint(128276);
document.getElementById('repeat').style.position='absolute';
document.getElementById('repeat').style.left='0px';
document.getElementById('repeat').style.top='-10px';
document.getElementById('repeat').style.backgroundColor='transparent';
document.getElementById('repeat').style.zIndex='199';
document.getElementById('myiframe').style.position='absolute';
document.getElementById('myiframe').style.left='-100px';
document.getElementById('myiframe').style.top='-100px';
document.getElementById('myiframe').style.zIndex='299';
//document.getElementById('myiframe').style.backgroundColor='transparent';
document.getElementById('myiframe').style.opacity='0.0';
if (aaconto) {
aaconto.getElementById('player').style.opacity='0.0';
} else {
aaset=true;
}
document.body.style.backgroundColor='transparent';
} else {
setInterval(function(){
if (document.getElementById('audioejkaraoke')) {
if (('' + document.getElementById('audioejkaraoke').title + ' ').substring(0,1) != ' ') {
document.getElementById('audioejkaraoke').title=' ' + document.getElementById('audioejkaraoke').title;
document.getElementById('audioejkaraoke').value=String.fromCodePoint(128276) + String.fromCodePoint(128276);
document.getElementById('audioejkaraoke').style.position='absolute';
document.getElementById('audioejkaraoke').style.left='0px';
document.getElementById('audioejkaraoke').style.top='0px';
document.getElementById('audioejkaraoke').style.backgroundColor='transparent';
document.getElementById('audioejkaraoke').style.zIndex='99';
document.getElementById('repeat').value=String.fromCodePoint(128276) + String.fromCodePoint(128276);
document.getElementById('repeat').style.position='absolute';
document.getElementById('repeat').style.left='0px';
document.getElementById('repeat').style.top='-10px';
document.getElementById('repeat').style.backgroundColor='transparent';
document.getElementById('repeat').style.zIndex='199';
document.getElementById('myiframe').style.position='absolute';
document.getElementById('myiframe').style.left='-100px';
document.getElementById('myiframe').style.top='-100px';
document.getElementById('myiframe').style.zIndex='299';
//document.getElementById('myiframe').style.backgroundColor='transparent';
document.getElementById('myiframe').style.opacity='0.0';
if (aaconto) {
aaconto.getElementById('player').style.opacity='0.0';
} else {
aaset=true;
}
document.body.style.backgroundColor='transparent';
}
}
}, 1000);
}
if (top.document.getElementById('aja')) {
var boxis=top.document.getElementById('aja').getBoundingClientRect();
//alert('boxis.left=' + boxis.left + ' ' + top.document.getElementById('aja').innerHTML);
if (top.document.getElementById('aja').innerHTML.indexOf('<iframe') == -1) {
//alert('Boxis.left=' + boxis.left);
top.document.getElementById('myja').style.width='' + eval(2 * boxis.width) + 'px';
top.document.getElementById('myja').style.height='' + eval(1 * boxis.height) + 'px';
setTimeout(function(){
top.document.getElementById('aja').innerHTML=top.document.getElementById('myja').outerHTML.replace('/About_Us.html',top.document.getElementById('aja').href).replace(' onload=',' data-onload=').replace(' id=',' data-id=').replace(' name=',' name-id=').replace('none;','inline-block;');
}, 2000);
} else if (3 == 4) {
top.document.getElementById('myja').style.position='absolute';
top.document.getElementById('myja').style.left='' + boxis.left + 'px';
top.document.getElementById('myja').style.top='' + boxis.top + 'px';
top.document.getElementById('myja').style.width='' + boxis.width + 'px';
top.document.getElementById('myja').style.height='' + boxis.height + 'px';
top.document.getElementById('myja').style.display='block';
top.document.getElementById('myja').style.zIndex='99';
//top.document.getElementById('aja').innerHTML='  ';
}
}
}, 1000);
}

if (top.document.URL.indexOf('/esp_ornot_esp.') != -1 || parent.document.URL.indexOf('/esp_ornot_esp.') != -1) {
if (top.document.title.indexOf(' justaudio ') != -1) {
asuffis='&justaudio=&';
bsuffis=' name=justaudio ';
}
}
}

Let’s start with …

Why can’t we just link to a YouTube video URL webpage off any old platform or web browser incarnation?

Well, you could! But we wanted a less obvious approach (and we were not sure about mobile platforms, trying this), only relevant for scenarios where you are only interested in the audio stream of a YouTube video (it should be noted), that is hiding from the reader “the mechanics” of what we are doing (to get a cheap giggle … there, are you happy now?!).

What does Javascript if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { } if test achieve?

If this test returns true we have detected a non-mobile platform/web browser scenario.

What does the HTML target attribute of an a HTML element do?

That target attribute determines the “navigational place” of the href attribute URL of that a link where …

  1. _blank opens in a new window
  2. _self clobbers current window
  3. _top adds a new (tabbed) window (perhaps from the viewpoint of a child HTML iframe window)
  4. other named target point to the name attribute of an HTML iframe element, presumably, in the current window

What does HTML code snippet onload=”if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { if (this.src.indexOf(‘About_Us.’) != -1) { document.getElementById(‘aja’).target=’myja’;
this.src=document.getElementById(‘aja’).href + ‘&rand=’ + Math.floor(Math.random() * 1989786); } } “
do as the onload event logic of the “second version” iframe incarnation?

We decided that we needed to get assistance from our inhouse YouTube video interfacing player, when it came to mobile platforms and web browsers, to get to a point where …

  • unbeknown to such mobile users
  • when they tap the 🔔🔔 “buzzer” button emojis …
  • it is arranged from the child iframe inhouse YouTube video interfacing player web application using “overlay” concepts …
    1. position: absolute
    2. opacity
    3. z-index
    4. top and left positioning
    5. width and height dimensioning
    6. 🔔🔔 into some button content

    … that what they are tapping is a YouTube video element

  • looking like 🔔🔔 at levels of a smaller z-index seen through opacity:0.0 higher z-index levels, the topmost transparent but high z-index one being the YouTube video element which is that webpage area’s “action item” … if you will

Huh?!

On mobile platforms, media cannot play, these days, unless it is as a direct result of a user tap (excluding programmatically produced taps). See all this in action, with thanks to FreeConvert, below …

And so, yes … was it worth it? Perhaps not to do with the job at hand, but for future reference, we’re happy to give this added oompha to this effort.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , | Leave a comment

Tabular Single Row Image Gallery Linking Tutorial

Tabular Single Row Image Gallery Linking Tutorial

Tabular Single Row Image Gallery Linking Tutorial

After yesterday’s Tabular Single Row YouTube Audio or Video Buttons Tutorial work mainly regarding audio and video media, today we return to those …

  • background WordPress Blog random tutorial images … and link them via a modified 404.php creator’s …
    <?php

    if (strpos(('?' . $_SERVER['QUERY_STRING']), '?rand=') !== false) {
    $huht=@file_get_contents('http://www.rjmprogramming.com.au/HTMLCSS/select_palette.php?putrandom=' . urlencode('?rand=' . $_GET['rand'] . '.' . $pnumis . $ptitle));
    }

    ?>
    … calling on …
  • a modified select_palette.php helper …
    <?php

    if (isset($_GET['putrandom'])) {
    $contis=str_replace(' ','++',str_replace('+',' ',urldecode($_GET['putrandom']))) . "\n";
    $xcurgmt=gmdate("Ymd");
    if (!file_exists($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm')) {
    foreach (glob($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . '*.htm') as $dfilename) {
    unlink($dfilename);
    }
    file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm', $contis);
    } else {
    file_put_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm', file_get_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm') . $contis);
    }
    exit;
    } else if (isset($_GET['getrandom'])) {
    $xcurgmt=gmdate("Ymd");
    $imode=0;
    $contis="";
    $idp="";
    $jdp="";
    $pfix="";
    $sfix="";
    if (file_exists($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm')) {
    $contis=file_get_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'media_gallery_swipe_' . $xcurgmt . '.htm');
    if (strlen($_GET['getrandom']) > 0) {
    $relstuffs=explode(str_replace(' ','++',str_replace('+',' ',strtolower(urldecode($_GET['getrandom'])))) . '.', $contis);
    if (sizeof($relstuffs) > 1) {
    $isub=0;
    $jdp=str_replace('rand=','',str_replace(' ','++',str_replace('+',' ',strtolower(urldecode($_GET['getrandom'])))));
    $imode=1;
    while (substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1) >= '0' && substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1) <= '9') {
    if ($imode == 0) {
    $jdp.=substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1);
    } else {
    $idp.=substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1);
    }
    $isub++;
    if (substr(substr($relstuffs[-1 + sizeof($relstuffs)],$isub),0,1) == '.') {
    $imode=1;
    $isub++;
    }
    }
    if (isset($_GET['via'])) {
    $pfix=" if (parent.document.getElementById('" . $_GET['via'] . "')) { parent.document.getElementById('" . $_GET['via'] . "').style.width='100%;'; parent.document.getElementById('" . $_GET['via'] . "').innerHTML+='<iframe style=width:100%;height:800px; src=!!!></iframe>'; } else { ";
    $sfix=" } ";
    }
    if (strtolower(urldecode($_GET['getrandom'])) != urldecode($_GET['getrandom'])) { // Cut to the Chase
    echo "<html><body onload=\"" . str_replace('!!!','/slideshow.html?title=' . explode(" (", explode("\n", explode('=' . $jdp . '.' . $idp, $contis)[1])[0])[0],$pfix) . " parent.window.open('/slideshow.html?title=" . explode(" (", explode("\n", explode('=' . $jdp . '.' . $idp, $contis)[1])[0])[0] . " " . $sfix . " ','_blank','top=200,left=200,width=600,height=600');\"></body></html>";
    exit;
    } else { // WordPress Blog Posting
    echo "<html><body onload=\"" . str_replace('!!!','/ITblog/?p=' . $idp . '#content',$pfix) . " parent.window.open('/ITblog/?p=" . $idp . "#content','_blank','top=200,left=200,width=600,height=600'); " . $sfix . " \"></body></html>";
    exit;
    }
    }
    }
    }
    echo "<html><body><pre>" . $contis . '</pre></body></html>';
    exit;
    }

    ?>
    … called at the parent window by …
  • changed swipe_media.html Tabular Single Row Media Gallery

    function checkmeout(evt, iscuttothechase) {
    if (evt.target.outerHTML.split('>')[0].indexOf('url(') != -1) {
    if (evt.target.outerHTML.split('>')[0].split('url(')[1].split(')')[0].indexOf('?rand=') != -1) {
    if (iscuttothechase) {
    document.getElementById('sparepal').src='/HTMLCSS/select_palette.php?getrandom=' + encodeURIComponent('RAND=' + evt.target.outerHTML.split('>')[0].split('url(')[1].split(')')[0].split('?rand=')[1].split("'")[0].split('"')[0].split(')')[0].split('"')[0]); // + ('&viJUNKa=' + evt.target.id).replace('td','div')
    } else {
    document.getElementById('sparepal').src='/HTMLCSS/select_palette.php?getrandom=' + encodeURIComponent('rand=' + evt.target.outerHTML.split('>')[0].split('url(')[1].split(')')[0].split('?rand=')[1].split("'")[0].split('"')[0].split(')')[0].split('"')[0]); // + ('&viJUNKa=' + evt.target.id).replace('td','div')
    }
    }
    }
    }

… web application, now accepting …

  1. click on one of these WordPress Blog random tutorial images to open window to relevant WordPress Blog posting … or …
  2. right click on one of these WordPress Blog random tutorial images to open window to relevant Cut to the Chase web application or presentation media regarding that blog posting above


Previous relevant Tabular Single Row YouTube Audio or Video Gallery Tutorial is shown below.

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Today we’ve connected …

… which now have three new functionality options …

  • <–> … link to align the (previously) “Brady Bunch” YouTube iframes into a single row in the same web browser tab
  • <–>A+V … call of yesterday’s Media Gallery web application playing our “inhouse” YouTube iframe video playing web application in a new web browser tab
  • <–>A-V … link to our “inhouse” audio stream only YouTube iframe playing functionality in a new web browser tab

… involving changes to …

  • our changed

    var ytlist='';

    if (('' + document.URL + ('' + location.hash)).indexOf('onerow=') != -1) {
    setTimeout(function(){
    var inis='';
    var iwis=document.getElementById('vplayer1').getBoundingClientRect().width;
    var ifsare=document.getElementsByTagName('iframe');
    for (var jtt=0; jtt<ifsare.length; jtt++) {
    //alert(ifsare[jtt].src);
    if (ifsare[jtt].src.indexOf('/embed/') != -1) {
    if (ytlist == '') {
    ytlist='' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    } else {
    ytlist+=',' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    }
    }
    ifsare[jtt].style.width='' + iwis + 'px';
    }
    var toho=document.getElementsByTagName('table')[0];
    var tih=toho.innerHTML;
    var newtih=tih;
    //alert(tih);
    var thingos=tih.split('<tr');
    for (var itt=3; itt>=1; itt--) {
    if (itt == 1) {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('</tr>','<!--/tr-->'));
    } else if (itt == 3) {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('<tr>','<!--tr-->'));
    } else {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('<tr>','<!--tr-->').replace('</tr>','<!--/tr-->'));
    }
    }
    toho.innerHTML=newtih;
    toho.style.width='1000%';
    }, 4000);
    }

    setTimeout(function(){
    var antwo='';
    if (ytlist == '') {
    var ifsare=document.getElementsByTagName('iframe');
    for (var jtt=0; jtt<ifsare.length; jtt++) {
    //alert(ifsare[jtt].src);
    if (ifsare[jtt].src.indexOf('/embed/') != -1) {
    if (ytlist == '') {
    ytlist='' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    } else {
    ytlist+=',' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    }
    }
    }
    }
    if (ytlist != '') {
    antwo+=' <a title="Audio and video plays of YouTube videos" target=_blank href="/HTMLCSS/swipe_media.html?youtube=' + encodeURIComponent(ytlist) + '"><--><sup>A+V</sup></a>';
    antwo+=' <a title="Audio only plays of YouTube videos" target=_blank href="/HTMLCSS/swipe_media.html?audioyoutube=' + encodeURIComponent(ytlist) + '"><--><sub>A-V</sub></a>';
    }
    if (document.URL.indexOf('?') != -1) {
    document.getElementById('wshuffle').innerHTML+=' <a title="Present in one table row" target=_self href="' + document.URL.replace('?', '?onerow=' + Math.floor(Math.random() * 1989786)) + '"><--></a>' + antwo + ' ';
    } else {
    document.getElementById('wshuffle').innerHTML+=' <a title="Present in one table row" target=_self href="' + document.URL + '?onerow=' + Math.floor(Math.random() * 1989786) + '"><--></a>' + antwo + ' ';
    }
    }, 9000);

    youtube_brady_bunch.js being used in our inhouse Disco web application “peer to peer suite” web application “grandparent” level example …
  • “second draft” swipe_media.html Tabular Single Row Image Gallery web application


Previous relevant Tabular Single Row Image Gallery Primer Tutorial is shown below.

Tabular Single Row Image Gallery Primer Tutorial

Tabular Single Row Image Gallery Primer Tutorial

“Tabular Single Row Image Gallery” …

Smabular Single Row Image Gallery

… we’re sure is the reaction of some readers out there, to today’s “starting draft” for an idea we had. Today’s part of the jigsaw we want to explore may be “ho hum” and “so non-mobile”, but we’re hoping the thread appeals to more modern ideas as we go along.

So much for the apologies, and so let’s now look at the basis to this start …

  • media (so far just image) …
  • gallery … presented in …
  • table … HTML element … in …
  • single tr row
  • deliberately overflowing to the right of the screen view of the webpage … and so …
  • scrollable (ie. window scrollable) to … those right hand parts …
  • only “media loaded” …
  • as “scrolled to” or “stumbled upon”

So far the window scrollable detection goes (thanks to this useful link) …


window.onscroll = function (e) {
// called when the window is scrolled.
vspos4=document.body.scrollTop;
vspos3=document.body.scrollLeft;
var vstdn=Math.ceil(eval('' + vspos3) / eval('' + amin));
if (curtdn != vstdn) {
checkthen(vstdn);
}
}

… and the CSS produced “wording (ie. non-media) content” is produced down the bottom left of “inhouse WordPress Blog image cell background” ( possible because of background-size:contain ) we think is interesting …


<style>
td {
border: 1px dotted green;
}

.inhouse {
vertical-align: bottom;
padding-bottom: 20px;
}

.inhouse::after {
content: 'Media Gallery \a RJM Programming \a August, 2025 \a Thanks to Lorem Picsum at https://picsum.photos/ \a ' attr(alt);
white-space: pre-wrap;
}

</style>

… in a “first draft” Tabular Single Row Image Gallery web application for your perusal. Thanks to Lorem Picsum regarding, as so often happens for us, when we’d like beautiful random images to be involved with web applications!

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Tabular Single Row YouTube Audio or Video Buttons Tutorial

Tabular Single Row YouTube Audio or Video Buttons Tutorial

Tabular Single Row YouTube Audio or Video Buttons Tutorial

From Tabular Single Row YouTube Audio or Video Gallery Tutorial we had …

… and this could be good having a reciprocal arrangement, and today we’ve started down that road (though, around here, it worries us a little that we keep going on roads heading down?!)

It’s the background-size:contain helping out, again, here, with some room down the bottom of the webpage screen to add 3×2 = 6 buttons for …

      

… reciprocal connections in “third draft” swipe_media.html Tabular Single Row Image Gallery web application.


Previous relevant Tabular Single Row YouTube Audio or Video Gallery Tutorial is shown below.

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Today we’ve connected …

… which now have three new functionality options …

  • <–> … link to align the (previously) “Brady Bunch” YouTube iframes into a single row in the same web browser tab
  • <–>A+V … call of yesterday’s Media Gallery web application playing our “inhouse” YouTube iframe video playing web application in a new web browser tab
  • <–>A-V … link to our “inhouse” audio stream only YouTube iframe playing functionality in a new web browser tab

… involving changes to …

  • our changed

    var ytlist='';

    if (('' + document.URL + ('' + location.hash)).indexOf('onerow=') != -1) {
    setTimeout(function(){
    var inis='';
    var iwis=document.getElementById('vplayer1').getBoundingClientRect().width;
    var ifsare=document.getElementsByTagName('iframe');
    for (var jtt=0; jtt<ifsare.length; jtt++) {
    //alert(ifsare[jtt].src);
    if (ifsare[jtt].src.indexOf('/embed/') != -1) {
    if (ytlist == '') {
    ytlist='' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    } else {
    ytlist+=',' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    }
    }
    ifsare[jtt].style.width='' + iwis + 'px';
    }
    var toho=document.getElementsByTagName('table')[0];
    var tih=toho.innerHTML;
    var newtih=tih;
    //alert(tih);
    var thingos=tih.split('<tr');
    for (var itt=3; itt>=1; itt--) {
    if (itt == 1) {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('</tr>','<!--/tr-->'));
    } else if (itt == 3) {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('<tr>','<!--tr-->'));
    } else {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('<tr>','<!--tr-->').replace('</tr>','<!--/tr-->'));
    }
    }
    toho.innerHTML=newtih;
    toho.style.width='1000%';
    }, 4000);
    }

    setTimeout(function(){
    var antwo='';
    if (ytlist == '') {
    var ifsare=document.getElementsByTagName('iframe');
    for (var jtt=0; jtt<ifsare.length; jtt++) {
    //alert(ifsare[jtt].src);
    if (ifsare[jtt].src.indexOf('/embed/') != -1) {
    if (ytlist == '') {
    ytlist='' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    } else {
    ytlist+=',' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    }
    }
    }
    }
    if (ytlist != '') {
    antwo+=' <a title="Audio and video plays of YouTube videos" target=_blank href="/HTMLCSS/swipe_media.html?youtube=' + encodeURIComponent(ytlist) + '"><--><sup>A+V</sup></a>';
    antwo+=' <a title="Audio only plays of YouTube videos" target=_blank href="/HTMLCSS/swipe_media.html?audioyoutube=' + encodeURIComponent(ytlist) + '"><--><sub>A-V</sub></a>';
    }
    if (document.URL.indexOf('?') != -1) {
    document.getElementById('wshuffle').innerHTML+=' <a title="Present in one table row" target=_self href="' + document.URL.replace('?', '?onerow=' + Math.floor(Math.random() * 1989786)) + '"><--></a>' + antwo + ' ';
    } else {
    document.getElementById('wshuffle').innerHTML+=' <a title="Present in one table row" target=_self href="' + document.URL + '?onerow=' + Math.floor(Math.random() * 1989786) + '"><--></a>' + antwo + ' ';
    }
    }, 9000);

    youtube_brady_bunch.js being used in our inhouse Disco web application “peer to peer suite” web application “grandparent” level example …
  • “second draft” swipe_media.html Tabular Single Row Image Gallery web application


Previous relevant Tabular Single Row Image Gallery Primer Tutorial is shown below.

Tabular Single Row Image Gallery Primer Tutorial

Tabular Single Row Image Gallery Primer Tutorial

“Tabular Single Row Image Gallery” …

Smabular Single Row Image Gallery

… we’re sure is the reaction of some readers out there, to today’s “starting draft” for an idea we had. Today’s part of the jigsaw we want to explore may be “ho hum” and “so non-mobile”, but we’re hoping the thread appeals to more modern ideas as we go along.

So much for the apologies, and so let’s now look at the basis to this start …

  • media (so far just image) …
  • gallery … presented in …
  • table … HTML element … in …
  • single tr row
  • deliberately overflowing to the right of the screen view of the webpage … and so …
  • scrollable (ie. window scrollable) to … those right hand parts …
  • only “media loaded” …
  • as “scrolled to” or “stumbled upon”

So far the window scrollable detection goes (thanks to this useful link) …


window.onscroll = function (e) {
// called when the window is scrolled.
vspos4=document.body.scrollTop;
vspos3=document.body.scrollLeft;
var vstdn=Math.ceil(eval('' + vspos3) / eval('' + amin));
if (curtdn != vstdn) {
checkthen(vstdn);
}
}

… and the CSS produced “wording (ie. non-media) content” is produced down the bottom left of “inhouse WordPress Blog image cell background” ( possible because of background-size:contain ) we think is interesting …


<style>
td {
border: 1px dotted green;
}

.inhouse {
vertical-align: bottom;
padding-bottom: 20px;
}

.inhouse::after {
content: 'Media Gallery \a RJM Programming \a August, 2025 \a Thanks to Lorem Picsum at https://picsum.photos/ \a ' attr(alt);
white-space: pre-wrap;
}

</style>

… in a “first draft” Tabular Single Row Image Gallery web application for your perusal. Thanks to Lorem Picsum regarding, as so often happens for us, when we’d like beautiful random images to be involved with web applications!

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Tabular Single Row YouTube Audio or Video Gallery Tutorial

Today we’ve connected …

… which now have three new functionality options …

  • <–> … link to align the (previously) “Brady Bunch” YouTube iframes into a single row in the same web browser tab
  • <–>A+V … call of yesterday’s Media Gallery web application playing our “inhouse” YouTube iframe video playing web application in a new web browser tab
  • <–>A-V … link to our “inhouse” audio stream only YouTube iframe playing functionality in a new web browser tab

… involving changes to …

  • our changed

    var ytlist='';

    if (('' + document.URL + ('' + location.hash)).indexOf('onerow=') != -1) {
    setTimeout(function(){
    var inis='';
    var iwis=document.getElementById('vplayer1').getBoundingClientRect().width;
    var ifsare=document.getElementsByTagName('iframe');
    for (var jtt=0; jtt<ifsare.length; jtt++) {
    //alert(ifsare[jtt].src);
    if (ifsare[jtt].src.indexOf('/embed/') != -1) {
    if (ytlist == '') {
    ytlist='' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    } else {
    ytlist+=',' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    }
    }
    ifsare[jtt].style.width='' + iwis + 'px';
    }
    var toho=document.getElementsByTagName('table')[0];
    var tih=toho.innerHTML;
    var newtih=tih;
    //alert(tih);
    var thingos=tih.split('<tr');
    for (var itt=3; itt>=1; itt--) {
    if (itt == 1) {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('</tr>','<!--/tr-->'));
    } else if (itt == 3) {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('<tr>','<!--tr-->'));
    } else {
    inis='<tr' + thingos[itt].split('</tr>')[0] + '</tr>';
    newtih=newtih.replace(inis, inis.replace('<tr>','<!--tr-->').replace('</tr>','<!--/tr-->'));
    }
    }
    toho.innerHTML=newtih;
    toho.style.width='1000%';
    }, 4000);
    }

    setTimeout(function(){
    var antwo='';
    if (ytlist == '') {
    var ifsare=document.getElementsByTagName('iframe');
    for (var jtt=0; jtt<ifsare.length; jtt++) {
    //alert(ifsare[jtt].src);
    if (ifsare[jtt].src.indexOf('/embed/') != -1) {
    if (ytlist == '') {
    ytlist='' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    } else {
    ytlist+=',' + ifsare[jtt].src.split('/embed/')[1].substring(0,11);
    }
    }
    }
    }
    if (ytlist != '') {
    antwo+=' <a title="Audio and video plays of YouTube videos" target=_blank href="/HTMLCSS/swipe_media.html?youtube=' + encodeURIComponent(ytlist) + '"><--><sup>A+V</sup></a>';
    antwo+=' <a title="Audio only plays of YouTube videos" target=_blank href="/HTMLCSS/swipe_media.html?audioyoutube=' + encodeURIComponent(ytlist) + '"><--><sub>A-V</sub></a>';
    }
    if (document.URL.indexOf('?') != -1) {
    document.getElementById('wshuffle').innerHTML+=' <a title="Present in one table row" target=_self href="' + document.URL.replace('?', '?onerow=' + Math.floor(Math.random() * 1989786)) + '"><--></a>' + antwo + ' ';
    } else {
    document.getElementById('wshuffle').innerHTML+=' <a title="Present in one table row" target=_self href="' + document.URL + '?onerow=' + Math.floor(Math.random() * 1989786) + '"><--></a>' + antwo + ' ';
    }
    }, 9000);

    youtube_brady_bunch.js being used in our inhouse Disco web application “peer to peer suite” web application “grandparent” level example …
  • “second draft” swipe_media.html Tabular Single Row Image Gallery web application


Previous relevant Tabular Single Row Image Gallery Primer Tutorial is shown below.

Tabular Single Row Image Gallery Primer Tutorial

Tabular Single Row Image Gallery Primer Tutorial

“Tabular Single Row Image Gallery” …

Smabular Single Row Image Gallery

… we’re sure is the reaction of some readers out there, to today’s “starting draft” for an idea we had. Today’s part of the jigsaw we want to explore may be “ho hum” and “so non-mobile”, but we’re hoping the thread appeals to more modern ideas as we go along.

So much for the apologies, and so let’s now look at the basis to this start …

  • media (so far just image) …
  • gallery … presented in …
  • table … HTML element … in …
  • single tr row
  • deliberately overflowing to the right of the screen view of the webpage … and so …
  • scrollable (ie. window scrollable) to … those right hand parts …
  • only “media loaded” …
  • as “scrolled to” or “stumbled upon”

So far the window scrollable detection goes (thanks to this useful link) …


window.onscroll = function (e) {
// called when the window is scrolled.
vspos4=document.body.scrollTop;
vspos3=document.body.scrollLeft;
var vstdn=Math.ceil(eval('' + vspos3) / eval('' + amin));
if (curtdn != vstdn) {
checkthen(vstdn);
}
}

… and the CSS produced “wording (ie. non-media) content” is produced down the bottom left of “inhouse WordPress Blog image cell background” ( possible because of background-size:contain ) we think is interesting …


<style>
td {
border: 1px dotted green;
}

.inhouse {
vertical-align: bottom;
padding-bottom: 20px;
}

.inhouse::after {
content: 'Media Gallery \a RJM Programming \a August, 2025 \a Thanks to Lorem Picsum at https://picsum.photos/ \a ' attr(alt);
white-space: pre-wrap;
}

</style>

… in a “first draft” Tabular Single Row Image Gallery web application for your perusal. Thanks to Lorem Picsum regarding, as so often happens for us, when we’d like beautiful random images to be involved with web applications!

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Tabular Single Row Image Gallery Primer Tutorial

Tabular Single Row Image Gallery Primer Tutorial

Tabular Single Row Image Gallery Primer Tutorial

“Tabular Single Row Image Gallery” …

Smabular Single Row Image Gallery

… we’re sure is the reaction of some readers out there, to today’s “starting draft” for an idea we had. Today’s part of the jigsaw we want to explore may be “ho hum” and “so non-mobile”, but we’re hoping the thread appeals to more modern ideas as we go along.

So much for the apologies, and so let’s now look at the basis to this start …

  • media (so far just image) …
  • gallery … presented in …
  • table … HTML element … in …
  • single tr row
  • deliberately overflowing to the right of the screen view of the webpage … and so …
  • scrollable (ie. window scrollable) to … those right hand parts …
  • only “media loaded” …
  • as “scrolled to” or “stumbled upon”

So far the window scrollable detection goes (thanks to this useful link) …


window.onscroll = function (e) {
// called when the window is scrolled.
vspos4=document.body.scrollTop;
vspos3=document.body.scrollLeft;
var vstdn=Math.ceil(eval('' + vspos3) / eval('' + amin));
if (curtdn != vstdn) {
checkthen(vstdn);
}
}

… and the CSS produced “wording (ie. non-media) content” is produced down the bottom left of “inhouse WordPress Blog image cell background” ( possible because of background-size:contain ) we think is interesting …


<style>
td {
border: 1px dotted green;
}

.inhouse {
vertical-align: bottom;
padding-bottom: 20px;
}

.inhouse::after {
content: 'Media Gallery \a RJM Programming \a August, 2025 \a Thanks to Lorem Picsum at https://picsum.photos/ \a ' attr(alt);
white-space: pre-wrap;
}

</style>

… in a “first draft” Tabular Single Row Image Gallery web application for your perusal. Thanks to Lorem Picsum regarding, as so often happens for us, when we’d like beautiful random images to be involved with web applications!

If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , | Leave a comment

Write Like You Render Primer Tutorial

Write Like You Render Primer Tutorial

Write Like You Render Primer Tutorial

The recent goings on with the YouTube Style SubRip Subtitles Button Tutorial thread of blog postings, uncovering for us the wonders of the great DOMParser Web API, has inspired us to write, again, a new HTML validator web application, just on the clientside of the “webpage equation”.

If you are into the creation of HTML on a Content Management System such as WordPress, here, with this blog, there is some forgiveness regarding what you construct as your content HTML and allowing that through to webpage content. But perhaps you’d …

Like to write the HTML as the web browser sees it, and then renders it

It mattered, a lot, in that project above, because for that project’s “collaboration purposes”, in the code, we wanted to know that HTML content in the caption data relevant “shadowing” textarea or textbox user interfacing elements would match any HTML element “innerHTML” or “outerHTML” or “innerText” reference later accessed. Any missing double quote mattered in this scenario. But, of course, it would be good as general practice for a Content Management System produced set of HTML to get close to that ideal HTML the web browser syntax in it’s form and format.

Which brings us to today’s …


Write Like You Render

… web application HTML validator “first draft” write_like_you_render.html with the starring codelines …


var newh=new DOMParser().parseFromString(inhtml, "text/html"); // thanks to https://stackoverflow.com/questions/57074776/parse-html-string-to-dom-and-convert-it-back-to-string
var newht=('' + newh.body.innerHTML);

… you can try for yourself here or below …

If this was interesting you may be interested in this too.

Posted in Coding, eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , | Leave a comment

Co-ordinate Cursor Mercator Projection External Javascript Tutorial

Co-ordinate Cursor Mercator Projection External Javascript Tutorial

Co-ordinate Cursor Mercator Projection External Javascript Tutorial

For describing where you are on Earth humans have set up the …


Longitude,Latitude

(usually measured in degrees, especially in Mbeya and Madrid) system of describing positions, and on a Mercator Projection (ie. at school, the ones showing Greenland huge (when it is, in actuality, roughly, similar in surface area to Saudi Arabia)) that globe is slapped onto a 2d rectangular sheet of map (like perfectly peeling an apple but fixing up the tears in forming a rectangle, sort of), if you will …


360,-180

… wide,high starting up at the top left of that rectangle with Longitude,Latitude …


-180,90

… degrees. We’re saying the height is -180 because down the bottom right of this Mercator Projection arrangement the Longitude,Latitude is …


180,-90

Knowing all this and working out the webpage stuff as per usual we can, with a call, now catered for …


function xmap(inidx) {
var outidx=eval('' + inidx);
if (geno) {
if (altotherx != 0.0 || altothery != 0.0 || altoriginx != 0.0 || altoriginy != 0.0 || altscalex != 1.0) {
outidx=('' + eval(eval('' + altoriginx) + (eval('' + inidx) - eval('' + genoriginx)) * eval('' + altscalex)).toPrecision(15));
//document.title='' + inidx + ' fixed=' + (eval('' + inidx) - eval('' + genoriginx)) + ' then ' + outidx;
if (outidx.indexOf('.') != -1) {
return outidx.split('.')[0] + '.' + outidx.split('.')[1].substring(0,2).replace(/0$/g,String.fromCodePoint(176));
}
return outidx.replace(/0$/g,String.fromCodePoint(176));
//} else {
// alert('Oops');
}
}
return inidx;
}

function ymap(inidy) {
var outidy=eval('' + inidy);
if (geno) {
if (altotherx != 0.0 || altothery != 0.0 || altoriginx != 0.0 || altoriginy != 0.0 || altscaley != 1.0) {
outidy=('' + eval(eval('' + altoriginy) + (eval('' + inidy) - eval('' + genoriginy)) * eval('' + altscaley)).toPrecision(15));
if (outidy.indexOf('.') != -1) {
return outidy.split('.')[0] + '.' + outidy.split('.')[1].substring(0,2).replace(/0$/g,String.fromCodePoint(176));
}
return outidy.replace(/0$/g,String.fromCodePoint(176));
}
}
return inidy;
}

… in a changed lefttopcursor.js external Javascript call of the ilk …


<script type=text/javascript src='//www.rjmprogramming.com.au/lefttopcursor.js?rand=876538765&scp=1F310&type=img&tl=-180,90&wh=360,-180'></script>

… affecting, further to yesterday’s Co-ordinate Cursor External Javascript Primer Tutorial, as per …

… to improve these web applications.


Previous relevant Co-ordinate Cursor External Javascript Primer Tutorial is shown below.

Co-ordinate Cursor External Javascript Primer Tutorial

Co-ordinate Cursor External Javascript Primer Tutorial

Today we’re taking what we learnt regarding …

co-ordinated cursors

(only regarding non-mobile platforms, alas) we implemented via the document.body onmousemove event logics in the recent Animated Plane Refuel Game Tutorial, and creating new external Javascript useful calleetool whereby …

  • not needing to implement it for that project above (except before launching into it making responsive design percentage friendly units into the mix via a changed “latest draft” Animated Plane Plane Refuel Game web application below), but doing a quick check to see that even if you did, the external Javascript would know enough to “lay off” … and ….
  • try out on yesterday’s Background Blend Mode Example web application (and which, eventually, we said “What the heck, so what if it gets an inapt cursor?!” and ended up creating a “second draft”) calling this new lefttopcursor.js external Javascript … via …

    <script type=text/javascript src='//www.rjmprogramming.com.au/lefttopcursor.js?scp=26fd'></script>

    … as an example call implementing cursor text with the ⛽ fuel pump emoji mentioned, on our macOS MAMP local Apache/PHP/MySql web server, and you can see working within today’s animated GIF presentation
  • try out on our changed do_away_with_the_boring_bits.html Try Your Own HTML web application‘s iframe HTML validator using it’s srcdoc

    <iframe srcdoc="<html><head><script type=text/javascript src='//www.rjmprogramming.com.au/lefttopcursor.js?rand=7635476'></script></head><body style=width:100%;height:650px;> </body></html>" data-src='about:blank' name='ihtmlcontent' id='ihtmlcontent' style='z-index:99;height:650px; background-color:lightblue;'></iframe>

    … attribute

… all happening.

It being external Javascript we wanted to see it working from a localhost web browser address bar URL call, and it did, making it a tool, to our mind.


Previous relevant Animated Plane Refuel Game Tutorial is shown below.

Animated Plane and Coconut Hunt Game Nuances Tutorial

Animated Plane Refuel Game Tutorial

Today we wondered how best to involve the …

  • plane … mainly, but perhaps also the …
  • gymnast … with a guest starring role …

… in an online game in our recent Animated Plane and Coconut Hunt Game Nuances Tutorial‘s web application, because their existence to do with Hunt Games seems a bit obscure.

And so, we thought, you see those games where characters get strength by picking up objects they “run into” or “run over” and we thought …

Plane Refuel Game

(where the longer the flight survives the more skillful the player) as a result of that thinking, plus being able to find an apt emoji ⛽ for the fuel pump we wanted to base the game around, along with an HTML progress element to inform the user regarding how much fuel is left, in a changed “latest draft” Animated Plane Plane Refuel Game web application below!


Previous relevant Animated Plane and Coconut Hunt Game Nuances Tutorial is shown below.

Animated Plane and Coconut Hunt Game Nuances Tutorial

Animated Plane and Coconut Hunt Game Nuances Tutorial

Today’s a day of nuanced progress, after yesterday’s Coconut Hunt Game Tutorial‘s “filling in sideways” work on our Animated Plane and Coconut Hunt Game web application. Today, we …

  • fixed some document.body.title annoyances whereby it would appear too often
  • worked on the default A option textarea via …
    1. some “panda 🐼 led recovery” modelling of a p emoji usage (with animation) and span emoji usage (without animation) … and …
    2. modelling of how iframe onload event can be used to develop dynamic Javascript (the default example changing the coconut 🥥 hunt into a bear 🐻 hunt?!) … as opposed to a document.createElement(‘script’) alternative approach
  • fixed some window.open too small size annoyances
  • allowed for screen co-ordinates cursor (on non-mobile), via onmousemove event logic, to assist intrepid users going above and beyond “overlay” positioning their own elements via position:absolute; left:?; top:?; in A option textareas
  • allowed for toggling of non-mobile cursor between as above and crosshair via right click
  • allowed for the last left:?; top:?; as above detected be remembered and involve itself as the default position:absolute; “overlay” positioning of the A option textarea default “panda 🐼 led recovery” emoji of above
  • allow for 8 seconds of time for a user to change default coconut 🥥 emoji to some other text via contenteditable=true ahead of the Hunt Game starting … thanks to this useful link regarding hiding a contenteditable=true focus border
  • allow for sharing of the Hunt Game
  • Hunt Game sound effects

Feel free to try these tweaks to our Animated Plane and Coconut Hunt Game, in a nuanced “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Coconut Hunt Game Tutorial is shown below.

Coconut Hunt Game Tutorial

Coconut Hunt Game Tutorial

Are you a reader who has been amused or bemused by the word Game being in the blog posting titles lately, up to yesterday’s Animated Plane Game User Animations and Styling Tutorial, when No Game really, about any of it? Well, today, it’s …

Game On

Do you like coconuts? Can I ask you, have you ever looked into a coconut, and asked yourself …

I shell always love you.

? Well, have we got the game for you?! Start the ball rollingshell shaking via the first click/top on the coconut fallen from the tree. And from there, it’s a fast reactions game, to score well! Good luck, in the changed “latest draft” Animated Plane Coconut Hunt Game web application below!


Previous relevant Animated Plane Game User Animations and Styling Tutorial is shown below.

Animated Plane Game User Animations and Styling Tutorial

Animated Plane Game User Animations and Styling Tutorial

On top of yesterday’s Animated Plane Game User Content Sharing Tutorial‘s honing in on the five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… today we wanted to offer two more user controllable parts to this Animated Plane Game web application, those being …

  • CSS styling … easy, as CSS can be dynamically added to a web application at the clientside, as the Javascript is executing … and, a bit more of a learning curve for beginners is …
  • user animations … we’re envisaging, in it’s “easiest to understand encapsulation for a newbie” uses …
    1. @keyframes
    2. transition

    … a whole big wooooorrrrlllldddd of animation study just by itself (and in order for modelling to, perhaps, help we used an example from this excellent link, thanks, as the default option A textarea usage model)

… but a hell of a lot easier for a user to establish than some arcane Javascript DOM animations involving setTimeout or setInterval timers?!

For these two new ideas, popup textarea windows appear to give the user plenty of space to play around in. As ever, email and SMS can follow up for that user to share with others what their animation ideas are, perhaps far removed from the original plane and gymnast scenario by the time they finish. And here it may be pertinent to point out that even using hashtag emailing (and even more so with SMSing) there must be message size limits that will stop you event-u-al-ly!

Try this in the changed “latest draft” Animated Plane Game web application below.

Did you know?

In yesterday’s “noun” work we talked about “content” defined by the user in terms of real references to media data URIs or URLs. Well, the other way a user can now affect “content” is via CSS. Below we make the plane and gymnast disappear via the C (for CSS styling) option (that can take you to a popup window textarea where you can Apply this) …


<style>
#myif { /* plane */
display:none; /* other choice could be visibility:hidden; */
}

#mytwoif { /* gymnast */
visibility:hidden; /* other choice could be display:none; */
}
</style>


Previous relevant Animated Plane Game User Content Sharing Tutorial is shown below.

Animated Plane Game User Content Sharing Tutorial

Animated Plane Game User Content Sharing Tutorial

Yesterday’s Animated Plane Game Primer Tutorial set up five “nouns” of interest …

  • trees
  • plane
  • gymnast
  • clouds
  • ground

… each of which has a relationship to a piece of media content. The border-image (ie. ground) content aspects we allow a user to define emoji text for, but the rest are associated with a data URI or URL.

Today’s work is to allow the user to specify these “content” data items themselves, as well as share this via email or SMS to another user, with those user “content” data items recreated for the recipient user clicking the email or SMS link containing those hashtagged user data components. Later we hope to expand the functionality more, from today’s …


function getsrc(fromoh) {
var forvpre='Currently this content points at ... ' + String.fromCharCode(10);
var forvsuf=String.fromCharCode(10) + 'Enter an alternative content URL (can be clipart style data URI you see often using Google Image (Copy Image Address via right click) Searches) ... or ... ' + String.fromCharCode(10) + String.fromCharCode(10) + '1[:URL] for trees, 2[:URL] for plane, 3[:URL] for gymnast, 4[:URL] for clouds, 5[:emoji(s)] for ground, E for email, S for SMS';
if (fromoh.indexOf(' src="//') != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=//") != -1) {
return forvpre + document.URL.split('//')[0] + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
} else if (fromoh.indexOf(' src="') != -1) {
return forvpre + fromoh.split(' src="')[1].split('"')[0] + forvsuf;
} else if (fromoh.indexOf(" src='") != -1) {
return forvpre + fromoh.split(" src='")[1].split("'")[0] + forvsuf;
} else if (fromoh.indexOf(" src=") != -1) {
return forvpre + fromoh.split(" src=")[1].split(" ")[0].split(">")[0] + forvsuf;
}
return fromoh;
}

function yourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=prompt(getsrc(ino.outerHTML), '');
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;


case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

function anyprompt(opsd) {
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
}
}

function ourprompt(ino, intlis) {
var ei=-1, si=-1;
isac=true;
var opsd=null;
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
opsd=prompt(intlis + String.fromCharCode(10) + String.fromCharCode(10) + intlis, '');
} else {
opsd=prompt(getsrc(document.getElementById('myimg').outerHTML), '');
}
if (opsd == null) { isac=false; return false; }
if (opsd.trim() != '') {
opsd=opsd;
switch (opsd.substring(0,1).toLowerCase().replace('+','s')) {
case '1': // trees
if ((opsd + ' ').substring(0,2) == '1:') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + (opsd + ' ').substring(2) + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where trees are.', '');
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
}
break;

case '2': // plane
if ((opsd + ' ').substring(0,2) == '2:') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where plane is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
planealt='&planealt=' + encodeURIComponent(opsd);
document.getElementById('myif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '3': // gymnast
if ((opsd + ' ').substring(0,2) == '3:') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps clipart via Google image search) data URI or URL suiting where gymnast is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
gymnastalt='&gymnastalt=' + encodeURIComponent(opsd);
document.getElementById('mytwoif').style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '4': // clouds
if ((opsd + ' ').substring(0,2) == '4:') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + ((opsd + ' ').substring(2)).replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
} else {
opsd=prompt('Enter your (perhaps via Google image search) data URI or URL suiting where cloud background image is.', '');
if (opsd != null) {
if (opsd.trim() != '') {
cloudsalt='&cloudsalt=' + encodeURIComponent(opsd);
document.body.style.backgroundImage='url(' + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + ')';
}
}
}
break;

case '5': // ground
if ((opsd + ' ').substring(0,2) == '5:') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + (opsd + ' ').substring(2) + suffixbiu + '") !important; </sty' + 'le>'
} else {
opsd=prompt('Enter your (probably quite long) emoji (we are guessing) border image text.', '');
if (opsd != null) {
if (opsd != '') {
groundalt='&groundalt=' + encodeURIComponent(opsd);
document.body.innerHTML+='<sty' + 'le> body { border-image:url("' + prefixbiu + opsd.replace(/^http\:/g,'').replace(/^https\:/g,'') + suffixbiu + '") !important; </sty' + 'le>'
} else {
groundalt='&groundalt='; // + encodeURIComponent(opsd);
document.body.style.borderImage='none';
document.body.style.borderBottom='1px solid transparent';
document.body.style.borderBottomWidth='0px';
//document.body.innerHTML+='<sty' + 'le> body { border-bottom-width:0px !important; } </sty' + 'le>';
}
}
}
break;

case 'e': // email
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.trim().indexOf('@') != -1) {
anchor.href = 'mailto:' + opsd.split('@')[0].split(' ')[eval(-1 + opsd.split('@')[0].split(' ').length)] + opsd.split(opsd.split('@')[0])[1].split(' ')[0] + '?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'mailto:?subject=My%20Animation&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

case 's': // SMS
opsd=opsd.replace(/\:/g,' ');
anchor = document.createElement('a');
if (opsd.substring(0,1).toLowerCase() == '+') {
anchor.href = 'sms:' + opsd.split(' ')[0] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else if (opsd.indexOf(' ') != -1) {
anchor.href = 'sms:' + opsd.split(' ')[eval(-1 + opsd.split(' ').length)] + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
} else {
anchor.href = 'sms:&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?rand=' + Math.floor(Math.random() * 19897865) + '#' + treesalt + planealt + gymnastalt + cloudsalt + groundalt);
}
anchor.style.display='none';
document.body.appendChild(anchor);
anchor.innerHTML='Email';
anchor.target='_top';
anchor.click();
break;

default:
if (opsd != null) {
if (opsd.trim() != '') {
treesalt='&treesalt=' + encodeURIComponent(opsd);
document.getElementById('myimg').src=('' + opsd + '').replace(/^http\:/g,'').replace(/^https\:/g,'');
}
}
break;
}
} else {
setTimeout(function(){ ino.click(); }, 100); return true;
}
isac=false;
return false;
}

… in the changed “eighth draft” Animated Plane Game web application.


Previous relevant Animated Plane Game Primer Tutorial is shown below.

Animated Plane Game Primer Tutorial

Animated Plane Game Primer Tutorial

The mix-blend-mode:multiply; discoveries (along with those naive previous usage without realizing it’s implications) we made creating Periodic Table Image Map Primer Tutorial recently has opened up new “vistas of possibility” (VOP, of course) for us, and has inspired us to give “just Javascript and CSS and HTML animated games” (aided in large part by clipart free content components) another go …

… with a “widget feel” now realizable, for us, knowing that white backgrounded HTML iframe content no longer has to hold us back piecing together animations (in an “OOP feeling” way) consisting of …

  • base webpage CSS and HTML and Javascript (DOM, also helping out the control of) …
  • HTML iframe components (and in our case the image content is it’s background image with background-size:contain; and background-repeat:no-repeat; along with a specific iframe width and height) for any one “noun” (or class of object) in your game storyboard … if you will … if you will … if you will … and …
  • HTML img components in a similar vein … but today’s trees did not need mix-blend-mode:multiply; because the originator made the background transparent (ie. another option with all this “animated pieces thinking”)

Animation(s) can be CSS @keyframe transitions (though not yet with animation above) or Javascript DOM logic via setTimeout (or setInterval) timers or animated GIF/webp content or, we daresay, many other approaches.

We’re going to tabularize below “how we got to the result above” below …

We started with a “first draft” … getting Freepik image plane image animated with a rudimentary green border-bottom representing the ground …
then to “second draft” … adding https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background to go with edited Freepik image because mix-blend-mode:multiply will not mask out the non heterogenous bluish clouds in the image …
then to “third draft” … tweaking https://i.makeagif.com/media/8-11-2023/Xu_roP.gif animated GIF cloud background … …
then to “fourth draft” … establishing an SVG+XML (with SVG text emoji content) border-image for the bottom border representing the ground …
then to “fifth draft” … added acknowledgements for all the help …

Thanks to Image by brgfx on Freepik and https://i.makeagif.com/media/8-11-2023/Xu_roP.gif and https://procul.org/images/2025/Animated-Clouds-Gif/ and and https://au.pinterest.com/pin/587930926347995281/ and https://giphy.com/explore/trees-swaying-stickers

then to “sixth draft” … added https://au.pinterest.com/pin/587930926347995281/ animated GIF gymnast background and thereby proving that overlapping “iframe widgets” (helped out by mix-blend-mode:multiply presumably) was possible, and important …
then to “seventh draft” … added https://giphy.com/explore/trees-swaying-stickers giphy.com/explore/trees-swaying-stickers animated (and transparently backgrounded) webp swaying trees image along with tweaked Freepik image now animated GIF to animate the plane itself a little, in place, separate to the Javascript DOM based animation moving across the screen … for today’s final draft …

Stop Press

In tomorrow’s installment we allow for user defined content, and sharing, as per …

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment