As mentioned with yesterdayโs Just Javascript Five Hundred Card Game Kitty Logic Tutorial, today is an aesthetics day regarding dropdown option colours (not so flexible) and emojis (a tiny bit better). Okay, so the card emojis have no inherent colour, but we had mixed success researching a red diamond (yes) and a red heart (no) suit emoji โrednessโ solution.
Also, we restricted some bidding button email click options by turning input type=submit into input type=button (ie. no navigation but looks the same) for bids that become too low to be valid in the context of the 500 card game.
So please join us on our โ500 card gameโ (getting ever closer to a) non-hybrid journey with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Kitty Logic Tutorial is shown below.
Adding to yesterdayโs Just Javascript Five Hundred Card Game Remote Kitty Tutorial weโve concluded โฆ
Thereโs got to be some logic to what Kitty does?
โฆ surely?!
And so we want to see if there are some aesthetic improvements (and user experience improvements restricting some poor button presses) to the emails, for tomorrowโs work, containing those dropdowns within the โฆ
- remote player kitty logic โฆ and distinct from todayโs push to resolve โฆ
- non-remote player kitty logic
โฆ involving that twin bidding/kitty Javascript prompt window ask after three pass answers from bidding players.
Please join us on our โ500 card gameโ (getting ever closer to a) non-hybrid journey with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Remote Kitty Tutorial is shown below.
On top of yesterdayโs Just Javascript Five Hundred Card Game Kitty Setup Tutorial, today weโve been concentrating on the scenario of remote email players and the winning bidder working the kitty.
Then, it occurred to us during this, that where we said yesterday โฆ
where you may discern that the trigger to move on is 4 โpassโ bids in a row
โฆ that in so doing we were adding an unnecessary ask (perhaps) into the โequationโ of how the โ500 card gameโ operates, in that on the third โpassโ bid we get back to the last successful bidder anyway, so why not offer them the chance to do either โฆ
- define their kitty swaps (as they won the bidding), and then click on their opening card placement for the first card of the first trick โฆ or, we could not remember exactly the rules, but โฆ
- also allow them to up their own last bid (and then we thought maybe this was feasible, then it opens the door to other players re-entering the โbidding frayโ as the opposition argument to thinking this sounds unfair) by clicking a higher ranked bidding submit button
โฆ and this was our main design issue for the day, leaving non-remote scenarios for tomorrow.
And so, if you join us on our โ500 card gameโ (getting towards) non-hybrid journey with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows), just be aware that a kitty for a non-remote player you swap cards via will not be enacted for a day or so. Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Kitty Setup Tutorial is shown below.
Operation โKitty Hawkโ proceeds today on top of the bidding work of yesterdayโs Just Javascript Five Hundred Card Game Bidding Tutorial. Itโs just that โฆ well โฆ itโs a bit more involved and we only got to the Kitty bit, not the Hawk bit, today.
Tomorrow we should be โtaking offโ regarding having a kitty (of 3 cards, optionally swappable for others in the winning bidders hand, in a game of 500 played by 4 players).
Weโve plumped for an extra โKittyโ table row be added to a remote email playerโs first โplaying of cardsโ email whereby they both โฆ
- make their optional kitty swapping moves via new dropdowns โฆ
for (ixc=0; ixc<hands.length; ixc++) {
bdl=hands[ixc].split(' '); // used in "Other code goes here"
if (eval('' + ixc) >= 40) {
eis=0;
//alert('0:' + hands[ixc] + '!');
threeis=hands[ixc].slice(-3);
//alert('threeis=' + threeis + ' ... ' + hands[ixc] + '!');
for (ihjk=0; ihjk<spcps.length; ihjk++) {
if (spcps[ihjk].indexOf(threeis + '.') != -1) {
eis=eval('' + spcps[ihjk].split('/')[0]);
}
}
//alert(String.fromCodePoint(eis) + ' threeis=' + threeis + 'zsuffs[]=' + zsuffs[eval(-1 + curplayer)]);
if (tds_kitty == '') {
tds_kitty='<tr><td>Kitty</td><td><select name=swap1><option value="">Kitty Card 1 ' + String.fromCodePoint(eis) + ' ... in for ...</option></SELECT></td></TR>';
thirty--;
thirty--;
for (ihjk=0; ihjk<10; ihjk++) {
tds_kitty=tds_kitty.replace('</SELECT>','<option value="+' + curplayer + '.11,-' + curplayer + '.' + eval(1 + eval('' + ihjk)) + '">' + zsuffs[eval(-1 + curplayer)].trim().split(' ')[eval('' + ihjk)] + '</option></SELECT>');
}
tds_kitty=tds_kitty.replace('</SELECT>','</select>');
} else {
tlen=eval(-1 + eval('' + tds_kitty.split('</td>').length));
//alert('tlen=' + tlen + ' ' + tds_kitty + ' ' + zsuffs[eval(-1 + curplayer)].trim().split(' ').length);
tds_kitty=tds_kitty.replace('</td></TR>','</td><td><select name=swap' + tlen + '><option value="">Kitty Card ' + tlen + ' ' + String.fromCodePoint(eis) + ' ... in for ...</option></SELECT></td></TR>');
thirty--;
for (ihjk=0; ihjk<10; ihjk++) {
tds_kitty=tds_kitty.replace('</SELECT>','<option value="+' + curplayer + '.1' + tlen + ',-' + curplayer + '.' + eval(1 + eval('' + ihjk)) + '">' + zsuffs[eval(-1 + curplayer)].trim().split(' ')[eval('' + ihjk)] + '</option></SELECT>');
}
tds_kitty=tds_kitty.replace('</SELECT>','</select>');
}
}
// Other code goes here
}
tds_kitty=tds_kitty.replace('</td></TR>','</td><td colspan=' + thirty + '></td></tr>');
โฆ (whose data navigates with the form (via defined โnameโ properties), and tomorrow, too, weโll turn off the card โaโ links on kitty scenarios, because we want you to navigate via the email inline HTML form rather than โaโ href navigation) โฆ as well as, the usual โฆ - click for (the first) card to be played (in this first trick)
And so today the navigation out from this is achieved and tomorrow we have to cater for โKitty Hawkโ getting down again โฆ
Hawk โฆ let Kitty down now, thatโs a good bird of prey!
If you join us on our โ500 card gameโ (getting towards) non-hybrid journey with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows), just be aware that a kitty you swap cards via will not be enacted for a day or so. Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Bidding Tutorial is shown below.
Moving on from yesterdayโs Just Javascript Five Hundred Card Game Order Tutorial we start out on our โ500 card gameโ bidding phase made up of โฆ
- pitting the four players against each other for the highest bid in amongst โฆ
var bids=["6s","6c","6d","6h","6n","7s","7c","7d","7h","7n","8s","misรจre","8c","8d","8h","8n","9s","9c","9d","9h","9n","10s","10c","10d","10h","open_misรจre","10n"];
โฆ the โopen_misรจreโ a job for another day - winner of bidding swaps three cards, out, for the three cards of the kitty, in
โฆ and we are concentrating on the first part today. This bidding for the โ04.0โ scenario still needs to hide cards from other players โฆ doh! As such, it is a whole layer of code (while variable in_bidding is true) on top of a hybrid 500 card game modus operandi. Funnily enough, even for non-email participants we converge on the email button press code in function sentclick (to arrive at, within that function) where you may discern that the trigger to move on is 4 โpassโ bids in a row โฆ
if (in_bidding) {
ma=sentanswer;
//alert('sent ma=' + ma);
if (ma.toLowerCase().indexOf('pass') == 0) {
passcnt++;
if (passcnt == 4) {
in_bidding=false;
curplayer=eval('' + cbidby);
lastwinner=eval('' + cbidby);
donelistis=',1,2,3,4,';
if (cbid.trim().slice(-1).toLowerCase() == 'n' || cbid.toLowerCase().indexOf('mis') != -1) {
trumpsare='0';
} else {
trumpsare=cbid.trim().slice(-1).toLowerCase();
}
for (ixc=0; ixc<hands.length; ixc++) {
bdl=hands[ixc].split(' ');
if (bdl[eval(-1 + eval('' + bdl.length))].indexOf('000') == 0) {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'') + blanks.substring(0,17);
//alert(hands[ixc].replace(' ',blanks.substring(0,20)).replace(/\ /g,'x'));
hands[ixc]=hands[ixc].replace(' ',blanks.substring(0,33));
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 33'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
} else if (bdl[eval(-1 + eval('' + bdl.length))].indexOf('11' + trumpsare) == 0) {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'') + blanks.substring(0,17);
hands[ixc]=hands[ixc].replace(' ',blanks.substring(0,31));
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 31'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
} else if (bdl[eval(-1 + eval('' + bdl.length))].indexOf('11' + trumpsare.replace('c','S').replace('s','C').replace('d','H').replace('h','D').toLowerCase()) == 0) {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'') + blanks.substring(0,16);
hands[ixc]=hands[ixc].replace(' ',blanks.substring(0,30));
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 30'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
} else if (bdl[eval(-1 + eval('' + bdl.length))].slice(-1) == trumpsare) {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'') + blanks.substring(0,13);
hands[ixc]=hands[ixc].replace(' ',blanks.substring(0,27));
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 27'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
} else {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'');
hands[ixc]=hands[ixc];
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 0'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
}
}
if (eval('' + emailsms.length) >= eval('' + curplayer)) {
//alert('7');
if (('' + emailsms[eval('' + curplayer)]).trim() != '') {
//alert('8');
remote=true;
retcom(msuffs[eval(-1 + bidplayer)], rsuffs[eval(-1 + bidplayer)]);
}
}
//alert('9');
if (1 == 1) {
if (!remote) { myalertmc('Player ' + curplayer + ' cards are ... ' + zsuffs[eval(-1 + curplayer)]); }
}
} else {
bidplayer++;
if (eval('' + bidplayer) > eval('' + nominal_numplayer)) { bidplayer=1; }
curplayer=eval('' + bidplayer);
if (eval('' + emailsms.length) >= eval('' + curplayer)) {
//alert('7');
if (('' + emailsms[eval('' + curplayer)]).trim() != '') {
//alert('8');
remote=true;
retcom(msuffs[eval(-1 + bidplayer)], rsuffs[eval(-1 + bidplayer)]);
}
}
//alert('9');
if (1 == 1) {
if (!remote) { myalertmc('Player ' + curplayer + ' cards are ... ' + zsuffs[eval(-1 + curplayer)]); }
}
}
} else {
passcnt=0;
var thisbidrank=-1;
for (var ibidis=0; ibidis<bids.length; ibidis++) {
if (ma.substring(0,3).toLowerCase() == (bids[ibidis] + ' ').substring(0,3).toLowerCase()) {
//alert('found bid ' + bids[ibidis]);
thisbidrank=ibidis;
if (eval('' + thisbidrank) > eval('' + cbidrank)) {
//alert('found relevant bid ' + bids[ibidis]);
cbid=bids[ibidis];
//alert('1');
cbidby=eval('' + bidplayer);
//alert('2');
cbidrank=ibidis;
//alert('3');
bidplayer++;
//alert('4');
nominal_numplayer=4;
if (eval('' + bidplayer) > eval('' + nominal_numplayer)) { bidplayer=1; }
//alert('5');
curplayer=eval('' + bidplayer);
//alert('sent bid=' + cbid + ' and onto bidplayer=' + curplayer);
}
// send next
//alert('6');
if (eval('' + emailsms.length) >= eval('' + curplayer)) {
//alert('7');
if (('' + emailsms[eval('' + curplayer)]).trim() != '') {
//alert('8');
remote=true;
retcom(msuffs[eval(-1 + bidplayer)], rsuffs[eval(-1 + bidplayer)]);
}
}
//alert('9');
if (1 == 1) {
if (!remote) { myalertmc('Player ' + curplayer + ' cards are ... ' + zsuffs[eval(-1 + curplayer)]); }
}
}
}
}
}
}
And so, again, join us on our โ500 card gameโ (getting towards) non-hybrid journey with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Order Tutorial is shown below.
Many humans get comfort from โorderโ. โOrderโ means many things to many people. Our recent โcolour codingโ forays developing our current โ500 card gameโ are our expressions of โorderโ.
If you actually play 500 with cards dealt to four players (one of them you) in two teams of two it will be interesting to see how each player re-organizes, or not, the ten cards they are dealt. Personally, I break into suit groups and even within those groups I sort (curiously for bridge card game rules, quite often), and later I might try to put right bowers into appropriate rearranged suits depending on what trumps ends up being after the bidding finishes.
We want to do something similar (but no โwithin suit sortingโ), hoping that expression of โorderโ is a better presentation for our online players too?! The fact that the [playerNumer].[cardNumber]โs become disordered is the price (we have decided) to pay, but we think the users will see how these just represent an expression of a tailored โback of the cardโ look, and get used to this, but relax a bit with the game as โorderโ increases.
And so onto yesterdayโs Just Javascript Five Hundred Card Game Smaller Deck Tutorial we add to a remote email users presentation the redisplay of data into an HTML table with four rows corresponding to the card suits the players cards fall into.
function tabord(indivhtml) {
var ilook=0, jlook=1;
var slookfor=[' data-suit=c', ' data-suit=d', ' data-suit=h', ' data-suit=s'];
var slooks=[];
var outdivhtml='<br><table border=2><thead></thead><tbody></tbody></table>'
for (ilook=0; ilook<slookfor.length; ilook++) {
slooks=(indivhtml + ' <input ').split(slookfor[ilook]);
twentythree=24;
outdivhtml=outdivhtml.replace('</tbody>', '<tr><td>' + slookfor[ilook].replace(' data-suit=','').replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's' + '</td></TR></tbody>');
twentythree--;
for (jlook=1; jlook<slooks.length; jlook++) {
outdivhtml=outdivhtml.replace('</TR>', '<td> <input' + slooks[jlook].split(' <input ')[0].replace('>:','><br>') + '</td></TR>');
twentythree--;
}
outdivhtml=outdivhtml.replace('</TR>', '<td colspan=' + twentythree + '></tr>');
}
//alert(outdivhtml);
return outdivhtml;
}
Again, join us on our โ500 card gameโ (getting towards) non-hybrid journey with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Smaller Deck Tutorial is shown below.
โIn betweenโ, as a phrase, resonates with me regarding computer programming. To me, programming sits between โฆ
- the complexity of human communication and reaction (at the impossible side of the ledger) โฆ and โฆ
- static model (at the โnot enough ambitionโ side of the ledger) of a human scenario you are writing a program (or tool) for
To do better than that โstatic modelโ above might rely on user acceptance testing by groups of real humans, hopefully with as much diversity as possible. Perhaps, open feedback, is an alternative way there.
Our โhybridโ โ500 card gameโ functionality has been gradually climbing up the scale above, but to jump to a non-hybrid โ500 card gameโ involving โฆ
- not all cards of deck used
- bidding (but further up the scale would add โbettingโ (which we will not do, though who knows what is possible with the email and SMS functionalities))
- kitty
- bidding winner leading, rather than Player 1 (nesessarily)
- two opposite hands Vs other two opposite hands
- more nuanced scoring
- misรจre scenarios (where non-participating player cards might be shown to the rest)
- finesse (during play)
โฆ is quite a big job, and today (after yesterdayโs Just Javascript Five Hundred Card Game Follow Suit Colour Coding Tutorial) we creep onto the big job from that โdisplay affectingโ โnot all cards of deck usedโ small job. How first to allow the host specify thet the โ500 card gameโ is non-hybrid โฆ
var nominal_numplayers = (document.URL.replace('?','&').indexOf('&card') != -1) ? prompt('How many players are playing your ' + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(0,1).toUpperCase() + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(1).toLowerCase() + ' card game (if Zebra (ie. Memories with cross colour match limitation) prefix answer by + and if Any Colour (ie. Memories with a same colour lack of limitation) prefix answer by -) and suffix by .0 for hybrid 500 card game (or use 04.0 to play 4 players in two teams with bidding version and optionally comma delimit by a list of email/SMS addresses/numbers, else we can show you cards via "turn away" popup windows, and if you want players not to have to follow suit involve a space character somewhere)?', '2') : null;
The smaller deck coding biggest step? Redefining the โspcpsโ and โcardsโ arrays, when we detect a โ04.0โ scenario above, cutting out 2โs and 3โs and red 4โs, is the start you then code around with a โsuck it and seeโ (approach) aided by a web browser web inspector, is how we approached the start of our long journey.
Please join us on our โ500 card gameโ non-hybrid journey with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Follow Suit Colour Coding Tutorial is shown below.
Onto yesterdayโs Just Javascript Five Hundred Card Game Follow Suit Tutorial as far as remote email players of the hybrid โ500 card gameโ go we come at improving the user experience, today, from two different colour coding ideas โฆ
- within the inline HTML email sent to remote โ500 card gameโ players start colouring heart and diamond card emojis red via โฆ
<font color=red>&#[heartOrDiamondEmojiCodePoint];</font> - within the inline HTML email sent to remote โ500 card gameโ players start colour coding the buttons preceding the card emojis into five categories as per โฆ
- lightgreen background if the same suit as the current trickโs lead card
- lightgreen background with yellow border if the same suit as the trick lead card, and is trumps
- yellow background if card suit is trumps
- normal background for otherwise clickable cards dealt out to current user
- missing card emoji if that card already played in this โ500 card gameโ incarnation
โฆ encouraging the following of suit for such remote users, and adding that clarity to help avoid some confusion playing the game (as a remote user sees none of the context the host or dealer of the โ500 card gameโ sees), and keeping it flowing without the host and dealer doling out any โdid not follow suitโ return email warnings that hold up the game.
All this colour coding is appearing within the (inline HTML) body section of the email. The subject section relies on the inherent colour of the emoji card, and that, up to this point of time, even for hearts and diamonds, is black.
So, yet again, to see these nuances in action try hosting a (hybrid) โ500 card gameโ of your own with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Follow Suit Tutorial is shown below.
For todayโs work progressing yesterdayโs Just Javascript Five Hundred Card Game Host Aesthetics Tutorial we had as an email to oneself โฆ
Fwd: Click away wider, documenttitle global variable, Know when 500 game ends, and add hybrid 500 card game in document.title
โฆ the incidentals for today on top of the planned โenforcing follow suitโ work from a few days ago.
Writing โchoresโ down ahead of a day is, of course, highly recommended, as the brain can mull over it with sleep. Not always possible, of course, but good.
The โdocumenttitle global variableโ may amuse or look kludgy to you, but we like the idea of fundamental DOM members such as โฆ
- document.URL
- document.title
- location.href
โฆ that deserve coding for more than one incarnation โmeaningโ (perhaps only discovered as a project matures) can be accommodated well (via โfunction documenttitleeqโ below) working the logic using Javascript global variables as per โฆ
- we went around globally substituting any โdocument.title=[blah];โ code with โdocumenttitleeq([blah];โ code then globally substituted any remaining โdocument.titleโ with โdocumenttitleโ then fixed up any โdocumenttitleeq([blah];โ code with โdocumenttitleeq([blah]);โ code โฆ then โฆ
-
var documenttitle=document.title; // up the top as the global variable initialization
function documenttitleeq(indt) {
documenttitle=indt;
if (card_game == '500ish') {
document.title='500 (hybrid) card game ... ' + scoresuffix;
if (eval('' + nominal_numplayers + ' * (' + scoresuffix.replace(/\,/g, ' + ') + ')') >= Math.abs(eval('' + totcpp))) {
if (eval('' + totcpp) > 0) {
totcpp=-totcpp;
if (confirm('Thanks for playing the 500 (hybrid) card game ... ' + scoresuffix + ' ... OK to play again?')) {
location.href=document.URL;
}
}
}
} else {
document.title=documenttitle;
}
}
As you see, this helps us with this (hybrid) โ500 card gameโ that somebody not in the game going to look at the host or dealer Player 1โs webpage now has a mechanism to discover what they are playing without having to interfere with that game (designed as a โJust Javascriptโ (ie. โNo Body Definitionโ) project).
Regarding the enforcement of โfollowing of suitโ, sure, itโs an important part of a real game of 500 where four players play and they are in teams of two, but weโre not doing that, yet, with our hybrid 500 card game, and so allow this โhybridโ at least have some variety on this front, as per โฆ
var nominal_numplayers = (document.URL.replace('?','&').indexOf('&card') != -1) ? prompt('How many players are playing your ' + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(0,1).toUpperCase() + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(1).toLowerCase() + ' card game (if Zebra (ie. Memories with cross colour match limitation) prefix answer by + and if Any Colour (ie. Memories with a same colour lack of limitation) prefix answer by -) and suffix by .0 for hybrid 500 card game (optionally comma delimited by a list of email/SMS addresses/numbers, else we can show you cards via "turn away" popup windows, and if you want players not to have to follow suit involve a space character somewhere)?', '2') : null;
Again, to see these nuances in action try hosting a (hybrid) โ500 card gameโ of your own with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Host Aesthetics Tutorial is shown below.
On top of the progress of yesterdayโs Just Javascript Five Hundred Card Game Email Buttons Tutorial, today, weโve been trying to improve โฆ
- aesthetics of the host (hybrid) โ500 card gameโ โฆ and in so doing โฆ
- improve the โuser experienceโ playing that โ500 card gameโ
We worked on the SVG content to the background images so as to make the cards be โฆ
- more legible (via increased size and appropriate repositioning and change to Verdana font family)
- colour coded โฆ hearts and diamonds red (via โstroke:red;โ) and clubs and spades black (via โfill:black;โ)
To see this in action try hosting a (hybrid) โ500 card gameโ of your own with ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game Email Buttons Tutorial is shown below.
Yesterdayโs Just Javascript Five Hundred Card Game By Correspondence Tutorial โ500 card gameโ communication options felt โฆ
- more like โsharingโ โฆ and only mildly โฆ
- anything like โcollaborationโ
โฆ and we think that by allowing (submit) button presses with the โemail via PHP mailโ conduit to affect the โ500 card gameโ display seen by the dealer and hoster (ie. Player 1) is more your โcollaborationโ integration, wouldnโt you say?
Well, itโs possible in two senses โฆ
- inline HTML email allows forms with multiple โsubmitโ buttons allowed โฆ as well as โฆ
- PHP helper integration to control the existence or not of some web server file(s) โฆ as our research into postMessage ideas got us to realize its brilliance is not enough for what we are after
Still โJust Javascriptโ (ie. โNo Body Definedโ) back at the parent (here with all this), though it constructs emails that can contain a body element in order to navigate via an inline HTML form to โbe a playerโ remotely.
Behind the scenes our new PHP cards_usefocusphp helps out ourchanged cards_usefocus
html code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players (who can affect the game remotely via email)!
Previous relevant Just Javascript Five Hundred Card Game By Correspondence Tutorial is shown below.
Yesterdayโs Just Javascript Five Hundred Card Game Joker Tutorial left us with the โto-do listโ โฆ
- enforce the following of suits
- aesthetics
- โuser experienceโ
- sharing
โฆ and today, weโve jumped straight to โsharingโ for a few reasons โฆ
- collaboration and sharing โฆ yes โฆ but also โฆ
- allow โ500 card gameโ players to not be huddled around the one computer โฆ and โฆ
- on that one computer used, (now) have a (better) mechanism for player cards be hidden (easier) from the other players in the game, our hybrid being โevery player for their ownโ
โฆ allowing for three modes of communication โฆ
- email via PHP mail โฆ our preferred method, because we can do this in the background via our favourite โmidairโ email communication conduit, Ajax/FormData โฆ
var xhr=null;
var form=null;
function inhouse(inhref) {
var ine=inhref.split('mailto:')[1].split('?')[0];
if (ine.toLowerCase() == ine) {
form = new FormData();
xhr = new XMLHttpRequest();
form.append('to', ine);
form.append('inline', 'y');
form.append('subject', decodeURIComponent(inhref.split('subject=')[1].split('&')[0].split('#')[0]));
form.append('body', '<html><body><p style=font-size:36px;>' + decodeURIComponent(inhref.split('body=')[1].split('&')[0].split('#')[0]) + '</p></body></html>');
//alert(decodeURIComponent(inhref.split('body=')[1].split('&')[0].split('#')[0]));
xhr.open('post', '//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php', true);
xhr.send(form);
return '';
}
return inhref;
} - email via โmailto:โ โaโ link (we do not advertise, but a mixed case email address will use this technique)
- SMS via โsms:โ โaโ link
โฆ still all โJust Javascriptโ (ie. โNo Body Definitionโ) in ourchanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your โ500 card gameโ players!
Previous relevant Just Javascript Five Hundred Card Game Joker Tutorial is shown below.
Yesterdayโs lack of a Joker in the โ500โ card game established yesterday with Just Javascript Five Hundred Card Game Tutorial has been remedied.
And we forgot the logic that allows a lead up player to still win (that trick) with a paltry non-trump card if the other users also play cards that are not trumps nor a larger card of that same leading suit, nor the Joker.
Thereโs still a bit more logic to go about the play (ie. enforce the following of suits), then aesthetics and then โuser experienceโ and finally sharing, perhaps.
But see how you go with thechanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). Try adding โ.0โ to number of card players to play (our hybrid) โ500โ card game!
Previous relevant Just Javascript Five Hundred Card Game Tutorial is shown below.
Onto yesterdayโs Just Javascript Memories SVG Emoji CSS Animation Tutorial, today, we add on โฆ
- a pared down version of the card game โ500โ โฆ featuring โฆ
- no bidding โฆ
- no Jokers (yet) โฆ
- left and right bowers (Jack trumps, Jack other same colour) as the top two cards โฆ
- for 2 to 25 players โฆ
- Player 1 leads off first
โฆ the cards dealt out in turn to users and the next card turned over to determine trumps.
Itโs early days for thechanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows). As such, we anticipate improvements to this first venture into card games that โturn on the winning of tricksโ.
Previous relevant Just Javascript Memories SVG Emoji CSS Animation Tutorial is shown below.
There are lots of styles of animation that do not suit a โJust Javascriptโ (ie. โNo Body Definitionโ) style of web application as for Just Javascript Memories SVG Emoji Background Tutorialโs work, but there is one left that can really help add some excitement and colour to the whole project, that being the use of CSS @keyframes Animation techniques.
Youโd be amazed how widespread it is regarding the CSS property animation availability we found at Animatable CSS properties, thanks, from colour through aesthetics to positioning and sizing of webpage content.
We decided the way weโd apply some animation was to, between the first and second selection of cards in the Memories game, for any user, weโd add a bit of tension by some mild animated movement applied to the multiple background images. Yes, animations can happen for multiple background images, even variable amounts of change for each single background image part, if you like, but we applied the same movement to every part of the background image components.
We also animated some aesthetics via some CSS filter application, as per โฆ
if (nominal_numplayers) {
defstyle=defstyle.replace('} </style>', ' animation: animatedBackground 10s linear infinite; } @keyframes animatedBackground { from { filter: contrast(175%) brightness(120%) saturate(70%); } to { filter: contrast(95%) brightness(90%) saturate(150%); } } </style>');
}
โฆ that can be built upon by a possible second layer of animation (and plain straight background colour randomness) via the document.head.innerHTML+=bpmore(defstyle); use of โฆ
function bpmore(incss) {
var cgcols=['lime','maroon','lightblue','purple','navy','teal','fuchsia','olive','red','lightgreen','darkorange','pink','orange','yellow'];
var icg=eval(0 + Math.floor(Math.random() * cgcols.length));
var mvt=eval(10 + Math.floor(Math.random() * 40));
var kf=" @keyframes animatedBpos { from { background-position: bp1; } to { background-position: bp2; } } ";
var inkf="", jnkf="", jnkfd="", nn=0;
var inks=[];
if (incss.indexOf('} </style>') != -1) {
if (incss.indexOf('background-position:') != -1) {
inkf=incss.split('background-position:')[1].split(';')[0].trim();
inks=inkf.split(',');
for (nn=0; nn<inks.length; nn++) {
if (('' + inks[nn]).indexOf(' ') != -1) {
if (('' + inks[nn]).indexOf('px') != -1) {
jnkf+=jnkfd + eval(mvt + eval('' + inks[nn].replace(/px/g,'').replace(/\%/g,'').split(' ')[0])) + 'px ' + eval(30 + eval('' + inks[nn].replace(/px/g,'').replace(/\%/g,'').split(' ')[1])) + 'px';
} else {
jnkf+=jnkfd + eval(mvt + eval('' + inks[nn].replace(/px/g,'').replace(/\%/g,'').split(' ')[0])) + '% ' + eval(30 + eval('' + inks[nn].replace(/px/g,'').replace(/\%/g,'').split(' ')[1])) + '%';
}
} else {
jnkf+=jnkfd + inks[nn];
}
jnkfd=',';
}
if (incss.indexOf('} @keyframes ') != -1) {
return incss.replace('yellow',cgcols[icg]).replace('} @keyframes ', ' animation: animatedBpos 10s linear infinite; }' + kf.replace('bp1', inkf).replace('bp2', jnkf) + ' @keyframes ');
} else {
return incss.replace('yellow',cgcols[icg]).replace('} </style>', ' animation: animatedBpos 10s linear infinite; }' + kf.replace('bp1', inkf).replace('bp2', jnkf) + ' } </style>');
}
}
}
return incss;
}
For more colour and pizazz try this in thechanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows).
Previous relevant Just Javascript Memories SVG Emoji Background Tutorial is shown below.
Yesterdayโs Just Javascript Memories SVG Emoji Cursor Tutorial had good and bad news related to SVG Emoji Cursors?
- the bad news is that this CSS cursor concept does not work on mobile platforms for similar reasons to why onmouseover does not work โฆ to hover over the mobile device screen means nothing to event logic โฆ while โฆ
- the good news is that the same type of data-uri of SVG content can work for a (mobile CSS) background image as it can work for (non-mobile CSS) cursor
โฆ and so we can show, ahead of time, via a background image, news about the Memories game on mobile platforms (that are missing that CSS cursor methodology of showing similar information) โฆ as per โฆ
var dhi='';
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
covercover=',80px 60px,80px 60px';
prevsb=String.fromCodePoint(10067,10068) + csuff;
dhi='<style> html { cursor: url("data:image/svg+xml;utf8,<svg xmlns=' + "'" + '//www.w3.org/2000/svg' + "'" + ' width=' + "'" + '96' + "'" + ' height=' + "'" + '48' + "'" + ' viewport=' + "'" + '0 0 100 100' + "'" + ' style=' + "'" + 'border-radius:60px;background-color:rgba(255,0,0,0.1);fill:black;font-size:24px;' + "'" + '><text y=' + "'" + '50%' + "'" + '>' + String.fromCodePoint(10067,10068) + csuff + '</text></svg>") 16 0, pointer; } </style>';
document.head.innerHTML+=dhi;
} else {
document.head.innerHTML+='<style> html { cursor: url("data:image/svg+xml;utf8,<svg xmlns=' + "'" + '//www.w3.org/2000/svg' + "'" + ' width=' + "'" + '96' + "'" + ' height=' + "'" + '48' + "'" + ' viewport=' + "'" + '0 0 100 100' + "'" + ' style=' + "'" + 'border-radius:60px;background-color:rgba(255,0,0,0.1);fill:black;font-size:24px;' + "'" + '><text y=' + "'" + '50%' + "'" + '>' + String.fromCodePoint(10067,10068) + csuff + '</text></svg>") 16 0, pointer; } </style>';
}
โฆ used as per code exemplified by โฆ
if ((nominal_numplayers && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && ocp) {
defstyle=defstyle.replace(';background-size:', ',repeat,repeat' + ';background-size:');
} else if ((nominal_numplayers && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && dhi != '') {
defstyle=defstyle.replace(';background-size:', ',repeat,repeat' + ';background-size:');
} else {
defstyle=defstyle.replace(';background-size:', ',no-repeat,no-repeat' + ';background-size:');
}
if ((nominal_numplayers && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && ocp) {
defstyle=defstyle.replace('; } </style>', ',linear-gradient(rgba(255,255,255,0.4),rgba(255,255,255,0.4)),url(' + opc.style.cursor.split('url(')[1].split(') ')[0] + '); } </style>'); // + ' ' + owidth + ' ' + oheight
} else if ((nominal_numplayers && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && dhi != '') {
defstyle=defstyle.replace('; } </style>', ',linear-gradient(rgba(255,255,255,0.4),rgba(255,255,255,0.4)),url(' + dhi.split('url(')[1].split(') ')[0] + '); } </style>'); // + ' ' + owidth + ' ' + oheight
} else {
defstyle=defstyle.replace('; } </style>', ',linear-gradient(rgba(255,255,255,0.4),rgba(255,255,255,0.4)),url(//www.rjmprogramming.com.au' + backi + '); } </style>'); // + ' ' + owidth + ' ' + oheight
}
So yet again, feel free to try this in thechanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows).
Previous relevant Just Javascript Memories SVG Emoji Cursor Tutorial is shown below.
The โMemoriesโ functionality introduced in yesterdayโs Just Javascript Memories Card Game Tutorial is a game component, and it is good to remember the โgameโ side to that. If a web application is a game and the player is not being timed, they may feel that freedom to be multitasking, go and do something else, and then come back โto work the gameโ. In that scenario, it would be quite friendly to offer a mechanism by which to remind the player(s) of the status of the game as they left it.
Even though we are in โJust Javascriptโ (ie. โNo Body Definitionโ) mode of use here, we still have CSS to offer a solution here, and weโve chosen in the CSS woooooorrrrrllllllddd to research a curiosity weโve had โfor just about everโ. Can we tailor the webpage โcursorโ to be โemoji text contentโ. Weโve looked this up in the past, and did not succeed on that occasion with the โurl([SVGcontent])โ we thought might be the go. It was tweaking onto this great link that gave examples for us to succeed this time, thanks, using code such as โฆ
csuff='';
var hjg='' + curplayer;
for (var ipl=0; ipl<hjg.length; ipl++) {
csuff+=String.fromCodePoint(eval(8320 + eval(eval('' + hjg.substring(ipl,eval(1 + eval('' + ipl))).charCodeAt(0)) - 48)));
}
if (ocp) { ocp.style.cursor='url("data:image/svg+xml;utf8,<svg xmlns=' + "'" + 'HTTP://www.w3.org/2000/svg' + "'" + ' width=' + "'" + '96' + "'" + ' height=' + "'" + '48' + "'" + ' viewport=' + "'" + '0 0 100 100' + "'" + ' style=' + "'" + 'border-radius:60px;background-color:rgba(255,0,0,0.1);fill:black;font-size:24px;' + "'" + '><text y=' + "'" + '50%' + "'" + '>' + String.fromCodePoint(10067,10068) + csuff + '</text></svg>") 16 0, pointer'; }
โฆ that โocpโ being the โevt.targetโ of the โonlickโ event logics previously talked about. Notice the fallback to those set cursors of โthe cursor wooooorrrrrlllllldddโ.
Along the way we offer variations to the playing rules of Memories, too, to add some variety for the user(s).
Yet again, feel free to try this in thechanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows).
Previous relevant Just Javascript Memories Card Game Tutorial is shown below.
Up until yesterdayโs Just Javascript Card Order Game One Window Tutorial every mode of execution of our web application involved the Javascript prompt (popup) window method of getting information off the user.
Today, though, adding a Memories Card Game new functionality part uses a hybrid Javascript prompt window arrangement โฆ
- a first usage is to use the default Javascript prompt window arrangement you glean from the user the number of players in the Memories Card Game to follow โฆ
- and then from then on โฆ
var lasttogglenumber='';
var lastec='', notyet=false;
var backi="/rjmquiz_plus.jpg";
var fiftytwo=52;
var message='';
var lastcard='';
var lasttto='';
var gamescoreprefix='';
var gamescores=[0];
var lasttmid='';
var lasttfrom='';
var lasttoggleto='';
var lasttogglefrom='';
var curplayer=1, card_of_play=0;
var card_game='memories';
var nominal_implication='';
var nominal_numplayers = (document.URL.replace('?','&').indexOf('&card') != -1) ? prompt('How many players are playing your ' + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(0,1).toUpperCase() + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(1).toLowerCase() + ' card game?', '2') : null;
if (nominal_numplayers) {
if (('' + nominal_numplayers).replace('0','').trim() != '' && ('' + nominal_numplayers).replace('0','').trim().indexOf('-') == -1) {
var prompt = function(zwords, defwords){ return null; };
nominal_implication=" var prompt = function(zwords, defwords){ return null; }; ";
fiftytwo=-1;
backi="/Games/Memories/Memories.jpg";
} else {
nominal_numplayers=null;
}
}
โฆ โpromptโ is overridden as above. That, and overriding the scoring mechanisms, and this same codeset is nearly there towards accommodating our new quite different requirement.
But with โNo Body Definitionโ/โJust Javascriptโ how can we show and implement this new Memories Card Game usage? Itโs a two way integration, the easier one being โฆ
- offer a place for click/touch on the default background imagery โฆ and with that webpage reminder โฆ
- what is an independent โadd onโ event methodology available to us, so as not to interfere with event logic that has preceded? โฆ spoiler alert โฆ double click โฆ
ele.addEventListener('dblclick', function(evt) {
location.href=document.URL.split('?')[0].split('#')[0] + '?card_memories=y';
});
โฆ (or two clicks quickly in a row) โฆ as per โฆ
var lastec='', notyet=false;
function antilastec() {
lastec='';
}
function antinotyet() {
notyet=true;
}
ele.addEventListener('click', function(evt) {
if (evt.touches) {
if (evt.touches[0].pageX) {
iourx = evt.touches[0].pageX;
ioury = evt.touches[0].pageY;
} else {
iourx = evt.touches[0].clientX;
ioury = evt.touches[0].clientY;
}
//alert('' + iourx);
} else if (evt.clientX) {
iourx = evt.clientX; // - elemLeft;
ioury = evt.clientY; // - elemLeft;
} else if (!evt.touches) {
iourx = evt.pageX; // - elemLeft;
ioury = evt.pageX; // - elemLeft;
}
if (('' + iourx + ',' + ioury) == lastec && lastec != '' && notyet) {
location.href=document.URL.split('?')[0].split('#')[0] + '?card_memories=y';
} else if (lastec == '') {
setTimeout(antilastec, 2000);
setTimeout(antinotyet, 200);
notyet=false;
lastec='' + iourx + ',' + ioury;
} else {
setTimeout(antilastec, 2000);
setTimeout(antinotyet, 200);
notyet=false;
lastec='' + iourx + ',' + ioury;
}
clickedmaybe();
});
Again, feel free to try this in thechanged cards_usefocushtml code behind the โJust Javascriptโ Memories
Card Game or live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows).
Previous relevant Just Javascript Card Order Game One Window Tutorial is shown below.
The โone windowโ rather than (52 + 1) = 53 windows scenario set up as a possibility with yesterdayโs Just Javascript Card Order Game Mobile Tutorial had us wondering โฆ
โฆ a one window solution that saves the day for mobile and we see as a good candidate for โdefault-nessโ for non-mobile โฆ weโll let that one sink in for a day or so?!
โฆ and tomorrow is today. Weโve decided not to make the one window scenario the default for non-mobile platforms, but serve as a fallback for some of the scenarios mentioned below โฆ
- the user gets blocked from using the popup windows on their non-mobile platform web browser โฆ big possibility!
- the user clicks half way through the popup window incarnation the parent window โฆ all the child popups disappear behind โฆ annoying โฆ so โฆ
var flexible=false;
function secsu() {
var ewd;
if (secs == 0) {
if (document.URL.indexOf('onewindow=') != -1 || navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
flexible=false;
} else {
flexible=true;
console.log('Flexible=T');
}
setTimeout(blater, 2500);
}
if (eval('' + overallgoes) < 52) {
secs++;
} else if (document.title.indexOf('Congratulations') == -1) {
document.title+=' ... Congratulations! End of Game! Refresh webpage to try again.';
}
var decs=document.title.split('.');
if (eval('' + decs.length) >= 3) {
document.title=document.title.replace('.' + decs[2].split(' ')[0] + ' ', '.' + secs + ' ');
} else {
ps=document.title.split('/')[0].trim();
pg=document.title.split('/')[1].split(' ')[0];
if (ps.indexOf('.') == -1 || pg.indexOf('.') == -1) {
ps=eval('' + overallscore + '.' + psecs); //eval(document.title.split('/')[0].trim());
pg=eval('' + overallgoes + '.' + secs);
document.title=document.title.replace(document.title.split(' ')[0], '' + overallscore + '.' + psecs + '/' + '' + overallgoes + '.' + secs);
//console.log('document.title becomes ' + document.title);
} else {
ps=eval(ps);
pg=eval(pg);
}
}
if (flexible) {
if (document.hasFocus()) {
flexible=false;
console.log('Flexible=F');
lastzkq='';
lastzkl='';
owidth=oowidth;
oheight=ooheight;
for (var igh=0; igh<oplist.length; igh++) {
opltlistl[igh]=oopltlistl[igh];
opltlistt[igh]=oopltlistt[igh];
if (oplist[igh]) {
console.log('Flexible=F' + igh);
if (!oplist[igh].closed) {
try {
oplist[igh].close();
oplist[igh]=null;
} catch(ewd) {
}
} else {
oplist[igh]=null;
}
}
}
}
}
}
โฆ document.hasFocus() to the rescue again โฆ the multiple background images of yesterdayโs work being a default part of any incarnation, and whether the click event logic of yesterday becomes relevant depends on โฆ
- if user is a mobile platform user, always relevant
- user enters URL with argument like ?onewindow=y then is always relevant โฆ else โฆ
- a scenario as above means that from that point on, the multiple background image one window click on cards modus operandi becomes relevant
We improve the web browser conditions too, if a non-mobile user โclicks half way through the popup window incarnation the parent windowโ in that we programmatically close any open child popup windows! Phew!
Feel free to try this in thechanged cards_usefocushtml code behind the โJust Javascriptโ live
run with single window (good for mobile) or default
live run (for your platform, and if non-mobile it will try child popup windows).
Previous relevant Just Javascript Card Order Game Mobile Tutorial is shown below.
Yesterdayโs Just Javascript Card Order Game Tutorial mobile usage scenario was impractical, in that mobile platforms can not work popup windows in front of a parent window. Can we convert those non-mobile popup windows into โฆ well โฆ what exactly?
Well, in order to keep to our โJust Javascriptโ (ie. โNo Body Definitionโ) pledge with this project, we needed to simulate those popups as background image parts, in the sense that you can have multiple background images these days with your HTML. Even with html as your CSS styling selector โฆ it pans out โฆ we needed to prove that today.
Also, today, for the first time, we achieved via โฆ
- comma separated background-repeat: no-repeat; list
- comma separated background-size list (set popup width height list until last one bigger (based on screen.width screen.height) for the parent background image (no-repeat))
- comma separated background-position list (as per what window.open in non-mobile was using for left top until last oneโs 0px 0px)
- comma separated background-image list (as per what window.open in non-mobile was using for URL([imageURL]) until last oneโs linear-gradient(rgba(255,255,255,0.4),rgba(255,255,255,0.4)), url(//www.rjmprogramming.com.au/rjmquiz_plus.jpg))
โฆ as per (the previous โwindow.openโ becomes โwindowopenโ) โฆ
function windowopen(one, two, three) {
if (document.URL.indexOf('onewindow=') != -1 || navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
console.log('Here ' + kq);
opltlistl.push((three.split('left=')[1].split(',')[0].split(')')[0].split('.')[0] + '.' + one.split('spcp=')[1].split('&')[0]));
opltlistt.push((three.split('top=')[1].split(',')[0].split(')')[0].split('.')[0] + '.' + kq));
owidth=eval(three.split('width=')[1].split(',')[0].split(')')[0].split('.')[0]);
oheight=eval(three.split('width=')[1].split(',')[0].split(')')[0].split('.')[0]);
if (defstyle.indexOf('background: URL(') != -1) {
defstyle=defstyle.split('background: URL(')[0] + 'background-repeat:no-repeat;background-size:' + owidth + 'px ' + oheight + 'px;background-position:' + ('' + opltlistl[eval(-1 + opltlistl.length)]).split('.')[0] + 'px ' + ('' + opltlistt[eval(-1 + opltlistt.length)]).split('.')[0] + '' + 'px' + ';background-image: url(' + cards[eval('' + donelist[eval(-1 + donelist.length)])] + ') ' + (' ' + ('' + opltlistl[eval(-1 + opltlistl.length)]).split('.')[0] + 'px ' + ('' + opltlistt[eval(-1 + opltlistt.length)]).split('.')[0] + '' + 'px').substring(0,1) + '; } </style>'; // + ' ' + owidth + ' ' + oheight
} else {
defstyle=defstyle.replace(';background-image:', (',' + opltlistl[eval(-1 + opltlistl.length)]).split('.')[0] + 'px ' + ('' + opltlistt[eval(-1 + opltlistt.length)]).split('.')[0] + '' + 'px' + ';background-image:');
defstyle=defstyle.replace('no-repeat','no-repeat,no-repeat');
defstyle=defstyle.replace('background-size:' + owidth + 'px ' + oheight + 'px','background-size:' + owidth + 'px ' + oheight + 'px,' + owidth + 'px ' + oheight + 'px');
defstyle=defstyle.replace('; } </style>', ',url(' + cards[eval('' + donelist[eval(0 + ijk)])] + ') ' + (' ' + ('' + opltlistl[eval(-1 + opltlistl.length)]).split('.')[0] + 'px ' + ('' + opltlistt[eval(-1 + opltlistt.length)]).split('.')[0] + '' + 'px').substring(0,1) + '; } </style>'); // + ' ' + owidth + ' ' + oheight
}
return null;
}
return window.open(one, two, three);
}
โฆ a one window solution that saves the day for mobile and we see as a good candidate for โdefault-nessโ for non-mobile โฆ weโll let that one sink in for a day or so?!
We needed to add event logic we were not sure would work at the start of the day, and saw it working by the end, with โฆ
var iourx=-1, ioury=-1;
function blater() {
if (1 == 2 && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
window.addEventListener('touchstart', function(evt) {
evt.preventDefault();
var touches = evt.changedTouches;
//if (evt.touches) {
if (touches[0].pageX) {
iourx = touches[0].pageX;
ioury = touches[0].pageY;
} else if (touches[0].clientX) {
iourx = touches[0].clientX;
ioury = touches[0].clientY;
}
//alert('x:' + iourx);
//}
clickedmaybe();
}, false);
} else {
eles = document.querySelectorAll("*")
for (var ele of eles) {
console.log('yes well');
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
ele.addEventListener('touchstart', function(evt) {
evt.preventDefault();
var touches = evt.changedTouches;
//if (evt.touches) {
if (touches[0].pageX) {
iourx = touches[0].pageX;
ioury = touches[0].pageY;
} else if (touches[0].clientX) {
iourx = touches[0].clientX;
ioury = touches[0].clientY;
}
//alert('x:' + iourx);
//}
clickedmaybe();
}, false);
ele.addEventListener('touchmove', function(evt) {
evt.preventDefault();
var touches = evt.changedTouches;
//if (evt.touches) {
if (touches[0].pageX) {
iourx = touches[0].pageX;
ioury = touches[0].pageY;
} else if (touches[0].clientX) {
iourx = touches[0].clientX;
ioury = touches[0].clientY;
}
//alert('x:' + iourx);
//}
clickedmaybe();
}, false);
ele.addEventListener('click', function(evt) {
evt.preventDefault();
var touches = evt.changedTouches;
//if (evt.touches) {
if (touches[0].pageX) {
iourx = touches[0].pageX;
ioury = touches[0].pageY;
} else if (touches[0].clientX) {
iourx = touches[0].clientX;
ioury = touches[0].clientY;
}
//alert('x:' + iourx);
//}
clickedmaybe();
}, false);
} else {
ele.addEventListener('click', function(evt) {
if (evt.touches) {
if (evt.touches[0].pageX) {
iourx = evt.touches[0].pageX;
ioury = evt.touches[0].pageY;
} else {
iourx = evt.touches[0].clientX;
ioury = evt.touches[0].clientY;
}
//alert('' + iourx);
} else if (evt.clientX) {
iourx = evt.clientX; // - elemLeft;
ioury = evt.clientY; // - elemLeft;
} else if (!evt.touches) {
iourx = evt.pageX; // - elemLeft;
ioury = evt.pageX; // - elemLeft;
}
clickedmaybe();
//alert('here');
});
}
}
}
}
See this in thechanged cards_usefocushtml code behind the โJust Javascriptโ live
run with single window (good for mobile) or default
live run (for your platform) we, again, welcome you to try for yourself.
Previous relevant Just Javascript Card Order Game Tutorial is shown below.
Today weโve made the web application of yesterdayโs Just Javascript Quiz Drag Tutorial โdual purposeโ โฆ
- quiz โฆ as for yesterday, and before โฆ and as of today, making more use of the card organizational side to the popup windows we introduce โฆ
- card order game
This card order game asks you to force the focus of the correct popup window (to score in the Card Order Game) in the order as designated by the background image part we have added today, and supported by the following Javascript โmappingโ code โฆ
var dragorder=[], curdrag=0;
var cards=["//www.rjmprogramming.com.au/images/01s.gif?n=7",
"//www.rjmprogramming.com.au/images/02s.gif?n=16",
"//www.rjmprogramming.com.au/images/03s.gif?n=33",
"//www.rjmprogramming.com.au/images/04s.gif?n=29",
"//www.rjmprogramming.com.au/images/05s.gif?n=8",
"//www.rjmprogramming.com.au/images/06s.gif?n=35",
"//www.rjmprogramming.com.au/images/07s.gif?n=52",
"//www.rjmprogramming.com.au/images/08s.gif?n=51",
"//www.rjmprogramming.com.au/images/09s.gif?n=12",
"//www.rjmprogramming.com.au/images/10s.gif?n=30",
"//www.rjmprogramming.com.au/images/11s.gif?n=1",
"//www.rjmprogramming.com.au/images/12s.gif?n=36",
"//www.rjmprogramming.com.au/images/13s.gif?n=22",
"//www.rjmprogramming.com.au/images/01h.gif?n=32",
"//www.rjmprogramming.com.au/images/02h.gif?n=23",
"//www.rjmprogramming.com.au/images/03h.gif?n=3",
"//www.rjmprogramming.com.au/images/04h.gif?n=18",
"//www.rjmprogramming.com.au/images/05h.gif?n=28",
"//www.rjmprogramming.com.au/images/06h.gif?n=39",
"//www.rjmprogramming.com.au/images/07h.gif?n=45",
"//www.rjmprogramming.com.au/images/08h.gif?n=48",
"//www.rjmprogramming.com.au/images/09h.gif?n=50",
"//www.rjmprogramming.com.au/images/10h.gif?n=44",
"//www.rjmprogramming.com.au/images/11h.gif?n=4",
"//www.rjmprogramming.com.au/images/12h.gif?n=9",
"//www.rjmprogramming.com.au/images/13h.gif?n=5",
"//www.rjmprogramming.com.au/images/01d.gif?n=27",
"//www.rjmprogramming.com.au/images/02d.gif?n=41",
"//www.rjmprogramming.com.au/images/03d.gif?n=20",
"//www.rjmprogramming.com.au/images/04d.gif?n=11",
"//www.rjmprogramming.com.au/images/05d.gif?n=37",
"//www.rjmprogramming.com.au/images/06d.gif?n=49",
"//www.rjmprogramming.com.au/images/07d.gif?n=42",
"//www.rjmprogramming.com.au/images/08d.gif?n=6",
"//www.rjmprogramming.com.au/images/09d.gif?n=21",
"//www.rjmprogramming.com.au/images/10d.gif?n=31",
"//www.rjmprogramming.com.au/images/11d.gif?n=40",
"//www.rjmprogramming.com.au/images/12d.gif?n=43",
"//www.rjmprogramming.com.au/images/13d.gif?n=17",
"//www.rjmprogramming.com.au/images/01c.gif?n=46",
"//www.rjmprogramming.com.au/images/02c.gif?n=19",
"//www.rjmprogramming.com.au/images/03c.gif?n=47",
"//www.rjmprogramming.com.au/images/04c.gif?n=25",
"//www.rjmprogramming.com.au/images/05c.gif?n=10",
"//www.rjmprogramming.com.au/images/06c.gif?n=15",
"//www.rjmprogramming.com.au/images/07c.gif?n=13",
"//www.rjmprogramming.com.au/images/08c.gif?n=26",
"//www.rjmprogramming.com.au/images/09c.gif?n=38",
"//www.rjmprogramming.com.au/images/10c.gif?n=34",
"//www.rjmprogramming.com.au/images/11c.gif?n=2",
"//www.rjmprogramming.com.au/images/12c.gif?n=14",
"//www.rjmprogramming.com.au/images/13c.gif?n=24"];
for (var ic=1; ic<=cards.length; ic++) {
found=false;
for (var jc=1; jc<=cards.length; jc++) {
if ((cards[eval(-1 + jc)] + '~').indexOf('?n=' + ic + '~') != -1) {
dragorder.push(eval(-1 + jc));
cards[eval(-1 + jc)]=cards[eval(-1 + jc)].replace('?n=' + ic, '');
firstbit+=String.fromCodePoint(eval('' + spcps[eval(-1 + jc)].split('/')[0])) + ' ';
found=true;
}
}
}
โฆ and โmaking use ofโ this and the new codeline as popups are created โฆ oplist[eval(-1 + oplist.length)].document.name=โ + kl; we have โฆ
function ourprompt(tw, blb, bdef) {
var kijk;
if (oplist[eval('' + tw)].document.name == ('' + dragorder[eval('' + curdrag)]) && eval('' + curdrag) == eval('' + overallgoes)) {
console.log('Dragorder[' + curdrag + ']=' + dragorder[eval('' + curdrag)] + ' vs tw=' + tw + ' and overall;goes=' + overallgoes);
var decs=document.title.split('.');
curdrag++;
overallgoes++;
if (eval('' + decs.length) >= 3) {
document.title=document.title.replace('.' + decs[1] + '.', '.' + curdrag + '/' + overallgoes + '.');
}
oplist[eval('' + tw)].close();
return null;
}
// Quiz only code follows
}
โฆ code.
It must be in the correct order (and not interrupted by quiz answer completions) to score, and you are timed, so you can try improving over time, using a document.title score presentation as per โฆ
[QuizScore].[CardOrderGameScore]/[QuizAnswerAttemptCount].[SecondsElapsed] [MultiPlayerQuizScoreGoesBreakdown] is User: Score/Goes - RJM Programming - April, 2021
โฆ so that both usages for the web application can be accommodated for in thechanged cards_usefocushtml code behind the โJust Javascriptโ live
run we welcome you to try for yourself.
Previous relevant Just Javascript Quiz Drag Tutorial is shown below.
Adding to yesterdayโs Just Javascript Quiz CSS Styling Tutorial we have added some โฆ
- non-mobile platform, only โฆ
- drag and drop functionality โฆ for โฆ
- the child popup windows
โฆ achieved through the comparison of โฆ
- original [popupWindow].screenLeft and [popupWindow].screenTop โฆ initially, to โฆ
- [popupWindow].screenLeft and [popupWindow].screenTop over time
โฆ and if one popup is dragged to overlay another it is closed, or you, as the user, can just drag and drop for clarity, leaving the popup window of the next quiz question out in the open, perhaps.
In order to achieve this, and keep backward compatibility we needed to delay the quiz question prompt window via โฆ
- document.hasFocus() is true โฆ then if โฆ
- inhouse dragging checks clear it of overlaying another popup (in which case that popup is programmatically closed, allowing another popup to become the โfocus windowโ) โฆ then โฆ
- delay (by 8 seconds) the prompt window (and in that time the user can be dragging popups (but no popups were harmed in the making of this tutorial)) โฆ via โฆ
setTimeout(function() { hj=prompt(dp + window.opener.blurb(), def); if (hj == null) { hj=''; } else { hj=window.opener.assess(hj); } if (hj.replace(def,'') != '') { checka(hj); } else { setTimeout(pa,10000); } aminmiddle=false; }, 8000);
โฆ you can see in amongst thechanged cards_usefocushtml code behind the โJust Javascriptโ live
run you are welcome to try for yourself โฆ best on non-mobile.
Still โNo Body Definitionโ, โJust Javascriptโ!
Previous relevant Just Javascript Quiz CSS Styling Tutorial is shown below.
Our โJust Javascriptโ adage used throughout this blog posting thread, up until today, headed by yesterdayโs Just Javascript Quiz Content Management Tutorial needs more explanation. Really what we are trying to do might better be described as โNo Body Definitionโ (ie. no defined document.body) but have โฆ
- an HTML webpage (ie. within <html> and </html>) โฆ has โฆ
- <head> and </head> (ie. document.head) content which can be made up of (at least) title, style, script, link, meta tags
To assert โJust Javascriptโ is just to allow script content above, but what we should really say is โJust Head Contentโ but that is not nearly so marketable, is it now?!
The thing is, though, we can dynamically add title, style, link, meta tag content within the script content, and we do this more than statically define it, to feel better about our ethics saying โJust Javascriptโ.
Dynamically adding style CSS styling either โฆ
- using Javascript DOM (not available to us for document.getElementById([elementID] and nor can we use inline CSS via style=โ[CSSstyling]โ statically within HTML element code for that same reason) ideas today though โฆ remember โNo Body Definitionโ โฆ but โฆ
- we can append to <head> and </head> (for todayโs scenario) as per โฆ
document.head.innerHTML+="<style> html { background-color: yellow; font-size: 36px; background: URL('//www.rjmprogramming.com.au/rjmquiz.jpg'); background-size: cover; } </style>";
โฆ allowing (into the scope of our work CSS styling of) background (image(s)) and other background styling ideas that can get us past the anonymous feel the web application had before today. We tailored the background image above to suit our Quiz and help it be a bit more self explanatory โฆ thanks CSS styling! We add onto the child โcardโ popup windows, their own background image colour and pizazz, to cheer things up in CSSstyling enhanced cards_usefocushtml code behind the โJust Javascriptโ live
run.
You may well ask โฆ
What can we hang our hat on with CSS style selectors without a body element?
Well, we had to step out of our usual comfort zone of CSS styling thinking, and realize, even without that body element we can still use the html selector to โpoint atโ the entirety of your webpage of interest.
Previous relevant Just Javascript Quiz Content Management Tutorial is shown below.
It feels like an โonions of the 4th dimensionโ idea to allow the user to control the questions and answers behind the workings of yesterdayโs Just Javascript Quiz Multiple Users Tutorialโs web application, featuring โJust Javascriptโ.
Itโs not โJust Javascriptโ weโre keeping, itโs โJust HTMLโ client work rather than involving any serverside anything (eg.PHP) and yet this question and answer data could be quite sizeable. What can we use, given no PHP serverside, and given weโve decided not to navigate via Ajax/FormData techniques? How about โthe better than HTTP Cookiesโ twins โฆ
- sessionStorage โฆ and โฆ
- localStorage
Yep, set up a means by which these two can store and restore questions and answers entered by the user, using these storage methods above.
function reassess() {
var retv='', ewq;
var retcols=[];
var ir=0;
if (window.localStorage) {
try {
retv=('' + window.localStorage.getItem('cards_usefocus_local')).replace(/^null$/g,'');
if (retv != '') {
//alert('0:' + retv);
retcols=decodeURIComponent(retv).split('~');
sq=[];
asq=[];
for (ir=0; ir<retcols.length; ir++) {
sq.push(retcols[ir].split('?!')[0] + '?');
asq.push(retcols[ir].split('?!')[1]);
nomap=false;
given='';
}
return;
}
} catch(ewq) {
}
}
if (window.sessionStorage) {
try {
retv=('' + window.sessionStorage.getItem('cards_usefocus_session')).replace(/^null$/g,'');
if (retv != '') {
//alert('1:' + retv);
retcols=decodeURIComponent(retv).split('~');
sq=[];
asq=[];
for (ir=0; ir<retcols.length; ir++) {
sq.push(retcols[ir].split('?')[0] + '?');
asq.push(retcols[ir].split('?')[1]);
nomap=false;
given='';
}
return;
}
} catch(ewq) {
}
}
}
function assess(what) {
var ewq, retv='';
if (what.toLowerCase() == '?x') {
sslistq=[];
sslista=[];
if (window.sessionStorage) {
try {
window.sessionStorage.removeItem('cards_usefocus_session');
} catch(ewq) {
}
location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897);
return '';
}
return '';
} else if (what.toLowerCase() == '?!x') {
lslistq=[];
lslista=[];
if (window.localStorage) {
try {
window.localStorage.removeItem('cards_usefocus_local');
} catch(ewq) {
}
location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897);
return '';
}
return '';
} else if (what.toLowerCase().indexOf('?!') != -1) {
if (what.toLowerCase() == '?!') {
location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897);
return '';
}
if (window.localStorage) {
if (lslistq.length == 0) {
lslistq.push(what.split('?!')[0]);
lslista.push(what.split('?!')[1]);
window.localStorage.setItem('cards_usefocus_local', encodeURIComponent(what));
} else {
lslistq.push(what.split('?!')[0]);
lslista.push(what.split('?!')[1]);
window.localStorage.setItem('cards_usefocus_local', window.localStorage.getItem('cards_usefocus_local') + encodeURIComponent('~' + what));
}
}
return '';
} else if (what.toLowerCase().indexOf('?') != -1) {
if (what.toLowerCase() == '?') {
location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897);
return '';
}
if (window.sessionStorage) {
if (sslistq.length == 0) {
sslistq.push(what.split('?')[0]);
sslista.push(what.split('?')[1]);
window.sessionStorage.setItem('cards_usefocus_session', encodeURIComponent(what));
} else {
sslistq.push(what.split('?')[0]);
sslista.push(what.split('?')[1]);
window.sessionStorage.setItem('cards_usefocus_session', window.sessionStorage.getItem('cards_usefocus_session') + encodeURIComponent('~' + what));
}
}
return '';
} else {
firstbit='';
if (window.localStorage) {
try {
retv=('' + window.localStorage.getItem('cards_usefocus_local')).replace(/^null$/g,'');
if (retv != '' && nomap) { location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897); }
} catch(ewq) {
}
}
if (window.sessionStorage) {
try {
retv=('' + window.sessionStorage.getItem('cards_usefocus_session')).replace(/^null$/g,'');
if (retv != '' && nomap) { location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897); }
} catch(ewq) {
}
}
}
return what;
}
Thefairly significantly changed cards_usefocushtml code behind the โJust Javascriptโ live
run is worth a look, we figure, for up to 52 players who play in turn.
Previous relevant Just Javascript Quiz Multiple Users Tutorial is shown below.
Adding to yesterdayโs Just Javascript Quiz via Cards Tutorial we were surprised how difficult it was to stay with โJust Javascriptโ and allow for multiple player play.
We didnโt opt for the parent to ask about the number of players, curiously, but on the second quiz answer and on, offered any non first player the chance to identify themselves as a new player into the game by appending their answer with a space character.
The implication of that is that weโll want to run Javascript functions of the parent from the children as per โฆ
oplist[eval(-1 + oplist.length)].document.write("<link rel=icon href=" + cards[kl] + "><scr" + "ipt type='text/javascript'> var da='" + eval(0 + kq) + "'; var dp='Given answer is integer from 0 to 25 ... " + sq[kq] + "'; var def=String.fromCodePoint(" + spcps[eval('' + kl)].split('/')[0] + "); function checka(tpa) { var os=''; var ps=eval(window.opener.document.title.split('/')[0].trim()); var pg=eval(window.opener.document.title.split('/')[1].split(' ')[0]); if (tpa.trim() == da) { ps++; os=tpa.split(da)[1]; } else { pg++; os=tpa.split(tpa.trim())[1]; } window.opener.document.title=ps + os + '/' + pg + ' is User Score/Goes'; window.close(); } function pa() { if (document.hasFocus()) { var hj=prompt(dp + window.opener.blurb(), def); if (hj == null) { hj=''; } if (hj.replace(def,'') == '') { setTimeout(pa,1000); } else { checka(hj); } } else { setTimeout(pa,1000); } } pa(); </scr" + "ipt>");
โฆ accessing โฆ
function blurb() { // theblurb and wblurb are global variables changed elsewhere
if (wblurb == ' Hello Player 1' && theblurb == ' If you are player 2 rather than player 1 append space to your answer.') {
theblurb='';
wblurb='';
}
return theblurb + wblurb;
}
โฆ giving the rather curious behaviour whereby a Javascript prompt window can be dynamically different from one document.hasFocus() incarnation (ie. the user might go away and answer another โcardโ Number Quiz question) to another (even not attending to answering the Javascript prompt window) โฆ huh?!
Thesignificantly changed cards_usefocushtml code behind the โJust Javascriptโ live
run is worth a look, we figure, for up to 52 players who play in turn.
Previous relevant Just Javascript Quiz via Cards Tutorial is shown below.
Yesterdayโs Just Javascript Navigation Tutorial continues our interest in โJust Javascriptโ (or โNo Bodyโ) web applications.
We think todayโs โNumbers Quizโ via a โCard Deckโ organizational design ups the ante on all this. We realize now what we have been missing not having involved document.hasFocus() in any of our popup window scenarios. Today, at least on non-mobile, we involve 52 such popup windows each containing a โNumber Quizโ question presented as a Javascript prompt (sub-)window. This would not be feasible without document.hasFocus() as you can tell if you examine the cards_usefocushtml code behind the โJust Javascriptโ live
run best used on your non-mobile platforms where popup windows can sit in front of parent (and beside sibling) windows, whereas mobile platforms open new web browser tabs for all the 52 windows of (a card deck) design.
Look out, too, in the code above, for use of window.opener back reference from a popup window back to the parent window where the scoring data is held, and updated by each popup window because of that window.opener avaalability.
Previous relevant Just Javascript Navigation Tutorial is shown below.
The recent use we made of โฆ
document.createElement/click()
โฆ got us thinking of the โJust Javascriptโ (or No Body) blog posting thread headed by Just Javascript Webmail No Body Attachment Tutorial.
As such, today we present the very simple (but first time use of the interesting hasFocus) โproof of conceptโ โฆ
<html>
<head>
<script type='text/javascript'>
function dothis() {
var ais=null;
var urlis=' ';
while (urlis != '') {
if (document.hasFocus()) {
urlis=prompt('Enter URL that we will send you to (exit to stop)', '');
} else {
setTimeout(dothis, 2000); // urlis=' ';
return;
}
if (urlis == null) { urlis=''; }
if (urlis.toLowerCase() == 'exit') { return; }
if (urlis.trim() != '') {
if (urlis.substring(0,1) == '.') { // relative URL
urlis=document.URL.split('nobody.htm')[0] + urlis;
} else if (urlis.substring(0,1) == '/' && urlis.indexOf('//') == -1) { // relative URL
urlis=document.URL.split('//')[0] + '//' + document.URL.split('//')[1].split('/')[0] + '/' + urlis;
} else if (urlis.split('/')[0].indexOf('.') != -1) { // absolute URL
if (urlis.toLowerCase().indexOf('http') != 0) {
if (urlis.indexOf('//') == 0) {
urlis=document.URL.split('//')[0] + urlis;
} else {
urlis=document.URL.split('//')[0] + '//' + urlis;
}
}
} else { // relative URL
urlis=document.URL.split('nobody.htm')[0] + urlis;
}
ais=document.createElement('a');
ais.onclick=function() { window.open(urlis, '_blank', 'top=100,left=100,width=600,height=600'); };
if (1 == 2) { ais.href=urlis; }
ais.target='_blank';
ais.click();
}
}
setTimeout(dothis, 2000); // urlis=' ';
}
dothis();
</script>
</head>
</html>
โฆ nobodyhtmlโs live
run link for you to use a Javascript prompt popup windowโs user interaction results to navigate to a new webpage, as applicable. Bookmarklets may be scarce on the ground, but these โJust Javascriptโ ideas continue the Bookmarklet Spirit of the past!
Previous relevant Just Javascript Webmail No Body Attachment Tutorial is shown below.
A โhard linerโ for the proper use of โbusiness emailsโ could argue that an email without an attachment is not productive. Couldnโt you just have a face to face meeting instead, if there is just wording in the email (as we somewhat concur with, as an argument)? So yesterdayโs Just Javascript Webmail No Body Tutorial had that limitation of no email attachment logic, which we remedy today.
And this is where PHPโs wonderful file_get_contents (function) means by which we garner (URL) content โฆ
- definitely works with โrelative URLsโ relative to HTTP://www.rjmprogramming.com.au/HTMLCSS/ where todayโs unchanged webmail_nobody
html resides โฆ in โparsing parlanceโ โฆ
"relative (URL)" to the left of any # or ? of what lies to the left of the most right hand "/" (of what the address bar URL is of the webpage you are on)
โฆ so that โฆ- โrelative URLsโ starting with โ./โ (followed by the filename, or just the filename (as you can see us using in todayโs tutorial picture)) refer to the web server directory corresponding to โHTTP://www.rjmprogramming.com.au/HTMLCSS/โ โฆ whereas, for example โฆ
- โrelative URLsโ starting with โ../โ (followed by the filename) refer to the web server directory corresponding to โHTTP://www.rjmprogramming.com.au/โ โฆ for example
โฆ and โฆ
- might work for โabsolute URLsโ (those that start with https: or HTTP: or even // (that we beg you not to confuse with Windows UNC pathnames) that infer a transport protocol of the transport protocol (out of https: or HTTP: or even file:) that got you to the webpage you are currently on), the โmightโ being far more likely on โabsolute URLsโ pointing to the same domain as indicated on the URL of the address bar of the webpage you are currently on
Upshot is, the user in their email Body section definitions (still no HTML body though!), can throw into any word they use, an โabsolute URLโ of interest, or a โrelative URLโ of interest, of files they want to attach (as attachments, doh!) in their email.
Depending on the email rules though, there are limits as to the amount of attachment data allowed. Weโll leave that to you intrepid โexplorers of the Netโ to discover for yourselves. On this subject though, have you noticed that with the Photos (or Gallery) app Share options, the Email option drops off when you have highlighted a large number of photos or videos or audios to share? Thatโs that email limit coming into play.
So feel free to try this HTML-body-less web application liverun to see what we mean here. Though the parent HTML is unchanged today, the new (email) attachment functionality needed achanged PHP emailhtml
php to make this happen.
Did you know?
This (relative URL) โ../โ navigation backwards up the hierarchy of the web server directories will, if repeated (ie. nested to โ../../โ etcetera) too many times, get you into uncharted unnavigable (web server directory) places relative to that web server web siteโs Document Root (below which you can not access in public webpages, normally). But when you perform similar thinking with โabsolute URLsโ and go โHTTP://www.rjmprogramming.com.au/HTMLCSS/../../../blahdeblah.jpgโ (in a web browser address bar) for instance, you cannot get into trouble, as you just donโt get beyond this sending you to (attempt the reference to) โHTTP://www.rjmprogramming.com.au/blahdeblah.jpgโ because on this rjmprogramming.com.au Apache domain the correspondence of the Document Root (web server directory) is to โHTTP://www.rjmprogramming.com.au/โ as the place you are not allowed (and cannot) go below in the hierarchy tree.
Previous relevant Just Javascript Webmail No Body Tutorial is shown below.
Were you around and interested in our series of about three blog postings in the series on the theme of creating webpage functionality of some interest, involving no Javascript, when we presented Missing Javascript Audio on Unmute Tutorial? Well, today, itโs the turn of โjust Javascriptโ, which is sort of like what Bookmarklets were about.
With todayโs โjust Javascriptโ we have to qualify that a little for our webmail emailing sender application with the architecture โฆ
- parent webpage with only document.head and apart from a document.title just a script Javascript tag of content (using Javascript prompt windows to ask for user information) โฆ
- sending (POSTing) data via โฆ
- Ajax XMLHttpRequest object โฆ as the conduit for โฆ
- FormData object
โฆ to ourchanged โฆ
- PHP communication emailing tool emailhtml
php โฆ and out to โฆ
- the emailee (out there in the big wide woooorrrrrllllldddd)
Guess we find it interesting that you can do all this (sending of email to emailee recipients) with no document.body in sight.
So take a look at that parent webmail_nobodyhtmlโs live
run link to see what we mean here, and/or watch the video below โฆ
Previous relevant Missing Javascript Audio on Unmute Tutorial is shown below.
Our โthird cab off the rankโ following on from yesterdayโs Missing Javascript Stop Watch Tutorial โmissing Javascriptโ ideas is an HTML div nesting scenario using just โฆ
- HTML
- CSS
โฆ again, with some or all of the โusualsโ below โฆ
- calc method to assist with defining width and height and size dimensions along with operator โ+โ and/or โ-โ offset calculation opportunities, and which weโd have used the Javascript window.getComputedStyle and/or [element].getBoundingClientRect methods to cover this (in a much more unwieldy way, as you would probably surmise)
- CSS variables we started talking about here at CSS Variables Primer Tutorial
- CSS3 @keyframes rules we first talked about at CSS3 @keyframes Rule Primer Tutorial that assist with animations that we can make work via โฆ
- CSS3 transitions for scheduled functionality (weโd have used Javascript setTimeout (and setInterval) methods to cover the same โterritoryโ) we first talked about at CSS3 Transition Primer Tutorial โฆ specified with CSS Criteria involving โฆ
- CSS Selectors :after and :before (and often, as for todayโs work, with the content: CSS property) first talked about here with WordPress Bullet Point CSS Styling Primer Tutorial โฆ and, today โฆ
- CSS3 transform propertyโs rotate (and translate and scale) settings (for the puppy dog body movements) โฆ as well as the idea that โฆ
- On non mobile platforms you can set up the playing of โaudioโ data via the use of an HTML audio tag with the properties โฆ
- controls
- autostart
- loop
- muted
Stop Press
Above is all fine and good for non-mobile but not so good for mobile, so to keep all happy with the one click, still, is to transfer HTML coding from โฆ
<audio id='myaudio' title='Got a sock in my mouth, so you might want to unmute me!' type='audio/mp3' style="display:none;margin-left:-350px;opacity:0.1;" autostart muted loop controls src="Puppy-sounds.mp3" />โฆ to โฆ
<!--audio id='myaudio' title='Got a sock in my mouth, so you might want to unmute me!' type='audio/mp3' style="display:none;margin-left:-350px;opacity:0.1;" autostart muted loop controls src="Puppy-sounds.mp3" /-->
<audio id='myaudiotwo' title='Got a sock in my mouth, so you might want to unmute me!' type='audio/mp3' style="margin-left:-350px;opacity:0.1;" autostart="0" loop controls src="Puppy-sounds.mp3" />โฆ and a src= URL data source (as we thank this link for today), or data URI if preferred (which we do for todayโs image data from this link, thanks (when we were researching animated GIF data URIs (which we may return to at a later date))
โฆ that sets up the scenario that all the user has to do to hear the audio is to click the โmutedโ control button, without needing the usual Javascript play() methods โฆ but not on mobile!
Feel free to let the puppyplay, that uses the HTML and CSS (but no Javascript) of the_nested
html and based largely on the previous HTML Nested Centering via Multiple Select Tutorial so that thesechanges reflect how we got to the first draft of todayโs work. Maybe some of the ideas are of interest. We hope so!
Previous relevant Missing Javascript Stop Watch Tutorial is shown below.
Following on from yesterdayโs Missing Javascript Primer Tutorial our second โcab off the rankโ for โmissing Javascriptโ ideas is a stop watch featuring just โฆ
- HTML
- CSS
โฆ again, setting up document.body load instigated โฆ
- calc method to assist with defining width and height and size dimensions along with operator โ+โ and/or โ-โ offset calculation opportunities, and which weโd have used the Javascript window.getComputedStyle and/or [element].getBoundingClientRect methods to cover this (in a much more unwieldy way, as you would probably surmise)
- CSS variables we started talking about here at CSS Variables Primer Tutorial
- CSS3 @keyframes rules we first talked about at CSS3 @keyframes Rule Primer Tutorial that assist with animations that we can make work via โฆ
- CSS3 transitions for scheduled functionality (weโd have used Javascript setTimeout (and setInterval) methods to cover the same โterritoryโ) we first talked about at CSS3 Transition Primer Tutorial โฆ specified with CSS Criteria involving โฆ
- CSS Selectors :after and :before (and often, as for todayโs work, with the content: CSS property) first talked about here with WordPress Bullet Point CSS Styling Primer Tutorial โฆ and, today โฆ
- CSS3 transform propertyโs rotate setting (for the stop watch hand movements)
โฆ which we needed to do to make multiple animations happen, but we used animation-delay:5s; to delay its start. The hands (second and minute, hence the two animations) are โoverlayโ โฆ
- position:absolute property
- z-index
โฆ feeling HTML horizontal rule elements that also feature linear gradients, to emphasise (in red) the โpointy endโ of the โhand conversationโ (good on walls with shadows โฆ but we digress).
Feel free to let loose the stopwatch that uses the HTML and CSS (but no Javascript) of stop_watch
html for todayโs instructional information. Thanks to Clipart โ stop watch for the great clip art used.
Previous relevant Missing Javascript Primer Tutorial is shown below.
If you were to ask me which programming component is most vital to web application development, Iโd not be Robinson Crusoe in saying โฆ
Without a doubt, Javascript
โฆ and with that thought in mind we have a two pronged motive to see how far we go developing some web applications that โdonโt use Javascriptโ, calling into play the โฆ
- meaning of โmissingโ, as in, our code is โmissingโ Javascript โฆ as well as how I feel with the masochism of the exercise, calling into play the โฆ
- meaning of โmissingโ, as in, itโs hard work writing meaningful web applications without Javascript โฆ but I guess weโll learn a bit from the exercise of โsee where we goโ, allowing for the fact, not today, but down the track, that we will allow the use of server-side languages such as PHP
Okay, so, given that restriction, letโs see todayโs challenge, to just use, in a web application โฆ
- HTML
- CSS
โฆ and here is where we have to point out that CSS3 introduced to us some functionality that improves the prospects for web application design โinterestโ without using Javascript (though it is hard to convince me even so, that I am not โmissingโ Javascript) here. CSS3 introduced to us โฆ
- calc method to assist with defining width and height and size dimensions along with operator โ+โ and/or โ-โ offset calculation opportunities, and which weโd have used the Javascript window.getComputedStyle and/or [element].getBoundingClientRect methods to cover this (in a much more unwieldy way, as you would probably surmise)
- CSS variables we started talking about here at CSS Variables Primer Tutorial
- CSS3 @keyframes rules we first talked about at CSS3 @keyframes Rule Primer Tutorial that assist with animations that we can make work via โฆ
- CSS3 transitions for scheduled functionality (weโd have used Javascript setTimeout (and setInterval) methods to cover the same โterritoryโ) we first talked about at CSS3 Transition Primer Tutorial โฆ specified with CSS Criteria involving โฆ
- CSS Selectors :after and :before (and often, as for todayโs work, with the content: CSS property) first talked about here with WordPress Bullet Point CSS Styling Primer Tutorial
โฆ and we use all of these in our Festive Season themed web application today, you can try at this liverunโs calc_use
html (free of any Javascript (but โwhyโ springs to mind โฆ because it is NOT there, perhaps?)).
Hereโs the other thing about today. Our long sought after โjust make the body background be semi-transparentโ but not its foreground parts, was solved, for us via the great advice of โฆ
- https://stackoverflow.com/questions/35669563/changing-the-opacity-of-background-image-in-css was a great link regarding semi-transparent background via CSS like โฆ
body {
background: URL(https://www.woodwardenglish.com/wp-content/uploads/2013/12/12-days-of-christmas.jpg) no-repeat center center fixed;
background-size: contain;
}
.banner {
background: rgba(220,220,255,0.8);
} - https://developer.mozilla.org/en-US/docs/Web/CSS/:root taught me how the :root { } CSS descriptor was a good place to define CSS (global) variables, thanks
- https://developer.mozilla.org/en-US/docs/Web/CSS/calc taught me lots regarding how to use CSS calc method, thanks
- https://codepen.io/robinrendle/embed/MaVPbo?height=300&theme-id=1&embed-version=2&slug-hash=MaVPbo&default-tab=result&user=robinrendle taught me lots of setting up the animation and transitioning in CSS, thanks
- https://www.google.com.au/search?q=lyrics+to+twelve+days+of+christmas&ie=utf-8&oe=utf-8&client=firefox-b-ab&gfe_rd=cr&dcr=0&ei=Z0U8WpLKEobp8wfejKjQDg is a great link to some lyrics, thanks
- https://www.woodwardenglish.com/wp-content/uploads/2013/12/12-days-of-christmas.jpg was link to very useful background image, thanks
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.
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.
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.