Important Announcement
PubHTML5 Scheduled Server Maintenance on (GMT) Sunday, June 26th, 2:00 am - 8:00 am.
PubHTML5 site will be inoperative during the times indicated!

Home Explore Front -End Web Development

Front -End Web Development

Published by Angarag, 2022-12-06 17:43:43

Description: Front -End Web Development

Search

Read the Text Version

["Save\tmain.js.\tWith\tthese\tvariables\tin\thand,\tlet\u2019s\ttake\tthem\tfor\ta\tspin\tin\tChrome\u2019s DevTools.","Working\tin\tthe\tConsole One\tof\tthe\tmost\tuseful\tparts\tof\tthe\tDevTools\tis\tthe\tconsole,\twhich\tlets\tyou\tenter JavaScript\tcode\tand\tevaluate\tit\timmediately.\tThis\tis\tespecially\tuseful\tfor\titeratively developing\tJavaScript\tcode\tthat\tmakes\tchanges\tto\ta\tpage. In\tthe\tDevTools,\tclick\ton\tthe\tConsole\ttab,\tto\tthe\tright\tof\tthe\tElements\ttab\t(Figure\t6.5). Figure\t6.5\t\tChoosing\tthe\tconsole\ttab The\tconsole\thas\ta\tprompt\twhere\tyou\tcan\tenter\tlines\tof\tcode.\tClick\tto\tthe\tright\tof\tthe\t symbol\tso\tthat\tthe\tconsole\tis\tready\tfor\tinput\t(Figure\t6.6). Figure\t6.6\t\tThe\tconsole,\tready\tfor\tinput Type\tthe\tfollowing\tmath\texpression\tinto\tthe\tconsole: 137\t+\t349 Press\tthe\tReturn\tkey.\tThe\tconsole\twill\tprint\tout\tthe\tresult\t(Figure\t6.7). Figure\t6.7\t\tEvaluating\ta\tmath\texpression The\tconsole\u2019s\tmain\tjob\tis\tto\ttell\tyou,\tin\tthe\tsimplest\tterms,\tthe\tvalue\tof\tthe\tcode\tyou\tenter. As\twith\tmany\tthings\tin\tlife,\torder\tmatters.\tIf\tyou\tneed\tcertain\titems\tto\tbe\tevaluated\tas\ta","group,\tyou\tcan\twrap\tparentheses\taround\tthem.\t(This\tis\tmuch\teasier\tthan\tmemorizing\tthe order\tin\twhich\tJavaScript\twould\tdo\tthis\twithout\tthe\tparentheses.)\tEnter\tthe\tfollowing expression\tin\tthe\tconsole. 3\t*\t(\t(2\t*\t4)\t+\t(3\t+\t5)\t) Press\tthe\tReturn\tkey,\tand\tthe\tconsole\twill\tcrunch\tthe\tnumbers\tin\tthe\tcorrect\torder (Figure\t6.8).\t(By\tthe\tway,\talthough\twe\thave\tadded\tspaces\tbetween\tthe\tnumbers\tand operators\tfor\tthe\tsake\tof\treadability,\tyou\tdo\tnot\tneed\tto\tinclude\tthem.\tThe\tconsole\tdoes not\tcare.) Figure\t6.8\t\tEvaluating\ta\tmore\tcomplex\tmath\texpression Now,\ton\tto\tusing\tyour\tvariables.\tYou\tcan\tclear\tthe\tcontents\tof\tthe\tconsole\tby\tpressing\tthe\t \ticon\tin\tthe\tupper\tleft\tof\tthe\tconsole\tpanel\tor\twith\tthe\tkeyboard\tshortcut\tCommand-K (Ctrl-K). Start\ttyping\tDETAIL_IMAGE_SELECTOR.\tAs\tyou\ttype\tthe\tfirst\tfew\tletters,\tyou\tcan\tsee\tthat the\tconsole\talready\tknows\tabout\tthe\tvariables\tyou\tcreated\tand\tprovides\ta\tlist\tof autocomplete\tsuggestions\t(Figure\t6.9). Figure\t6.9\t\tThe\tconsole\u2019s\tautocomplete\tmenu Press\tthe\tTab\tkey\tand\tlet\tthe\tconsole\tautocomplete\tthe\tvariable\tname\tfor\tyou.\tWhen\tyou press\tthe\tReturn\tkey,\tthe\tconsole\treports\tthat\tthe\tvalue\tof\tDETAIL_IMAGE_SELECTOR\tis\tthe string\t\\\"[data-image-role=\\\"target\\\"]\\\".","Figure\t6.10\t\tThe\tconsole\tprinting\ta\tvariable\u2019s\tvalue (The\tconsole\talways\tprints\tstrings\twith\tdouble\tquotes,\teven\tthough\tyou\tactually\tused single\tquotes\tin\tmain.js.) Strings\tare\tone\tof\tfive\tprimitive\tvalue\ttypes\tin\tJavaScript.\t(Numbers\tand\tBooleans\tare\ttwo of\tthe\tothers.)\tThey\tare\t\u201cprimitive\u201d\tbecause\tthey\trepresent\tsimple\tvalues.\tThis\tis\tin contrast\tto\tmore\tcomplex\tvalues\tin\tJavaScript,\twhich\tyou\twill\tlearn\tabout\tnext.","Accessing\tDOM\tElements You\thave\tjust\tseen\tthat\tthe\tconsole\tgives\tyou\taccess\tto\tthe\tvariables\tyou\tcreated.\tEarlier we\tsaid\tthat\tthese\tvariables\tcould\tbe\tused\tfor\taccessing\telements\ton\tthe\tpage.\tYou\tcan\ttry that\tnow.\tEnter\tthe\tfollowing\tin\tthe\tconsole: document.querySelector(DETAIL_IMAGE_SELECTOR); Press\tthe\tReturn\tkey.\tIt\twill\tshow\tyou\tthe\tHTML\tfor\tthe\tdetail\timage.\tHover\tover\tthis HTML\tin\tthe\tconsole.\tYou\twill\tsee\tthat\tthe\tdetail\timage\tis\thighlighted\ton\tthe\tpage,\tjust\tas if\tyou\tclicked\tHTML\tin\tthe\telements\tpanel\t(Figure\t6.11). Figure\t6.11\t\tHTML\tin\tthe\tconsole\tcorresponds\tto\tan\telement\ton\tthe\tpage In\tthe\tline\tof\tcode\tyou\twrote\ton\tthe\tconsole,\tthe\tword\tdocument\tis\tthe\tvariable\tbuilt\tinto the\tbrowser\tthat\tgives\tyou\taccess\tto\tthe\tweb\tpage.\tIts\tvalue\tis\tnot\tone\tof\tthe\tprimitive types.\tIt\tis\ta\tcomplex\tvalue,\twhose\ttype\tis\tobject. The\tdocument\tobject\tcorresponds\tto\tthe\tentire\tpage.\tIt\tgives\tyou\taccess\tto\ta\tnumber\tof methods\tfor\tgetting\treferences\tto\telements\ton\tthe\tpage.\tMethods\tare\ta\ttype\tof\tfunction (they\tare\tfunctions\twith\tan\texplicitly\tdesignated\towner,\tbut\tyou\tdo\tnot\tneed\tto\tworry about\tthat\tdetail\tright\tnow)\t\u2013\ta\tlist\tof\tsteps\tfor\tthe\tbrowser\tto\tfollow.\tYou\tused\tthe querySelector\tmethod\tin\tthe\tline\tyou\tentered\tin\tthe\tconsole.\tThe\tdot\toperator\t(i.e., the\tperiod)\tin\tdocument.querySelector\tis\thow\tyou\taccess\tan\tobject\u2019s\tmethods.","You\tasked\tthe\tdocument\tto\tuse\tits\tquerySelector\tmethod\tto\tfind\tany\telement matching\tthe\tstring\t'[data-image-role=\\\"target\\\"]'.\tquerySelector\tresponded\twith a\treference\tto\tthe\telement\tthat\tit\tfound,\tthe\tdetail\timage\t(Figure\t6.12). Figure\t6.12\t\tAccess\tto\tthe\tpage\tprovided\tby\tdocument\tand document.querySelector And\tnow,\ta\tbit\tof\tterminology.\tYou\tdid\tnot\treally\t\u201cask\u201d\tthe\tpage\tfor\tmatching\telements. You\tcalled\tthe\tdocument\u2019s\tquerySelector\tmethod\tand\tyou\tpassed\tit\ta\tstring.\tThe method\treturned\ta\treference\tto\tthe\tdetail\timage\telement. When\tyou\tcall\ta\tmethod,\tyou\tare\tmaking\tit\trun\twhatever\ttask\tit\twas\tdesigned\tto\tperform. You\twill\toften\tneed\tto\tpass\tit\tinformation\tit\tneeds\tto\tdo\tthat\ttask,\twhich\tyou\tplace\tin parentheses\tafter\tthe\tmethod\u2019s\tname.\tThen,\tin\taddition\tto\tits\tassigned\ttasks,\tthe\tmethod may\treturn\ta\tvalue\tthat\tyou\tcan\tuse. Remember\tthat\tDETAIL_IMAGE_SELECTOR\twas\tassigned\tthe\tvalue\t'[data-image- role=\\\"target\\\"]',\twhich\tmeans\tthat\tthis\tis\twhat\tis\tpassed\tto\tquerySelector. Behind\tthe\tscenes,\tquerySelector\tuses\tthis\tstring\tto\tsearch\tfor\tany\telements\tthat match\tthat\tselector.\tWhen\tit\tsearches,\tthe\tdocument\tis\tnot\tactually\tsearching\tthe\tpage,\tit\tis searching\tthe\tdocument\tobject\tmodel,\tor\tDOM.\tThe\tDOM\tis\tthe\tbrowser\u2019s\tinternal representation\tof\tan\tHTML\tdocument.\tIt\tbuilds\tthis\trepresentation\tas\tit\treads\tthrough\tand interprets\tthe\tHTML. In\tJavaScript,\tyou\tcan\tinteract\twith\tthe\tDOM\tusing\tthe\tdocument\tobject\tand\tits\tmethods, such\tas\tquerySelector.\tFor\teach\tHTML\ttag,\tthere\tis\ta\tcorresponding\telement\tin\tthe DOM,\tand\tyou\tcan\tinteract\twith\tany\tof\tthese\telements\tusing\tJavaScript.\t(Generally,\twhen we\trefer\tto\tan\t\u201celement,\u201d\twe\tmean\ta\t\u201cDOM\telement.\u201d) In\tthe\tconsole,\tcall\tdocument.querySelector\tagain,\tpassing\tit DETAIL_IMAGE_SELECTOR\tto\tget\ta\treference\tto\tthe\telement\tfor\tthe\tdetail\timage.\tBut\tthis time,\tassign\tthe\treference\tto\ta\tnew\tvariable\tnamed\tdetailImage:","var\tdetailImage\t=\tdocument.querySelector(DETAIL_IMAGE_SELECTOR); Press\tReturn,\tand\tthe\tconsole\twill\tprint\tundefined\t(Figure\t6.13).\tDo\tnot\tpanic!\tThis\tis\tnot an\terror. Figure\t6.13\t\tDeclaring\ta\tvariable\tin\tthe\tconsole The\tconsole\tis\tjust\tdoing\tits\tjob,\ttelling\tyou\tthat\tthere\tis\tno\tresulting\tvalue\tfrom\tdeclaring a\tvariable.\tIn\tJavaScript,\tthe\tabsence\tof\ta\tvalue\tis\trepresented\tby\tthe\tkeyword\tundefined. That\tdoes\tnot\tmean\tthat\tyour\tdetailImage\tvariable\twas\tnot\tassigned.\tTo\tcheck\tit,\tjust type\tdetailImage\tin\tthe\tconsole\tand\tpress\tReturn.\tYou\twill\tsee\tthe\tHTML representation\tof\tthe\tdetail\timage,\tjust\tas\tyou\tsaw\twhen\tyou\tentered document.querySelector(DETAIL_IMAGE_SELECTOR)\t(Figure\t6.14). Figure\t6.14\t\tChecking\tthe\tvalue\tof\tdetailImage","What\tis\tthe\tpoint\tof\tall\tthis?\tBy\tassigning\ta\treference\tto\ta\tvariable,\tyou\tcan\tuse\tthe variable\tname\tany\ttime\tyou\twant\tto\trefer\tto\tthe\telement.\tNow,\tinstead\tof\thaving\tto\ttype document.querySelector(DETAIL_IMAGE_SELECTOR)\tevery\ttime,\tyou\tcan\tjust\ttype detailImage. When\tyou\thave\ta\treference\tto\tthe\tdetail\timage,\tit\tis\teasy\tto\tchange\tthe\tvalue\tof\tits\tsrc attribute.\tIn\tthe\tconsole,\tassign\tdetailImage.src\tto\tthe\tstring\t'img\/otter2.jpg'. detailImage.src\t=\t'img\/otter2.jpg'; Using\tthe\tdot\toperator,\tyou\taccessed\tthe\tsrc\tproperty\tof\tthe\tdetailImage\tobject.\tA property\tis\tlike\ta\tvariable,\tbut\tit\tbelongs\tto\ta\tparticular\tobject.\tWhen\tyou\tassign\t(or\tset) src\tto\tthe\tstring\t'img\/otter2.jpg',\tyou\twill\tsee\tthat\ta\tdifferent\totter\toccupies\tthe\tdetail image\tarea\t(Figure\t6.15). Figure\t6.15\t\tSetting\tthe\tsrc\tproperty\tof\tthe\tdetail\timage The\tsrc\tproperty\tcorresponds\tto\tthe\tsrc\tattribute\tof\tthe\t<img>\ttag\tin\tindex.html. Because\tof\tthis\trelationship,\tanother\tway\tto\tachieve\tthe\tsame\tresult\tis\tto\tuse\tthe detailImage\u2019s\tsetAttribute\tmethod. Call\tthis\tmethod\tin\tthe\tconsole\tand\tpass\tit\ttwo\tstrings:\tthe\tname\tof\tthe\tattribute\tand\tthe new\tvalue. detailImage.setAttribute('src',\t'img\/otter3.jpg'); The\tdetail\timage\tchanges\tonce\tagain\t(Figure\t6.16).","Figure\t6.16\t\tUsing\tsetAttribute\tto\tchange\tthe\timage You\tnow\thave\tall\tthe\tpieces\tyou\tneed\tto\tcreate\tan\tautomated\tway\tto\tchange\tthe\tdetail image.\tGet\tready\tto\twrite\tyour\tfirst\tfunction!","Writing\tthe\tsetDetails\tFunction You\thave\tbeen\tworking\twith\tmethods\tand\thave\tseen\tthat\tthey\tcan\tbe\tinvoked\tto\tcause\ta block\tof\tcode\tto\trun.\tFunctions\tand\tmethods\tare\treally\tjust\ta\tlist\tof\tsteps\tthat\tyou\twould like\tto\tuse\tagain\tand\tagain.\tCalling\ta\tfunction\tis\tlike\tsaying\t\u201cMake\ta\tsandwich\u201d\tinstead\tof \u201cLay\tout\ttwo\tslices\tof\tbread.\tPut\tprosciutto,\tsalami,\tand\tprovolone\ton\tone\tslice.\tPut\tthe other\tslice\tof\tbread\ton\ttop.\u201d You\twill\twrite\tseven\tfunctions\tfor\tOttergram\tin\tthis\tchapter.\tYour\tfirst\tfunction\twill\tdo two\tthings:\tchange\tthe\tdetail\timage\tand\tthe\tdetail\timage\ttitle.\tAdd\tthis\tfunction declaration\tto\tmain.js. var\tDETAIL_IMAGE_SELECTOR\t=\t'[data-image-role=\\\"target\\\"]'; var\tDETAIL_TITLE_SELECTOR\t=\t'[data-image-role=\\\"title\\\"]'; var\tTHUMBNAIL_LINK_SELECTOR\t=\t'[data-image-role=\\\"trigger\\\"]'; function\tsetDetails()\t{ \t\t'use\tstrict'; \t\t\/\/\tCode\twill\tgo\there } You\tdeclared\ta\tfunction\tnamed\tsetDetails\tusing\tthe\tfunction\tkeyword.\tWhen declaring\ta\tfunction,\tthe\tname\tis\talways\tfollowed\tby\ta\tpair\tof\tparentheses.\tThey\tare\tnot part\tof\tthe\tname,\thowever\t\u2013\tyou\twill\tfind\tout\twhat\tthey\tare\tfor\tsoon. After\tthe\tparentheses\tis\ta\tpair\tof\tcurly\tbraces.\tInside\tthe\tcurly\tbraces\tis\tthe\tbody\tof\tthe function.\tThe\tbody\twill\tcontain\tthe\tsteps\tthe\tfunction\tneeds\tto\tperform.\tThese\tsteps\tare more\tformally\treferred\tto\tas\tstatements. The\tfirst\tline\tof\tyour\tfunction\tis\tthe\tstring\t'use\tstrict';.\tYou\twill\tuse\tthis\tstring\tat\tthe beginning\tof\tall\tyour\tfunctions\tto\ttell\tthe\tbrowser\tthat\tthey\tconform\tto\tthe\tmost\trecent standard\tversion\tof\tJavaScript.\t(There\tis\tmore\tabout\tstrict\tmode\tin\ta\tFor\tthe\tMore\tCurious section\tat\tthe\tend\tof\tthis\tchapter.) The\tother\tline\tin\tthe\tsetDetails\tfunction\tis\ta\tcomment.\tLike\tCSS\tcomments, JavaScript\tcomments\tare\tignored\tby\tthe\tbrowser\tbut\tuseful\tfor\tdevelopers.\tJavaScript comments\tthat\tare\tonly\tone\tline\tcan\tbe\twritten\tthis\tway,\twith\t\/\/.\tFor\tcomments\tthat\tspan multiple\tlines,\tyou\tcan\tuse\tthe\t\/*\t*\/\tstyle.\tBoth\tare\tcorrect\tin\tJavaScript. In\tthe\tconsole,\tyou\thave\talready\ttried\tout\tall\tof\tthe\tstatements\tneeded\tto\tchange\tthe\tphoto in\tthe\tdetail\timage.\tGo\tback\tto\tthe\tconsole\tand\tpress\tthe\tUp\tarrow\tkey.\tYou\twill\tsee\tthe most\trecent\tstatement\tyou\tentered\tcopied\tat\tthe\tprompt.\tThe\tUp\tand\tDown\tarrows\tallow you\tto\tgo\tbackward\tand\tforward\tthrough\tyour\thistory\tof\tstatements. Using\tthe\tarrow\tkeys,\tfind\tthe\tstatement\tthat\tgets\ta\treference\tto\tthe\tdetail\timage:\tvar detailImage\t=\tdocument.querySelector(DETAIL_IMAGE_SELECTOR);.\tCopy\tthis\tline from\tthe\tconsole\tand\tpaste\tit\tinto\tmain.js\tin\tplace\tof\tthe\tcomment.\tThen,\tcopy\tand paste\tthe\tline\tin\tthe\tconsole\tthat\tcalls\tthe\tdetailImage.setAttribute\tmethod: detailImage.setAttribute('src',\t'img\/otter3.jpg');. Your\tsetDetails\tfunction\tin\tmain.js\tshould\tlook\tlike\tthis: ... function\tsetDetails()\t{ \t\t'use\tstrict'; \t\t\/\/\tCode\twill\tgo\there \t\tvar\tdetailImage\t=\tdocument.querySelector(DETAIL_IMAGE_SELECTOR);","detailImage.setAttribute('src',\t'img\/otter3.jpg'); } Save\tmain.js\tand\tgo\tback\tto\tthe\tconsole.\tEnter\tthe\tfollowing\tand\tpress\tReturn\tto\trun your\tsetDetails\tfunction. setDetails(); Entering\t\u2013\tor\tcalling\t\u2013\tthe\tname\tof\ta\tfunction\tfollowed\timmediately\tby\tparentheses\tmakes the\tfunction\texecute\tall\tof\tthe\tcode\tin\tits\tbody.\tYou\tshould\tsee\tthat\timg\/otter3.jpg\tis now\tdisplayed\tas\tthe\tdetail\timage\t(Figure\t6.17). Figure\t6.17\t\tRunning\tsetDetails\tto\tchange\tthe\timage setDetails\thas\tchanged\tthe\tdetail\timage,\tbut\tnot\tthe\tdetail\timage\ttitle.\tYou\twant\tit\tto do\tboth.\tAs\tyou\tdid\twith\tthe\tdetail\timage,\tyou\twill\tadd\tstatements\tto\tget\ta\treference\tto\tthe element\tand\tto\tchange\tthe\telement\u2019s\tproperties. In\tyour\tsetDetails\tfunction\tin\tmain.js,\tcall\tdocument.querySelector\tagain, passing\tit\tDETAIL_TITLE_SELECTOR.\tAssign\tthe\tresult\tto\ta\tnew\tvariable\tnamed detailTitle.\tThen,\tset\tits\ttextContent\tproperty\tto\t'You\tShould\tBe\tDancing'. ... function\tsetDetails()\t{ \t\t'use\tstrict'; \t\tvar\tdetailImage\t=\tdocument.querySelector(DETAIL_IMAGE_SELECTOR); \t\tdetailImage.setAttribute('src',\t'img\/otter3.jpg'); \t\tvar\tdetailTitle\t=\tdocument.querySelector(DETAIL_TITLE_SELECTOR); \t\tdetailTitle.textContent\t=\t'You\tShould\tBe\tDancing'; } The\ttextContent\tproperty\tis\tthe\ttext\t(not\tincluding\tHTML\ttags)\tinside\tof\tan\telement. Save\tyour\tchanges\tand\trun\tsetDetails\tin\tthe\tconsole.\tNow\tthe\timage\tand\ttitle\tchange (Figure\t6.18).","Figure\t6.18\t\tChanging\tthe\timage\tand\ttitle\tusing\tsetDetails Accepting\targuments\tby\tdeclaring\tparameters setDetails\tdoes\tthe\twork\tof\tchanging\tthe\tdetail\timage\tand\ttitle.\tBut\tevery\ttime\tyou run\tit,\tit\tsets\tthe\timage\u2019s\tsrc\tto\t'img\/otter3.jpg'\tand\tthe\ttitle\u2019s\ttextContent\tto\t'You Should\tBe\tDancing'.\tWhat\tif\tyou\twant\tto\tuse\tother\timages\tand\ttext? You\tneed\ta\tway\tto\ttell\tsetDetails\twhich\timage\tand\twhat\ttext\tto\tuse\twhen\tyou\tcall\tit. To\tachieve\tthis,\tyou\tneed\tyour\tfunction\tto\taccept\targuments\t\u2013\tvalues\tthat\tare\tpassed\tto\tthe function\tand\tthat\tit\tcan\twork\twith.\tAnd\tto\tdo\tthat,\tyou\thave\tto\tspecify\tparameters\tin\tthe function\tdeclaration. Add\ttwo\tparameters\tto\tsetDetails\tin\tmain.js: ... function\tsetDetails(imageUrl,\ttitleText)\t{ \t\t'use\tstrict'; \t\tvar\tdetailImage\t=\tdocument.querySelector(DETAIL_IMAGE_SELECTOR); \t\tdetailImage.setAttribute('src',\t'img\/otter3.jpg'); \t\tvar\tdetailTitle\t=\tdocument.querySelector(DETAIL_TITLE_SELECTOR); \t\tdetailTitle.textContent\t=\t'You\tShould\tBe\tDancing'; } Now,\tuse\tthose\tparameters\tin\tplace\tof\t'img\/otter3.jpg'\tand\t'You\tshould\tBe Dancing': ... function\tsetDetails(imageUrl,\ttitleText)\t{","'use\tstrict'; \t\tvar\tdetailImage\t=\tdocument.querySelector(DETAIL_IMAGE_SELECTOR); \t\tdetailImage.setAttribute('src',\t'img\/otter3.jpg'); \t\tdetailImage.setAttribute('src',\timageUrl); \t\tvar\tdetailTitle\t=\tdocument.querySelector(DETAIL_TITLE_SELECTOR); \t\tdetailTitle.textContent\t=\t'You\tShould\tBe\tDancing'; \t\tdetailTitle.textContent\t=\ttitleText; } Your\ttwo\tparameters,\timageUrl\tand\ttitleText,\tare\tused\tas\tlabels\tassigned\tto\tvalues passed\tto\tsetDetails.\tSave\tmain.js\tand\ttry\tit\tout\tin\tthe\tconsole\tto\tsee\tthis\tworking. Call\tsetDetails\tand\tpass\tit\tthe\tvalues\t'img\/otter4.jpg'\tand\t'Night\tFever'.\t(Make sure\tthere\tis\ta\tcomma\tbetween\tthem.) setDetails('img\/otter4.jpg',\t'Night\tFever'); You\tshould\tsee\tthe\tnew\timage\tand\ttitle\ttext,\tas\tin\tFigure\t6.19. Figure\t6.19\t\tPassing\tvalues\tto\tsetDetails There\tis\tan\timportant\tdistinction\tbetween\targuments\tand\tparameters.\tParameters\tare defined\tas\tpart\tof\tthe\tfunction.\tIn\tJavaScript,\tparameters\tare\texactly\tlike\tvariables\tthat\tare declared\tinside\ta\tfunction\tbody.\tArguments\tare\tvalues\tyou\tsupply\tto\ta\tfunction\twhen\tyou call\tit. Also,\tbe\taware\tthat\tno\tmatter\twhat\tvariable\tnames\tyou\tuse\tfor\tyour\targuments,\ttheir values\tare\talways\tmapped\tto\tthe\tparameter\tnames\tso\tthey\tcan\tbe\tused\tinside\tthe\tfunction body.\tFor\texample,\timagine\tthat\tyou\tused\tvariables\tfor\tthe\timage\tURL\tand\tthe\ttitle\ttext. When\tyou\tcall\tsetDetails,\tyou\tpass\tin\tthese\ttwo\tvariables\tas\targuments. var\totterOneImage\t=\t'img\/otter1.jpg'; var\totterOneTitle\t=\t'Stayin\\\\'\tAlive'; setDetails(otterOneImage,\totterOneTitle); The\tsetDetails\tfunction\taccepts\tthe\tvalues,\tlabels\tthem\twith\tthe\tparameter\tnames imageUrl\tand\ttitleText,\tand\tthen\truns\tthe\tcode\tinside\tits\tbody.\tThat\tcode\tuses\timageUrl","and\ttitleText,\tpassing\tthem\tas\targuments\tto\tdocument.querySelector. Like\tvariable\tnames,\tparameter\tnames\tare\tjust\tlabels\tfor\tvalues.\tYou\tcan\tuse\twhatever parameter\tnames\tyou\tlike,\tbut\tit\tis\tgood\tpractice\tto\tuse\tdescriptive\tnames,\tas\tyou\thave done\there,\tto\tmake\tyour\tcode\teasier\tto\tread\tand\tmaintain.","Returning\tValues\tfrom\tFunctions You\thave\tcompleted\tthe\tfirst\t(or,\trather,\tlast)\titem\ton\tthe\tplan\tand\tpicked\tup\tsome JavaScript\tknow-how\talong\tthe\tway.\tNow\tyou\twill\tmove\ton\tto\tthe\tnext\ttwo\titems\ton\tthe list:\tgetting\tthe\timage\tand\tthe\ttitle\tfrom\ta\tthumbnail.\tFor\teach\tof\tthese,\tyou\twill\twrite\ta new\tfunction. Add\ta\tfunction\tdeclaration\tin\tmain.js\tfor\timageFromThumb.\tIt\twill\taccept\ta\tsingle parameter,\tthumbnail,\twhich\tis\ta\treference\tto\ta\tthumbnail\tanchor\telement.\tIt\twill\tretrieve and\treturn\tthe\tvalue\tof\tthe\tdata-image-url\tattribute. ... function\tsetDetails(imageUrl,\ttitleText)\t{ \t\t... } function\timageFromThumb(thumbnail)\t{ \t\t'use\tstrict'; \t\treturn\tthumbnail.getAttribute('data-image-url'); } The\tgetAttribute\tmethod\tdoes\tthe\topposite\tof\tthe\tsetAttribute\tmethod\tyou used\tin\tthe\tsetDetails\tfunction.\tIt\tonly\ttakes\ta\tsingle\targument,\tthe\tname\tof\tan attribute. Unlike\tsetDetails,\tthe\timageFromThumb\tfunction\tuses\tthe\treturn\tkeyword.\tWhen you\tcall\ta\tfunction\tthat\thas\ta\treturn\tstatement,\tit\tgives\tyou\tback\ta\tvalue. querySelector\tis\tan\texample\tof\tthis.\tWhen\tyou\tcalled\tit,\tit\treturned\ta\tvalue\tthat\tyou then\tassigned\tto\ta\tvariable. Save\tmain.js\tand\ttry\tout\tthe\tfollowing\tin\tthe\tconsole,\tpressing\tReturn\tbetween\tthe lines. var\tfirstThumbnail\t=\tdocument.querySelector(THUMBNAIL_LINK_SELECTOR); imageFromThumb(firstThumbnail); The\tconsole\treports\tthat\tthe\tvalue\treturned\twas\tthe\tstring\t\\\"img\/otter1.jpg\\\",\tbecause imageFromThumb\treturns\tthe\tdata-image-url\tof\tthe\tthumbnail. Figure\t6.20\t\tValue\treturned\tfrom\timageFromThumb Note\tthat\tany\tstatements\tthat\tcome\tafter\ta\treturn\tstatement\twill\tnot\tbe\trun.\tA\treturn statement\teffectively\tstops\ta\trunning\tfunction.","The\tnext\tfunction\tto\twrite\tis\tone\tthat\twill\taccept\ta\tthumbnail\telement\treference\tand\treturn the\ttitle\ttext. Add\ta\tfunction\tdeclaration\tin\tmain.js\tfor\ttitleFromThumb,\twith\ta\tthumbnail parameter.\tIt\twill\treturn\tthe\tvalue\tof\tthe\tdata-image-title\tattribute. ... function\timageFromThumb(thumbnail)\t{ \t\t... } function\ttitleFromThumb(thumbnail)\t{ \t\t'use\tstrict'; \t\treturn\tthumbnail.getAttribute('data-image-title'); } Save\tmain.js\tand\ttry\tthis\tfunction\tout\tin\tthe\tconsole,\ttoo: var\tfirstThumbnail\t=\tdocument.querySelector(THUMBNAIL_LINK_SELECTOR); titleFromThumb(firstThumbnail); Figure\t6.21\t\tValue\treturned\tfrom\ttitleFromThumb The\tnext\tfunction\tto\twrite\tbrings\tthe\tthree\tother\tfunctions\ttogether\tfor\tconvenience,\tso that\tyou\tdo\tnot\tneed\tto\tcall\tthem\tseparately.\tIt\twill\taccept\ta\treference\tto\ta\tthumbnail element\tand\tthen\tcall\tsetDetails,\tpassing\tin\tthe\tvalues\tfrom\tcalling imageFromThumb\tand\ttitleFromThumb. Add\tsetDetailsFromThumb\tin\tmain.js. ... function\ttitleFromThumb(thumbnail)\t{ \t\t... } function\tsetDetailsFromThumb(thumbnail)\t{ \t\t'use\tstrict'; \t\tsetDetails(imageFromThumb(thumbnail),\ttitleFromThumb(thumbnail)); } Notice\tthat\tsetDetails\tis\tbeing\tcalled\twith\ttwo\targuments\t\u2013\tand\tthose\targuments\tare function\tcalls,\ttoo.\tHow\tdoes\tthis\twork? Before\tsetDetails\tis\tactually\tcalled,\tits\targuments\tare\treduced\tto\ttheir\tsimplest values.\tFirst,\timageFromThumb(thumbnail)\truns\tand\treturns\ta\tvalue.\tThen, titleFromThumb(thumbnail)\truns\tand\treturns\ta\tvalue.\tFinally,\tsetDetails\tis called\twith\tthe\tvalues\treturned\tby\timageFromThumb(thumbnail)\tand titleFromThumb(thumbnail).\tFigure\t6.22\tshows\tthis\tprocess.","Figure\t6.22\t\tFunction\tcalls\tas\targuments Save\tmain.js.\tYou\thave\tcompleted\tall\tthe\tcode\tfor\tretrieving\tdata-attribute\tvalues\tfrom thumbnails\tand\tusing\tthose\tvalues\tto\tupdate\twhat\tis\tshown\tin\tthe\tdetail\timage\tand\ttitle. Moving\tup\tfrom\tthe\tlow-level\toperations,\tthe\tnext\tthing\tto\tdo\tis\twrite\tcode\tthat\twill perform\tyour\tdata\ttransfer\tfrom\tthumbnail\tto\tdetail\twhen\tthe\tuser\tclicks\ta\tthumbnail.","Adding\tan\tEvent\tListener Browsers\tare\tbusy\tpieces\tof\tsoftware.\tEvery\ttap,\tclick,\tscroll,\tand\tkeystroke\tis\tnoticed\tby the\tbrowser.\tEach\tof\tthese\tis\tan\tevent\tthat\tthe\tbrowser\tmay\trespond\tto.\tTo\tmake\twebsites more\tdynamic\tand\tinteractive,\tyou\tcan\ttrigger\tyour\town\tcode\twhen\tone\tof\tthese\tevents occurs.\tIn\tthis\tsection,\tyou\twill\tadd\tevent\tlisteners\tto\teach\tof\tyour\tthumbnails. An\tevent\tlistener\tis\tan\tobject\tthat,\tas\tthe\tname\tsuggests,\t\u201clistens\u201d\tfor\ta\tparticular\tevent, such\tas\ta\tmouse\tclick.\tWhen\tits\tassigned\tevent\toccurs,\tthe\tevent\tlistener\ttriggers\ta function\tcall\tin\tresponse\tto\tthe\tevent. (Mouse\tevents,\tlike\tclicks\tand\tdouble-clicks,\tand\tkeyboard\tevents\tlike\tkeypresses\tare among\tthe\tmost\tcommon\tevent\ttypes.\tFor\ta\tcomplete\tlisting\tof\tevents,\tcheck\tthe\tevent reference\tin\tthe\tMDN\tat\tdeveloper.mozilla.org\/e\u200b n-US\/\u200bdocs\/W\u200b eb\/\u200b Events.) The\taddEventListener\tmethod\tis\tavailable\ton\tevery\tDOM\telement,\tincluding\tthe document.\tAs\tbefore,\tyou\twill\texperiment\twith\tsome\tcode\tin\tthe\tconsole\tfirst\tand\tthen\tuse your\ttested\tcode\tto\twrite\tfunctions\tin\tmain.js. Switch\tto\tChrome\tand\tenter\tthe\tfollowing\tcode\tin\tthe\tconsole.\tYou\twill\tneed\tto\tpress\tShift- Return\tto\tenter\tthe\tline\tbreaks.\tPress\tReturn\twhen\tyou\thave\tfinished\ttyping\tall\tthe\tcode. document.addEventListener('click',\tfunction\t()\t{ \t\tconsole.log('you\tclicked!'); }); The\tcode\tyou\tentered\tadded\tan\tevent\tlistener\tfor\tthe\tdocument\tobject\tthat\tis\tlistening\tfor any\tclicks\tthat\toccur\ton\tthe\tpage.\tWhen\ta\tclick\thappens,\tthe\tevent\tlistener\twill\tprint\t\u201cyou clicked!\u201d\tto\tthe\tconsole\tusing\tthe\tbuilt-in\tconsole.log\tmethod\t(Figure\t6.23).","Figure\t6.23\t\tAdding\ta\tlistener\tfor\tclick\tevents Click\ton\tthe\theader,\tthe\tdetail\timage,\tor\tthe\tbackground.\tYou\tshould\tsee\tthat\tthe\ttext\t\u201cyou clicked!\u201d\tappears\tprinted\tin\tthe\tconsole.\t(Do\tnot\tclick\tthe\tthumbnails\t\u2013\tthose\twill\ttake you\taway\tfrom\tOttergram\u2019s\tindex.html\tpage.\tWhen\tyou\tare\tnot\ton\tthe\tindex.html page,\tnone\tof\tyour\tmarkup,\tCSS,\tor\tJavaScript\twill\tbe\tloaded\tand\trunning\tin\tthe\tbrowser.) addEventListener\taccepts\ttwo\targuments:\ta\tstring\twith\tthe\tname\tof\tthe\tevent\tand\ta function.\tThis\tfunction\twill\tbe\trun\tby\taddEventListener\tany\ttime\tthe\tevent\toccurs for\tthe\telement.\tThe\tway\tthis\tfunction\tis\twritten\tmay\tlook\ta\tlittle\tstrange\tat\tfirst.\tIt\tis\tan anonymous\tfunction. So\tfar,\tyou\thave\tworked\twith\tnamed\tfunctions,\tlike\tsetDetails\tand titleFromThumb.\tNamed\tfunctions\thave\tnames\t\u2013\tno\tsurprise\tthere\t\u2013\tand\tare\tcreated using\tfunction\tdeclarations. You\tcan\talso\twrite\tliteral\tfunction\tvalues,\tthe\tsame\tway\tyou\tcan\twrite\tliteral\tnumber values\tlike\t42\tand\tliteral\tstring\tvalues\tlike\t\\\"Barry\tthe\tOtter\\\".\tAnother\tname\tfor\tliteral function\tvalues\tis\tanonymous\tfunctions. Anonymous\tfunctions\tare\tfrequently\tused\tas\targuments\tto\tother\tfunctions,\tlike\tthe\tone you\tpassed\tas\tthe\tsecond\targument\tto\tdocument.addEventListener.\tThis\tpractice of\tpassing\ta\tfunction\tto\tanother\tfunction\tis\tquite\tcommon\tin\tJavaScript\tand\tis\tknown\tas\ta callback\tpattern\tbecause\tthe\tfunction\tyou\tpass\tin\tas\tan\targument\twill\tget\t\u201ccalled\tback\u201d\tat some\tpoint\tin\tthe\tfuture. It\tis\tperfectly\tfine\tto\tuse\ta\tnamed\tfunction\tas\ta\tcallback,\tbut\tmany\tfront-end\tdevelopers will\tuse\tanonymous\tfunctions\tbecause\tthey\tcan\tprovide\tmore\tflexibility\tthan\tnamed functions.\tYou\twill\tsee\thow\tthis\tworks\tshortly. Now\tyou\twill\tadd\tan\tevent\tlistener\tfor\tan\tindividual\tthumbnail.\tEnter\tthe\tfollowing\tin\tthe console.\t(Remember\tto\tuse\tShift-Return\tfor\tthe\tline\tbreaks\tin\tthe\tcall\tto","firstThumbnail.addEventListener.) var\tfirstThumbnail\t=\tdocument.querySelector(THUMBNAIL_LINK_SELECTOR); firstThumbnail.addEventListener('click',\tfunction\t()\t{ \t\tconsole.log('you\tclicked!'); }); If\tyou\ttry\tclicking\tthe\tfirst\tthumbnail\t(Barry\tthe\tOtter,\tfarthest\tto\tthe\tleft),\tyour\tbrowser will\ttake\tyou\tto\tthe\tlarge\timage\tof\tBarry.\tWhat\thappened?\tRemember\tthat\teach\tthumbnail is\twrapped\tin\tan\tanchor\ttag\twith\tan\thref\tthat\tpoints\tto\tan\timage,\tlike img\/otter1.jpg.\tThis\tis\tthe\tnormal\tbehavior\tof\ta\tbrowser\twhen\ta\tuser\tclicks\ta\tlink: It\thas\topened\tthe\tfile\tindicated\tby\tthe\thref\tattribute. But\tyou\tdo\tnot\twant\tto\tnavigate\taway\tfrom\tOttergram\twhen\ta\tthumbnail\tis\tclicked,\tand you\tshould\tnot\thave\tto\tchange\tyour\tanchor\ttags\tto\tsomething\telse.\tLuckily,\tyou\tcan handle\tall\tof\tthis\tfrom\tyour\tcallback\tfunction. Recall\tfrom\tearlier\tin\tthe\tchapter\tthat\tfunctions\tcarry\tout\ttheir\ttasks\twithout\tyou\thaving\tto worry\tabout\tthe\tdetails.\tUsually\tyou\tonly\tneed\tto\tknow\twhat\tinformation\tto\tpass\tas arguments\tand\twhat\tinformation\twill\tbe\treturned.\tWhen\tyou\tpass\ta\tcallback\tfunction\tas\tan argument,\tthere\tis\tone\tmore\tthing\tyou\tneed\tto\tknow:\twhat\tinformation\twill\tbe\tpassed\tto your\tcallback. When\tyou\tcall\taddEventListener,\tyou\tare\ttelling\tthe\tbrowser,\t\u201cWhen\tthe firstThumbnail\tis\tclicked,\tcall\tthis\tfunction\u201d\t\u2013\tand\tthen\tthe\tbrowser\tdiligently\twaits\tfor that\telement\tto\tbe\tclicked.\tIf\ta\tclick\thappens,\tthe\tbrowser\tmakes\tnote\tof\tall\tthe\tdetails about\tthe\tevent\t(such\tas\tthe\texact\tposition\tof\tthe\tmouse,\twhether\tit\twas\tthe\tleft\tor\tright mouse\tbutton,\tand\twhether\tit\twas\ta\tsingle\tor\tdouble\tclick).\tThe\tbrowser\tthen\tpasses\tan object\twith\tthis\tinformation\tto\tyour\tfunction.\tThis\tobject\tis\tan\tevent\tobject. This\trelationship\tis\tdiagrammed\tin\tFigure\t6.24,\tusing\ta\tmade-up\timplementation\tof addEventListener. Figure\t6.24\t\tPassing\tan\tanonymous\tfunction\tthat\texpects\tan\targument","In\ta\tmoment,\tyou\twill\tpass\tan\tanonymous\tfunction\tto\taddEventListener,\tjust\tlike before.\tBut,\tthis\ttime,\tyour\tanonymous\tfunction\twill\texpect\tto\treceive\tan\targument.\tMake sure\tOttergram\tis\ton\tthe\tindex.html\tpage\tand\tenter\tthe\tfollowing\tin\tthe\tconsole: var\tfirstThumbnail\t=\tdocument.querySelector(THUMBNAIL_LINK_SELECTOR); firstThumbnail.addEventListener('click',\tfunction\t(event)\t{ \t\tevent.preventDefault(); \t\tconsole.log('you\tclicked!'); \t\tconsole.log(event); }); The\tbrowser\twill\tcall\tyour\tanonymous\tfunction\teach\ttime\tfirstThumbnail\tis\tclicked, and\tit\twill\tpass\tyour\tanonymous\tfunction\tthe\tevent\tobject.\tUsing\tthis\tobject\t(which\tyou have\tlabeled\tevent),\tyou\tcall\tits\tpreventDefault\tmethod.\tThis\tmethod\twill\tstop\tthe link\tfrom\ttaking\tthe\tbrowser\tto\ta\tdifferent\tpage.\tFinally,\tyou\tcall\tconsole.log\ton\tthe event\tobject\tso\tthat\tyou\tcan\tinspect\tit\tin\tthe\tDevTools. Now\tclick\ton\tthe\tfirst\tthumbnail.\tYour\tbrowser\tremains\ton\tthe\tOttergram\tpage\tand\tthe event\tis\tlogged\tto\tthe\tconsole:\tMouseEvent\t{isTrusted:\ttrue}.\tIf\tyou\tclick\tthe disclosure\tarrow\tnext\tto\tMouseEvent,\tyou\tshould\tsee\tquite\ta\tbit\tof\tinformation\tabout\tthe event\t(Figure\t6.25),\tincluding\tthe\tmouse\tcoordinates\ton\tthe\tpage,\twhich\tmouse\tbutton was\tclicked,\tand\twhether\tany\tspecial\tmodifier\tkeys\twere\tpressed\tduring\tthe\tclick. Figure\t6.25\t\tPreventing\tthe\tevent\tdefault\tand\tlogging\tthe\tevent\tobject For\tnow,\tdo\tnot\tfocus\ton\tthe\tdifferent\tproperties\tof\tthe\tevent\tobject.\tJust\tknow\tthat\tit carries\tlots\tof\tinformation\tabout\tthe\tbrowser\tevent\tthat\twas\ttriggered. By\tthe\tway,\tit\tis\tnot\trequired\tthat\tthe\tcallback\tfunction\u2019s\tparameter\tbe\tnamed\tevent\t\u2013\tit will\tbe\tmapped\tto\tthe\tvalue\tthat\tis\tpassed\tin\tno\tmatter\twhat\tyou\tname\tit.\tYou\tcan\tuse whatever\tparameter\tnames\tyou\tlike,\tbut\tit\tis\tgood\tpractice\tto\tuse\tdescriptive\tnames,\tas you\thave\tdone\there,\tto\tmake\tyour\tcode\teasier\tto\tread\tand\tmaintain. You\tnow\thave\ta\tfunction\tthat\taccepts\ta\tthumbnail\tand\tadds\tan\tevent\tlistener.\tAdd\ta","function\tdeclaration\tto\tmain.js\tfor\taddThumbClickHandler.\tIt\tshould\tdefine\ta parameter\tnamed\tthumb. You\tcan\tcopy\tyour\texperimental\taddEventListener\tcode\tfrom\tthe\tconsole\tand\tpaste it\tinto\tthe\tbody\tof\taddThumbClickHandler.\tModify\tit\tso\tthat\tyou\tare\tcalling thumb.addEventListener.\tFor\tnow,\tyou\twill\tonly\tneed\tthe\tcall\tto event.preventDefault\tin\tthe\tevent\tcallback. ... function\tsetDetailsFromThumb(thumbnail)\t{ \t\t... } function\taddThumbClickHandler(thumb) \t\t'use\tstrict'; \t\tthumb.addEventListener('click',\tfunction\t(event)\t{ \t\t\t\tevent.preventDefault(); \t\t}); } Inside\tthe\tevent\tcallback,\tyou\thave\taccess\tto\tthe\tthumb\tparameter\tdeclared\tas\tpart\tof addThumbClickHandler.\tPass\tit\tto\ta\tcall\tto\tsetDetailsFromThumb. ... function\taddThumbClickHandler(thumb)\t{ \t\t'use\tstrict'; \t\tthumb.addEventListener('click',\tfunction\t(event)\t{ \t\t\t\tevent.preventDefault(); \t\t\t\tsetDetailsFromThumb(thumb); \t\t}); } JavaScript,\tlike\tmany\tother\tprogramming\tlanguages,\thas\trules\tabout\tdefining\tand accessing\tvariables\tand\tfunctions.\tThe\tanonymous\tfunction\tyou\tpassed\tto addEventListener\tis\table\tto\taccess\tthe\tsetDetailsFromThumb\tfunction because\tsetDetailsFromThumb\twas\tdeclared\tin\tthe\tglobal\tscope.\tThis\tmeans\tthat\tit can\tbe\taccessed\tfrom\tany\tother\tfunction\tor\tfrom\tthe\tconsole.\tThe\tsame\tis\ttrue\tfor variables\tlike\tDETAIL_IMAGE_SELECTOR,\twhich\tis\talso\tdeclared\tin\tthe\tglobal\tscope. However,\tthe\tvariables\tdetailImage\tand\tdetailTitle,\twhich\tyou\tdeclared\tinside setDetails,\tare\tonly\tavailable\twithin\tthe\tbody\tof\tsetDetails.\tYou\tcannot\taccess them\tfrom\tthe\tconsole\tor\tfrom\tother\tfunctions.\tThese\tvariables\tare\tdeclared\tin\tthe function\tscope\t(or\tlocal\tscope)\tof\tsetDetails.\tA\tfunction\u2019s\tparameters\twork\tvery much\tlike\tvariables\tdeclared\tinside\ta\tfunction.\tThey\ttoo\tare\tpart\tof\tthat\tfunction\u2019s\tscope. Normally,\tfunctions\tcannot\taccess\tvariables\tor\tparameters\tthat\tare\tpart\tof\tanother function\u2019s\tscope.\taddThumbClickHandler\tis\tinteresting\tbecause\tit\tdefines\tthe parameter\tthumb,\twhich\tis\taccessed\tby\tanother\tfunction\t\u2013\tthe\tcallback\tfunction\tyou passed\tto\taddEventListener.\tThis\tis\tpossible\tbecause\tthe\tcallback\tfunction\tis\tpart\tof addThumbClickHandler\u2019s\tscope. You\tcan\tread\tmore\tabout\thow\tall\tof\tthis\tworks\tin\ta\tFor\tthe\tMore\tCurious\tsection\tat\tthe end\tof\tthis\tchapter.","Accessing\tAll\tthe\tThumbnails In\tthe\tconsole,\tyou\tadded\tan\tevent\tlistener\tfor\tthe\tfirst\tthumbnail.\tNow\tyou\twill\tadd\tan event\tlistener\tfor\tall\tof\tthe\tthumbnails,\tusing\ta\tnew\tDOM\tmethod. When\tyou\tretrieved\tthe\tdetail\timage\tand\tthe\tdetail\ttitle,\tyou\tused\tthe document.querySelector\tmethod\tto\tsearch\tthe\tDOM\tfor\tan\telement\tthat\tmatched the\tselector\tpassed\tin.\tdocument.querySelector\twill\tonly\treturn\ta\tsingle\tvalue, even\tif\tyou\tpass\tin\ta\tselector\tthat\tmatches\tmultiple\telements. The\tdocument.querySelectorAll\tmethod,\ton\tthe\tother\thand,\twill\treturn\ta\tlist\tof all\tmatching\telements.\tCall\tdocument.querySelectorAll(THUMBNAIL_LINK_SELECTOR)\tin the\tconsole\tand\texamine\tthe\tresults.\tYou\tshould\tsee\tthe\tlist\tof\tanchor\telement\tresults (Figure\t6.26). Figure\t6.26\t\tdocument.querySelectorAll\treturns\tmultiple\tmatching elements Knowing\tthis,\tyou\tcan\ttest\tsetDetailsFromThumb\tproperly.\tIn\tthe\tconsole,\tassign the\tresult\tof\tcalling\tdocument.querySelectorAll(THUMBNAIL_LINK_SELECTOR)\tto\ta variable\tnamed\tthumbnails.\tUse\tbracket\tsyntax\tto\tretrieve\tthe\tfifth\telement\tfrom\tthe thumbnails\tlist,\tpassing\tit\tto\tsetDetailsFromThumb.\tBracket\tsyntax\tlets\tyou\tspecify an\titem\tin\tthe\tlist\tby\tits\tnumerical\tindex.\tThe\tindex\tstarts\tat\t0,\tso\tthe\tfifth\titem\tis\tat\tindex 4. Here\tis\tyour\tcode\tfor\tthe\tconsole: var\tthumbnails\t=\tdocument.querySelectorAll(THUMBNAIL_LINK_SELECTOR); setDetailsFromThumb(thumbnails[4]); After\trunning\tthis\tin\tthe\tconsole,\tyou\tcan\tsee\tthat\tan\titem\tfrom\tthe\tthumbnails\tlist\tcan\tbe passed\tto\tsetDetailsFromThumb,\tsuccessfully\tupdating\tthe\tdetail\timage\tand\ttitle (Figure\t6.27).","Figure\t6.27\t\tPassing\tan\titem\tfrom\tquerySelectorAll\tto setDetailsFromThumb In\tmain.js,\tadd\ta\tfunction\tnamed\tgetThumbnailsArray\tand\tpaste\tin\tthe\tcode\tthat retrieves\tall\tmatching\telements\tfor\tTHUMBNAIL_LINK_SELECTOR\tand\tassigns\tthe\tresult\tto\ta thumbnails\tvariable. ... function\taddThumbClickHandler(thumb)\t{ \t\t... } function\tgetThumbnailsArray()\t{ \t\t'use\tstrict'; \t\tvar\tthumbnails\t=\tdocument.querySelectorAll(THUMBNAIL_LINK_SELECTOR); } Before\tyou\tgo\tany\tfurther,\tthere\tis\ta\tsmall\t\u201cgotcha\u201d\twhen\tworking\twith\tDOM\tmethods. Methods\tthat\treturn\tlists\tof\telements\tdo\tnot\treturn\tarrays.\tInstead,\tthey\treturn\tNodeLists. Both\tarrays\tand\tNodeLists\tare\tlists\tof\titems,\tbut\tarrays\thave\ta\tnumber\tof\tpowerful methods\tfor\tworking\twith\tcollections\tof\titems,\tsome\tof\twhich\tyou\twill\twant\tfor Ottergram. You\twill\tneed\tto\tconvert\tthe\tNodeList\treturned\tfrom\tquerySelectorAll\tto\tan\tarray using\tan\todd-looking\tbit\tof\tJavaScript.\tDo\tnot\tworry\tabout\tthis\tsyntax\tright\tnow.\tIt\tis\ta backward-compatible\tway\tto\tconvert\tfrom\ta\tNodeList\tto\tan\tarray.\tMake\tthis\tchange\tin main.js: ... function\tgetThumbnailsArray()\t{ \t\t'use\tstrict'; \t\tvar\tthumbnails\t=\tdocument.querySelectorAll(THUMBNAIL_LINK_SELECTOR); \t\tvar\tthumbnailArray\t=\t[].slice.call(thumbnails); \t\treturn\tthumbnailArray; } Now,\tarmed\twith\tall\tof\tthe\totter\tthumbnails,\tyou\tcan\tconnect\tthem\tto\tyour\tevent\tlistening code,\twhich\twill\tchange\tthe\tdetail\timage\tand\ttitle\tin\tresponse\tto\ta\tclick.","Iterating\tThrough\tthe\tArray\tof\tThumbnails Connecting\tthe\tthumbnails\tto\tyour\tevent\thandling\tcode\twill\tbe\tshort\tand\tsweet.\tYou\twill write\ta\tfunction\tthat\twill\tbe\tthe\tstarting\tpoint\tfor\tall\tof\tOttergram\u2019s\tlogic.\tOther programming\tlanguages\thave\ta\tbuilt-in\tmechanism\tfor\tstarting\tan\tapplication,\twhich JavaScript\tlacks.\tBut\tnot\tto\tworry\t\u2013\tit\tis\teasy\tenough\tto\timplement\tby\thand. Begin\tby\tadding\tan\tinitializeEvents\tfunction\tat\tthe\tend\tof\tmain.js.\tThis method\twill\ttie\ttogether\tall\tof\tthe\tsteps\tfor\tmaking\tOttergram\tinteractive.\tFirst,\tit\twill\tget the\tarray\tof\tthumbnails.\tThen,\tit\twill\titerate\tover\tthe\tarray,\tadding\tthe\tclick\thandler\tto each\tone.\tAfter\tyou\thave\twritten\tthe\tfunction,\tyou\twill\tadd\ta\tcall\tto initializeEvents\tat\tthe\tvery\tend\tof\tmain.js\tto\trun\tit. In\tthe\tbody\tof\tyour\tnew\tfunction,\tadd\ta\tcall\tto\tgetThumbnailsArray\tand\tassign\tthe result\t(the\tarray\tof\tthumbnails)\tto\ta\tvariable\tnamed\tthumbnails. ... function\tgetThumbnailsArray()\t{ \t\t... } function\tinitializeEvents()\t{ \t\t'use\tstrict'; \t\tvar\tthumbnails\t=\tgetThumbnailsArray(); } Next,\tyou\tneed\tto\tgo\tthrough\tthe\tarray\tof\tthumbnails,\tone\titem\tat\ta\ttime.\tAs\tyou\tvisit\teach one,\tyou\twill\tcall\taddThumbClickHandler\tand\tpass\tthe\tthumbnail\telement\tto\tit.\tThat may\tseem\tlike\tseveral\tsteps,\tbut\tbecause\tthumbnails\tis\ta\tproper\tarray,\tyou\tcan\tdo\tall\tof this\twith\ta\tsingle\tmethod\tcall. Add\ta\tcall\tto\tthe\tthumbnails.forEach\tmethod\tin\tmain.js\tand\tpass\tit\tthe addThumbClickHandler\tfunction\tas\ta\tcallback. ... function\tinitializeEvents()\t{ \t\t'use\tstrict'; \t\tvar\tthumbnails\t=\tgetThumbnailsArray(); \t\tthumbnails.forEach(addThumbClickHandler); } Note\tthat\tyou\tare\tpassing\ta\tnamed\tfunction\tas\ta\tcallback.\tAs\tyou\twill\tread\tlater,\tthis\tis\tnot always\ta\tgood\tchoice.\tHowever,\tin\tthis\tcase\tit\tworks\twell,\tbecause addThumbClickHandler\tonly\tneeds\tinformation\tthat\twill\tbe\tpassed\tto\tit\twhen forEach\tcalls\tit\t\u2013\tan\titem\tfrom\tthe\tthumbnails\tarray. Finally,\tto\tsee\teverything\tin\taction,\tadd\ta\tcall\tto\tinitializeEvents\tat\tthe\tvery\tend\tof main.js. ... function\tinitializeEvents()\t{ \t\t'use\tstrict'; \t\tvar\tthumbnails\t=\tgetThumbnailsArray(); \t\tthumbnails.forEach(addThumbClickHandler); } initializeEvents(); Remember,\tas\tthe\tbrowser\treads\tthrough\teach\tline\tof\tyour\tJavaScript\tcode,\tit\truns\tthe code.\tFor\tmost\tof\tmain.js,\tit\tis\tonly\trunning\tvariable\tand\tfunction\tdeclarations.\tBut when\tit\treaches\tthe\tline\tinitializeEvents();,\tit\twill\trun\tthat\tfunction.","Save\tand\treturn\tto\tthe\tbrowser.\tClick\ta\tfew\tdifferent\tthumbnails\tand\tsee\tthe\tfruits\tof\tyour labor\t(Figure\t6.28). Figure\t6.28\t\tYou\tshould\tindeed\tbe\tdancing Sit\tback,\trelax,\tand\tenjoy\tclicking\tsome\totters!\tThere\twas\ta\tlot\tto\twork\tthrough\tand absorb\twhile\tbuilding\tyour\tsite\u2019s\tinteractive\tlayer.\tIn\tthe\tnext\tchapter\tyou\twill\tfinish Ottergram\tby\tadding\tvisual\teffects\tfor\textra\tpop.","Silver\tChallenge:\tLink\tHijack The\tChrome\tDevTools\tgive\tyou\ta\tlot\tof\tpower\tfor\ttoying\twith\tpages\tthat\tyou\tvisit.\tThis next\tchallenge\tis\tto\tchange\tall\tof\tthe\tlinks\ton\ta\tsearch\tresults\tpage\tso\tthat\tthey\tdo\tnot\tgo anywhere. Go\tto\tyour\tfavorite\tsearch\tengine\tand\tsearch\tfor\t\u201cotters.\u201d\tOpen\tthe\tDevTools\tto\tthe console.\tWith\tthe\tfunctions\tyou\twrote\tin\tOttergram\tas\ta\treference,\tattach\tevent\tlisteners\tto all\tof\tthe\tlinks\tand\tdisable\ttheir\tdefault\tclick\tfunctionality.","Gold\tChallenge:\tRandom\tOtters Write\ta\tfunction\tthat\tchanges\tthe\tdata-image-url\tof\ta\trandom\totter\tthumbnail\tso\tthat\tthe detail\timage\tno\tlonger\tmatches\tthe\tthumbnail.\tUse\tthe\tURL\tof\tan\timage\tof\tyour\tchoosing (though\ta\tweb\tsearch\tfor\t\u201ctacocat\u201d\tshould\tprovide\ta\tgood\tone). For\tan\textra\tchallenge,\twrite\ta\tfunction\tthat\tresets\tyour\totter\tthumbnails\tto\ttheir\toriginal data-image-url\tvalues\tand\tchanges\tanother\tone\tat\trandom.","For\tthe\tMore\tCurious:\tStrict\tMode What\tis\tstrict\tmode,\tand\twhy\tdoes\tit\texist?\tIt\twas\tcreated\tas\ta\tcleaner\tmode\tof\tJavaScript, catching\tcertain\tkinds\tof\tcoding\tmistakes\t(like\ttypos\tin\tvariable\tnames),\tsteering developers\taway\tfrom\tsome\terror-prone\tparts\tof\tthe\tlanguage,\tand\tdisabling\tsome language\tfeatures\tthat\tare\tjust\tplain\tbad. Strict\tmode\tprovides\ta\tnumber\tof\tbenefits.\tIt: enforces\tthe\tuse\tof\tthe\tvar\tkeyword does\tnot\trequire\twith\tstatements places\trestrictions\ton\tthe\tway\tthe\teval\tfunction\tcan\tbe\tused treats\tduplicate\tnames\tin\ta\tfunction\u2019s\tparameters\tas\ta\tsyntax\terror All\tthis\tjust\tfor\tadding\tthe\t'use\tstrict'\tdirective\tto\tthe\ttop\tof\ta\tfunction.\tAs\ta\tbonus,\tthe 'use\tstrict'\tdirective\tis\tignored\tby\tolder\tbrowsers\tthat\tdo\tnot\tsupport\tit.\t(These browsers\tsimply\tsee\tthe\tdirective\tas\ta\tstring.) You\tcan\tread\tmore\tabout\tstrict\tmode\ton\tthe\tMDN\tat\tdeveloper.mozilla.org\/\u200ben- US\/d\u200b ocs\/W\u200b eb\/\u200bJavaScript\/\u200bReference\/S\u200b trict_mode.","For\tthe\tMore\tCurious:\tClosures Earlier\twe\tmentioned\tthat\tdevelopers\toften\tprefer\tto\tuse\tanonymous\tfunctions\tas callbacks\tinstead\tof\tnamed\tfunctions.\taddThumbClickHandler\tillustrates\twhy\tan anonymous\tfunction\tis\ta\tbetter\tsolution. Let\u2019s\tsay\tyou\ttried\tto\tuse\ta\tnamed\tfunction,\tclickFunction,\tfor\tthe\tcallback.\tInside\tof that\tfunction,\tyou\thave\taccess\tto\tthe\tevent\tobject\tbecause\tit\twill\tbe\tpassed\tin\tby addEventListener.\tBut\tthe\tbody\tof\tclickFunction\thas\tno\taccess\tto\tthe\tthumb object.\tThat\tparameter\tis\tonly\taccessible\tinside\tthe\taddThumbClickHandler function. function\tclickFunction\t(event)\t{ \t\tevent.preventDefault(); \t\tsetDetailsFromThumb(thumb);\t\/\/\t<---\tThis\twill\tcause\tan\terror } function\taddThumbClickHandler(thumb)\t{ \t\tthumb.addEventListener('click',\tclickFunction); } On\tthe\tother\thand,\tusing\tan\tanonymous\tfunction\tdoes\tgive\tit\taccess\tto\tthe\tthumb parameter,\tbecause\tit\tis\talso\tinside\tof\taddThumbClickHandler.\tWhen\ta\tfunction\tis defined\tinside\tof\tanother\tfunction,\tit\tcan\tuse\tany\tof\tthe\tvariables\tand\tparameters\tof\tthis outer\tfunction.\tIn\tcomputer\tscience\tterms,\tthis\tis\tknown\tas\ta\tclosure. When\tthe\taddThumbClickHandler\tfunction\truns,\tit\tcalls\taddEventListener, which\tassociates\tthe\tcallback\tfunction\twith\tthe\tclick\tevent.\tThe\tbrowser\tkeeps\ttrack\tof these\tassociations,\tinternally\tholding\ta\treference\tto\tthe\tcallback\tfunction\tand\trunning\tthe callback\twhen\tthe\tevent\toccurs. Technically,\twhen\tthe\tcallback\tis\teventually\texecuted,\tthe\tvariables\tand\tparameters\tof addThumbClickHandler\tno\tlonger\texist.\tThey\twent\taway\twhen addThumbClickHandler\tfinished\trunning.\tBut,\tthe\tcallback\t\u201ccaptures\u201d\tthe\tvalues\tof addThumbClickHandler\u2019s\tvariables\tand\tparameters.\tThe\tcallback\tuses\tthese captured\tvalues\twhen\tit\truns. For\ta\tdeeper\tdive,\tread\tup\ton\tclosures\tin\tthe\tMDN.","For\tthe\tMore\tCurious:\tNodeLists\tand HTMLCollections There\tare\ttwo\tways\tto\tretrieve\tlists\tof\telements\tthat\tlive\tin\tthe\tDOM.\tThe\tfirst\tone\tis document.querySelectorAll,\twhich\treturns\ta\tNodeList.\tThe\tother\tis document.getElementsByTagName,\twhich\tdiffers\tfrom document.querySelectorAll\tin\tthat\tyou\tcan\tonly\tpass\tit\ta\tstring\twith\ta\ttag\tname, like\t\\\"div\\\"\tor\t\\\"a\\\",\tand\talso\tin\tthat\tit\treturns\tan\tHTMLCollection. Neither\tNodeLists\tnor\tHTMLCollections\tare\ttrue\tarrays,\tso\tthey\tlack\tarray\tmethods\tsuch as\tforEach,\tbut\tthey\tdo\thave\tsome\tvery\tinteresting\tproperties. HTMLCollections\tare\tlive\tnodes.\tThis\tmeans\tthat\twhen\tchanges\tare\tmade\tto\tthe\tDOM, the\tcontents\tof\tan\tHTMLCollection\tcan\tchange\twithout\tyou\thaving\tto\tcall document.getElementsByTagName\tagain. To\tsee\thow\tthis\tworks,\ttry\tthe\tfollowing\tin\tthe\tconsole. var\tthumbnails\t=\tdocument.getElementsByTagName(\\\"a\\\"); thumbnails.length; After\tgetting\tall\tof\tthe\tanchor\telements\tas\tan\tHTMLCollection,\tyou\tprint\tthe\tlength\tof that\tlist\tto\tthe\tconsole. Now,\tremove\tsome\tof\tthe\tanchor\ttags\tfrom\tthe\tpage\tusing\tthe\telements\tpanel\tin\tthe DevTools:\tControl-click\t(right-click)\tone\tof\tthe\tlist\titems\tand\tchoose\tDelete\telement (Figure\t6.29).","Figure\t6.29\t\tDeleting\ta\tDOM\telement\twith\tthe\tDevTools Do\tthis\tseveral\ttimes,\tthen\tenter\tthumbnails.length\tinto\tthe\tconsole\tagain.\tYou\tshould see\tthat\tthe\tlength\tis\tdifferent\t(Figure\t6.30). Figure\t6.30\t\tThe\tlength\tvalue\tchanges\tafter\tdeleting\telements","Converting\tNodeLists\tand\tHTMLCollections\tto\tarrays\tnot\tonly\tmakes\tthem\tmore convenient\tto\twork\twith\tvia\tarray\tmethods,\tbut\tyou\talso\thave\tthe\tguarantee\tthat\tthe\titems in\tthe\tarray\twill\tnot\tchange,\teven\tif\tthe\tDOM\tis\tmodified.","For\tthe\tMore\tCurious:\tJavaScript\tTypes Throughout\tthe\tchapter,\tyou\tcreated\tvariables\tso\tyou\tcould\trefer\tto\tsome\tdata\tinside\tyour functions.\tEarly\ton,\twe\ttold\tyou\tthat\tstrings,\tnumbers,\tand\tBooleans\tare\tthree\tof\tthe\tfive primitive\tdata\ttypes.\tThe\tother\ttwo\ttypes\tare\tnull\tand\tundefined. Table\t6.2\tsummarizes\tthe\tproperties\tof\tthe\tfive\tprimitive\ttypes. Table\t6.2\t\tPrimitive\tdata\ttypes\tin\tJavaScript Type Example Description string \u201cAnd\tyou\tget\t$100!\tAnd\tyou Letters,\tnumbers,\tor\tsymbols\tenclosed\tin get\t$100!\tAnd\u2026!\u201d matching\tquotation\tmarks. number 42,\t3.14159,\t-1 Whole\tnumbers\tand\tdecimals. Boolean true,\tfalse The\tkeywords\ttrue\tand\tfalse, corresponding\tto\tlogical\ttrue\tand\tfalse. null null The\tvalue\tthat\tdenotes\tan\tinvalid\tvalue. undefined undefined The\tvalue\tof\ta\tvariable\tthat\thas\tnot\tbeen assigned\tto\tanything. All\tother\ttypes\tin\tJavaScript\tare\tconsidered\tcompound\ttypes\tor\tcomplex\ttypes.\tThese include\tarrays\tand\tobjects,\twhich\tcan\thave\tother\ttypes\tinside\tof\tthem.\tFor\texample,\tyou wrote\ta\tfunction\tthat\tproduced\tan\tarray\tof\tthumbnail\tobjects.\tArrays\talso\thave\tproperties (like\tlength)\tand\tmethods\t(such\tas\tforEach). You\twill\tcontinue\tto\twork\twith\tprimitive\tand\tcomplex\tdata\ttypes\tthroughout\tthis\tbook.","7\t Visual\tEffects\twith\tCSS In\tthe\tlast\tchapter,\tyou\tgave\tOttergram\tthe\tability\tto\trespond\tto\tuser\tinteraction\tby changing\tthe\tdetail\timage\twhen\tthe\tuser\tclicks\ta\tthumbnail.\tYou\twill\tbuild\ton\tthat\tin\tthis chapter\tby\tadding\tthree\tdifferent\tvisual\teffects\tto\tOttergram. The\tfirst\teffect\tis\ta\tsimple\tlayout\tchange\tthat\tinvolves\thiding\tthe\tdetail\timage\tand\tletting the\tthumbnails\ttake\tup\tthe\twidth\tof\tthe\tpage.\tWhen\tthe\tuser\tclicks\ta\tthumbnail,\tyou\twill make\tthe\tdetail\timage\treappear\tand\treturn\tthe\tthumbnails\tto\ttheir\tprevious\tsize. The\tother\ttwo\teffects\twill\tuse\tCSS\tto\tcreate\tvisual\tanimations\tfor\tthe\tthumbnails\tand\tthe detail\timage\t(Figure\t7.1). Figure\t7.1\t\tOttergram\twith\ttransition\teffects Hiding\tand\tShowing\tthe\tDetail\tImage Ottergram\u2019s\tusers\tmay\twant\tto\tbe\table\tto\tscroll\tthrough\tthe\tthumbnails\twithout\tthe\tdetail image\tbeing\ton\tthe\tpage\t(Figure\t7.2).","Figure\t7.2\t\tDetail\timage\tvisible\tand\thidden To\tmake\tthis\thappen,\tyou\tneed\tto\tbe\table\tto\tapply\tstyles\tto\tyour\t.thumbnail-list\tand .detail-image-container\tbased\ton\ta\tcondition\tthat\twill\tturn\ton\tand\toff\tas\tthe\twebsite\tis in\tuse.\tYou\tcould\tdo\tthis\tby\tcreating\tnew\tclass\tselectors,\tlike\t.thumbnail-list-no- detail\tand\t.hidden-detail-image-container,\tand\tadd\tthose\tclasses\tto\tthe\ttarget elements\twith\tJavaScript.\tThe\ttrouble\twith\tthis\tapproach\tis\tthat\tit\twould\tbe\tinefficient. The\tevent\tthat\twill\tcause\tthe\tdetail\timage\tto\thide\twill\tsimultaneously\tcause\tthe\tthumbnail list\tto\treposition\titself.\tIt\tis\ta\tsingle\tevent.\tAdding\tclasses\tto\tyour\t<ul>\tand\t<div> elements\tseparately\tdoes\tnot\treflect\tthis. A\tbetter\tapproach\tis\tto\tuse\tJavaScript\tto\tadd\ta\tsingle\tclass\tselector\tthat\taffects\tthe\tlayout as\ta\twhole.\tThen,\tyou\tcan\ttarget\tthe\t.thumbnail-list\tand\t.detail-image-container when\tthey\tare\tdescendents\tof\tthe\tnew\tselector. You\tare\tgoing\tto\tdynamically\tadd\ta\tclass\tname\tto\tthe\t<body>\telement\tto\thide\tthe\tdetail image\tand\tenlarge\tthe\tthumbnails,\tand\tthen\tdynamically\tremove\tthe\tclass\tname\tto\treturn to\tyour\tcurrent\tstyles\t(Figure\t7.3).","Figure\t7.3\t\tRestyling\tdescendants\twith\tclass\tchange\tto\tancestor This\ttechnique\tis\tsimilar\tin\ttwo\tways\tto\tthe\tone\tyou\tused\twith\tthe\tmedia\tqueries. First,\tit\tinvolves\tstyles\tthat\tare\tactivated\twhen\tan\tancestor\tmeets\ta\tparticular\tcondition. With\tmedia\tqueries,\tthat\tancestor\tis\tthe\tviewport\tand\tthe\tcondition\tis\ta\tminimum\twidth. In\tthis\tnew\tcode,\tthe\tancestor\twill\tbe\tany\telement\tyou\tselect\tthat\tthe\ttarget\telements share,\tand\tthe\tcondition\twill\tbe\tthat\tthe\tancestor\thas\ta\tparticular\tclass\tname. The\tsecond\tsimilarity\tis\tthat\tyou\tmust\tplace\tthe\tconditional\tstyles\tafter\tthe\tother declarations\tfor\tthe\taffected\telements\tin\tyour\tstylesheet\tbecause\tthese\tconditional\tstyles need\tto\toverride\tthe\tprevious\tdeclarations\twhen\tthey\tare\tactive. You\twill\tproceed\tin\tthree\tsteps: 1.\t In\tyour\tCSS,\tdefine\tthe\tstyles\tthat\tcreate\tthe\tvisual\teffect\tyou\tare\ttrying\tto\tget. Also,\ttest\tyour\tstyles\tin\tthe\tDevTools. 2.\t Write\tJavaScript\tfunctions\tto\tadd\tand\tremove\ta\tclass\tname\tfor\tthe\t<body> element. 3.\t Add\tan\tevent\tlistener\tto\ttrigger\tyour\tJavaScript\tfunction. Creating\tstyles\tto\thide\tthe\tdetail\timage To\thide\tthe\t.detail-image-container,\tyou\twill\tadd\ta\tdeclaration\tthat\tsets\tdisplay: none\tfor\tthis\telement.\tdisplay:\tnone\ttells\tthe\tbrowser\tthat\tthe\telement\tshould\tnot\tbe rendered. The\tclass\tyou\twill\tbe\tadding\tdynamically\tto\tthe\t<body>\twill\tbe\tcalled\thidden-detail. Therefore,\tyou\tonly\twant\tto\tapply\tdisplay:\tnone\tto\t.detail-image-container\twhen\tit is\ta\tdescendent\tof\t.hidden-detail. Add\tthe\tstyle\tto\thide\tthe\tdetail\timage\tin\tstyles.css: ...",".detail-image-title\t{ \t\t... } .hidden-detail\t.detail-image-container\t{ \t\tdisplay:\tnone; } @media\tall\tand\t(min-width:\t768px)\t{ \t\t... } Now,\tgive\tsome\tthought\tto\twhat\tyour\t.thumbnail-list\twill\tlook\tlike.\tBased\ton\tthe current\tstyles,\tit\twill\tbe\ta\tcolumn\talong\tthe\tleft\tside\tof\twider\tscreens\tand\ta\thorizontal\trow at\tthe\ttop\tof\tnarrower\tscreens.\tA\tcentered\tcolumn\twould\tbe\tbetter\twhen\tthe\tdetail\timage\tis hidden,\tregardless\tof\tthe\tscreen\tsize. Add\tstyles\tto\tthe\t.thumbnail-list\tand\t.thumbnail-item\tin\tstyles.css\twhen\tthey are\tdescendents\tof\t.hidden-detail. ... .hidden-detail\t.detail-image-container\t{ \t\tdisplay:\tnone; } .hidden-detail\t.thumbnail-list\t{ \t\tflex-direction:\tcolumn; \t\talign-items:\tcenter; } .hidden-detail\t.thumbnail-item\t{ \t\tmax-width:\t80%; } @media\tall\tand\t(min-width:\t768px)\t{ \t\t... } Now,\tthe\t.thumbnail-list\twill\talways\tbe\tdisplayed\tas\ta\tcolumn\twhile\tthe\t.detail- image-container\tis\thidden. You\thave\talso\tadded\ta\tdeclaration\tsetting\tthe\twidth\tof\tthe\t.thumbnail-item\telements\tto max-width:\t80%\twhen\tthe\tdetail\timage\tis\thidden.\tThis\toverrides\tthe\tmax-width\tstyles\tset elsewhere\tfor\tthe\t.thumbnail-items\tso\tthat\tthey\twill\tbecome\tthe\tfocus\tof\tthe\tpage. When\tthe\t.detail-image-container,\t.thumbnail-list,\tand\t.thumbnail-item\telements are\tnested\tanywhere\tinside\tof\tan\telement\twith\tthe\tclass\thidden-detail,\tthese\tnew\tstyles will\tbe\tactivated. Note\tthat\tyou\tadded\tthese\tbefore\tyour\tmedia\tqueries.\tAs\tyou\talready\tknow,\tthe\torder\tof your\tCSS\tcode\tmatters,\twith\tstyles\tthat\tappear\tlater\tin\tthe\tfile\toverriding\tthose\tthat\tcame before.\tIn\tgeneral,\tfor\tthe\tsame\tselector,\tthe\tbrowser\tuses\tthe\tstyles\tit\thas\tseen\tmost recently.\tIn\tthis\tcase,\thowever,\tyour\tnew\tstyles\tuse\tselectors\tthat\tare\tmore\tspecific\tthan the\tones\tthat\tappear\tin\tyour\tmedia\tqueries,\tand\tspecificity\ttrumps\trecency. Generally,\tit\tis\tbest\tto\tkeep\tyour\tmedia\tqueries\tat\tthe\tend\tof\tthe\tfile.\tYour\tmedia\tqueries will\tusually\treuse\tthe\tsame\tselectors\tfrom\texisting\tstyles,\tso\tputting\tthem\tat\tthe\tend makes\tsure\tthat\tyour\tmedia\tqueries\toverwrite\tthose\texisting\tstyles.\tAlso,\tit\tmakes\tyour media\tqueries\teasier\tto\tlocate,\tbecause\tthey\tare\talways\tat\tthe\tend\tof\tthe\tfile. Save\tyour\tfile.\tBefore\tyou\twrite\tthe\tJavaScript\tthat\tdepends\ton\tthe\tstyles\tyou\thave\tadded, it\tis\twise\tto\ttest\tthem.\tStart\tbrowser-sync\t(using\tbrowser-sync\tstart\t--server\t-- browser\t\\\"Google\tChrome\\\"\t--files\t\\\"*.html,\tstylesheets\/*.css,\tscripts\/*.js\\\") and\topen\tthe\tDevTools.\tIn\tthe\telements\tpanel,\tControl-click\t(right-click)\tthe\t<body> element\tand\tchoose\tAdd\tAttribute\tfrom\tthe\tmenu\tthat\tappears\t(Figure\t7.4).","Figure\t7.4\t\tChoosing\tthe\tAdd\tAttribute\tmenu\titem The\tDevTools\tprovides\ta\tspace\tfor\tyou\tto\tstart\ttyping\tinside\tthe\t<body>\ttag.\tEnter class=\\\"hidden-detail\\\"\tand\tpress\tReturn\t(Figure\t7.5). Figure\t7.5\t\tAdding\tthe\thidden-detail\tclass\tattribute After\tyou\tadd\tthe\thidden-detail\tclass\tto\tthe\t<body>\tin\tthe\tDevTools,\tthe\tdetail\timage disappears\tand\tthe\tthumbnails\tbecome\tmuch\tlarger\t\u2013\tjust\tas\tyou\tintended\t(Figure\t7.6).","Figure\t7.6\t\tLayout\tchange\tafter\tapplying\thidden-detail\tclass Writing\tthe\tJavaScript\tto\thide\tthe\tdetail\timage Next,\tyou\twill\twrite\tthe\tJavaScript\tthat\twill\ttoggle\tthe\t.hidden-detail\tclass\tfor\tthe <body>\telement. In\tmain.js,\tadd\ta\tvariable\tnamed\tHIDDEN_DETAIL_CLASS. var\tDETAIL_IMAGE_SELECTOR\t=\t'[data-image-role=\\\"target\\\"]'; var\tDETAIL_TITLE_SELECTOR\t=\t'[data-image-role=\\\"title\\\"]'; var\tTHUMBNAIL_LINK_SELECTOR\t=\t'[data-image-role=\\\"trigger\\\"]'; var\tHIDDEN_DETAIL_CLASS\t=\t'hidden-detail'; ... Now,\twrite\ta\tnew\tfunction\tin\tmain.js\tnamed\thideDetails.\tIts\tjob\tis\tto\tadd\ta\tclass name\tto\tthe\t<body>\telement.\tYou\twill\tuse\tthe\tclassList.add\tDOM\tmethod\tto manipulate\tthe\tclass\tname. ... function\tgetThumbnailsArray()\t{ \t\t... } function\thideDetails()\t{ \t\t'use\tstrict'; \t\tdocument.body.classList.add(HIDDEN_DETAIL_CLASS); } function\tinitializeEvents()\t{ \t\t... } ... You\taccessed\tthe\t<body>\telement\tusing\tthe\tdocument.body\tproperty.\tThis\tDOM\telement corresponds\tto\tthe\t<body>\ttag\tin\tyour\tmarkup.\tLike\tall\tDOM\telements,\tit\tgives\tyou\ta convenient\tway\tto\tmanipulate\tits\tclass\tnames. You\talso\tcalled\tthe\tadd\tmethod\ton\tdocument.body\tto\tadd\tthe\thidden-detail\tclass\tto\tthe <body>. Listening\tfor\tthe\tkeypress\tevent","Now\tyou\tneed\ta\tway\tto\ttrigger\tthe\tdetail\timage\tto\thide.\tAs\tbefore,\tyou\twill\tuse\tan\tevent listener,\tbut\tthis\ttime\tyour\tevent\tlistener\twill\tlisten\tfor\ta\tkeypress\tinstead\tof\ta\tclick. We\tuse\tthe\tterm\t\u201ckeypress\u201d\tgenerally\tto\tmean\tpressing\tand\treleasing\ta\tkey,\tbut\tthat simple\tprocess\tactually\ttriggers\tmultiple\tevents.\tWhen\tthe\tkey\tis\tfirst\tdepressed,\tthe keydown\tevent\tis\tsent.\tIf\tit\tis\ta\tcharacter\tkey\t(as\topposed\tto\ta\tmodifier\tkey\tlike\tShift)\tthen the\tkeypress\tevent\tis\talso\tsent.\tWhen\tthe\tkey\tis\treleased,\tthe\tkeyup\tevent\tis\tsent. For\tOttergram,\tthese\tdifferences\tare\tminimal.\tYou\tare\tgoing\tto\tuse\tthe\tkeyup\tevent. In\tmain.js,\tadd\ta\tfunction\tnamed\taddKeyPressHandler\tthat\tcalls document.body.addEventListener,\tpassing\tit\tthe\tstring\t'keyup'\tand\tan anonymous\tfunction\tthat\tdeclares\ta\tparameter\tnamed\tevent.\tInside\tthe\tbody\tof\tthis anonymous\tfunction,\tmake\tsure\tto\tpreventDefault\tfor\tthe\tevent,\tand\tthen console.log\tthe\tevent\u2019s\tkeyCode. ... function\thideDetails()\t{ \t\t... } function\taddKeyPressHandler()\t{ \t\t'use\tstrict'; \t\tdocument.body.addEventListener('keyup',\tfunction\t(event)\t{ \t\t\t\tevent.preventDefault(); \t\t\t\tconsole.log(event.keyCode); \t\t}); } function\tinitializeEvents()\t{ \t\t... } ... All\tof\tthe\tkeypress\tevents\thave\ta\tproperty\tcalled\tkeyCode\tthat\tcorresponds\tto\tthe\tkey that\ttriggered\tthe\tevent.\tThe\tkeyCode\tis\tan\tinteger,\tlike\t13\tfor\tReturn,\t32\tfor\tthe\tspace bar,\tand\t38\tfor\tthe\tup\tarrow. Update\tthe\tinitializeEvents\tfunction\tin\tmain.js\tso\tthat\tit\tcalls addKeyPressHandler.\tYou\tneed\tto\tdo\tthis\tso\tthat\tthe\t<body>\telement\tcan\tlisten\tfor keyboard\tevents\twhen\tthe\tpage\tloads. ... function\tinitializeEvents()\t{ \t\t'use\tstrict'; \t\tvar\tthumbnails\t=\tgetThumbnailsArray(); \t\tthumbnails.forEach(addThumbClickHandler); \t\taddKeyPressHandler(); } initializeEvents(); Save\tand\tswitch\tback\tto\tthe\tbrowser.\tMake\tsure\tthe\tconsole\tis\tvisible,\tthen\tclick\ton\tthe page\tto\tmake\tsure\tthat\tthe\tfocus\tis\tnot\ton\tthe\tDevTools\t\u2013\totherwise,\tthe\tevent\tlistener\twill not\tbe\ttriggered.\tNow\tpress\tsome\tkeys\ton\tyour\tkeyboard.\tYou\twill\tsee\tnumbers\tprinted\tto the\tconsole\t(Figure\t7.7).","Figure\t7.7\t\tLogging\tthe\tkeyCode\tto\tthe\tconsole You\twant\tto\thide\tthe\tdetail\timage\twhen\tthe\tEsc\tkey\tis\tpressed,\tnot\tjust\tany\tkey.\tIf\tyou press\tthe\tEsc\tkey,\tyou\twill\tsee\tthat\tthe\tcorresponding\tevent.keyCode\tvalue\tis\t27.\tYou will\tuse\tthat\tto\tmake\tyour\tevent\tlistener\tmore\tspecific. Add\ta\tvariable\tto\tthe\ttop\tof\tmain.js\tfor\tthe\tEsc\tkey\u2019s\tvalue. var\tDETAIL_IMAGE_SELECTOR\t=\t'[data-image-role=\\\"target\\\"]'; var\tDETAIL_TITLE_SELECTOR\t=\t'[data-image-role=\\\"title\\\"]'; var\tTHUMBNAIL_LINK_SELECTOR\t=\t'[data-image-role=\\\"trigger\\\"]'; var\tHIDDEN_DETAIL_CLASS\t=\t'hidden-detail'; var\tESC_KEY\t=\t27; ... Now,\tupdate\tyour\tkeyup\tevent\tlistener\tto\tcall\thideDetails\twhen\tthe\tvalue\tof event.keyCode\tmatches\tthe\tvalue\tof\tESC_KEY. ... function\taddKeyPressHandler()\t{ \t\t'use\tstrict'; \t\tdocument.body.addEventListener('keyup',\tfunction\t(event)\t{ \t\t\t\tevent.preventDefault(); \t\t\t\tconsole.log(event.keyCode); \t\t\t\tif\t(event.keyCode\t===\tESC_KEY)\t{ \t\t\t\t\t\thideDetails(); \t\t\t\t} \t\t}); } ... You\tused\tthe\tstrict\tequality\toperator\t(===)\tto\tcompare\tthe\tvalues\tof\tevent.keyCode and\tESC_KEY.\tWhen\tthese\tvalue\tare\tthe\tsame,\tyou\tcall\thideDetails.","You\tcould\thave\tused\tthe\tloose\tequality\toperator\t(==)\tto\tcompare\tthe\tvalues\tinstead,\tbut\tit is\tusually\tbest\tto\tuse\tthe\tstrict\tequality\toperator.\tThe\tmajor\tdifference\tbetween\tthe equality\toperators\tis\tthat\tthe\tloose\tequality\toperator\twill\tautomatically\tconvert\tfrom\tone type\tof\tvalue\tto\tanother.\tThe\tstrict\tequality\toperator\twill\tnot\tdo\tthe\tconversion.\tWith\tstrict equality,\tif\tthe\ttypes\tare\tnot\tthe\tsame,\tthen\tthe\tresult\tof\tthe\tcomparison\tis\talways\tfalse. Many\tfront-end\tdevelopers\trefer\tto\tthis\tautomatic\ttype\tconversion\tas\ttype\tcoercion.\tIt\tis performed\twhen\tvalues\tneed\tto\tbe\tcompared\t(when\tusing\tan\tequality\toperator),\tadded together\t(in\tthe\tcase\tof\tnumbers),\tor\tconcatenated\t(as\twith\tstrings). Because\tof\tthis\tautomatic\tconversion,\tthere\tis\tno\tsyntax\terror\tif\tyou\ttry\tto\tadd\tthe\tstring \\\"27\\\"\twith\tthe\tnumber\t42\t\u2013\tthough\tthe\tresult\tmight\tnot\tbe\twhat\tyou\texpect\t(Figure\t7.8). Figure\t7.8\t\tJavaScript\twill\tautomatically\tconvert\tbetween\ttypes This\tis\tvery\timportant\twhen\tworking\twith\tuser-provided\tdata,\twhich\tyou\twill\tdo\tin Chapter\t10. Save\tmain.js\tand\ttest\tyour\tnew\tfunctionality\tin\tthe\tbrowser\t(Figure\t7.9). Figure\t7.9\t\tPoof!\tPressing\tEsc\thides\tthe\tdetail\timage\tand\ttitle","Showing\tthe\tdetail\timage\tagain There\tis\tone\tsmall\tbut\timportant\tpiece\tto\tadd:\tmaking\tthe\tdetail\timage\tvisible\tagain.\tThis will\tbe\ttriggered\twhen\ta\tthumbnail\tis\tclicked. You\tused\tclassList.add\tto\tadd\ta\tclass\tname\tto\tthe\t<body>\telement.\tYou\twill\tuse classList.remove\tto\tremove\tthat\tclass\tname\twhen\ta\tthumbnail\tis\tclicked.\tAdd\ta new\tfunction\tnamed\tshowDetails\tto\tmain.js. ... function\thideDetails()\t{ \t\t... } function\tshowDetails()\t{ \t\t'use\tstrict'; \t\tdocument.body.classList.remove(HIDDEN_DETAIL_CLASS); } function\taddKeyPressHandler()\t{ \t\t... } ... Now\tadd\ta\tcall\tto\tshowDetails\tin\tyour\taddThumbClickHandler\tfunction\t\u2013\tno need\tto\tadd\ta\tnew\tevent\tlistener. ... function\taddThumbClickHandler(thumb)\t{ \t\t'use\tstrict'; \t\tthumb.addEventListener('click',\tfunction\t(event)\t{ \t\t\t\tevent.preventDefault(); \t\t\t\tsetDetailsFromThumb(thumb); \t\t\t\tshowDetails(); \t\t}); } ... Save\tmain.js\tand\tswitch\tto\tyour\tbrowser.\tTry\tout\tyour\tnew\tfunctionality:\tHide\tthe detail\timage,\tthen\tclick\ton\ta\tthumbnail\tto\tbring\tit\tback\t(Figure\t7.10).\tThe\totters\tlook\tlike they\tapprove,\tdon\u2019t\tthey? Figure\t7.10\t\tEsc\thides\tdetails;\tclick\tshows\tdetails Now,\tOttergram\tcan\tdynamically\tadapt\tits\tlayout\tbased\ton\tthe\tviewport,\tusing\tmedia queries,\tas\twell\tas\tin\tresponse\tto\tuser\tinput. At\tthe\tmoment,\tthe\tlayout\tchanges\thappen\tabruptly.\tIn\tthe\tnext\tsection,\tyou\twill\tsmooth","that\tout\tusing\tCSS\ttransitions.","State\tChanges\twith\tCSS\tTransitions CSS\ttransitions\tcreate\ta\tgradual\tchange\tfrom\tone\tvisual\tstate\tto\tanother,\twhich\tis\tjust what\tyou\tneed\tto\tmake\tOttergram\u2019s\tshow\/hide\teffect\tmore\tpolished. When\tyou\tcreate\ta\tCSS\ttransition,\tyou\tare\ttelling\tthe\tbrowser,\t\u201cI\twould\tlike\tthis\telement\u2019s styles\tto\tchange\tto\tthese\tnew\tproperties,\tand\tI\twould\tlike\tfor\tthat\tchange\tto\ttake\texactly\tas long\tas\tI\ttell\tyou.\u201d One\tcommon\texample\tis\tthe\tfly-out\tmenu\tseen\ton\tmany\tsites,\tsuch\tas\tthe\tsmall-screen version\tof\tbignerdranch.com.\tIn\ta\tbrowser\twith\ta\tnarrow\tviewport,\tclicking\tthe menu\ticon\tmakes\tthe\tnavigation\tmenu\tappear\tfrom\tthe\ttop\t\u2013\tbut\tit\tdoes\tnot\tappear\tall\tat once.\tInstead,\tit\tslides\tdown\tfrom\tthe\theader,\tvisually\tanimating\tfrom\tthe\tinitial\tstate (hidden)\tto\tthe\tend\tstate\t(visible)\t(Figure\t7.11).\tClicking\tthe\tmenu\ticon\tagain\tcauses\tthe navigation\tmenu\tto\tslide\tback\tup\tuntil\tit\tis\thidden\tagain. Figure\t7.11\t\tFly-out\tnavigation\ton\tbignerdranch.com Before\tyou\tcreate\tthe\ttransition\teffect\tfor\tshowing\tand\thiding\tthe\tdetail\timage,\tyou\twill build\ta\tsimpler\ttransition\tfor\tyour\tthumbnails. In\tgeneral,\tyou\tshould\tcreate\ttransitions\tin\tthree\tsteps: 1.\t Decide\twhat\tthe\tend\tstate\tshould\tbe.\tOne\tgood\tapproach\tis\tto\tadd\tthe\tCSS declarations\tfor\tthe\tend\tstate\tto\tthe\ttarget\telement.\tThis\tallows\tyou\tto\tsee\tthem\tin the\tbrowser\tand\tmake\tsure\tthat\tthey\tlook\tthe\tway\tyou\tintend. 2.\t Move\tthe\tdeclarations\tfrom\tthe\ttarget\telement\u2019s\texisting\tdeclaration\tblock\tto\ta new\tCSS\tdeclaration\tblock.\tYou\tmay\twant\tto\tuse\ta\tnew\tclass\tfor\tthe\tselector\tfor the\tnew\tblock. 3.\t Add\ta\ttransition\tdeclaration\tto\tthe\ttarget\telement.\tThe\ttransition\tproperty tells\tthe\tbrowser\tthat\tit\twill\tneed\tto\tvisually\tanimate\tthe\tchanges\tfrom\tthe\tcurrent CSS\tvalues\tto\tthe\tend-state\tCSS\tvalues\tand\tthat\tthe\ttransition\tshould\ttake\tplace over\ta\tspecific\tperiod\tof\ttime.","Working\twith\tthe\ttransform\tproperty Your\tfirst\ttransition\twill\tincrease\tthe\tsize\tof\ta\tthumbnail\twhen\tyou\thover\tover\tit\twith\tthe cursor\t(Figure\t7.12).\tHowever,\tyou\twill\tnot\tdirectly\tchange\tthe\twidth\tor\theight\tstyles. You\twill\tuse\tthe\ttransform\tproperty,\twhich\tcan\talter\tthe\tshape,\tsize,\trotation,\tand\tlocation of\tan\telement\twithout\tinterrupting\tthe\tflow\tof\tthe\telements\taround\tit. Figure\t7.12\t\tA\tthumbnail\twith\tzoom\teffect The\ttarget\telement\tfor\tthis\ttransition\tis\tthe\t.thumbnail-item.\tYou\twill\tbegin\tby\tadding\ta transform\tdeclaration\tdirectly\tto\tthe\t.thumbnail-item\telement. After\tyou\thave\ttested\tit\tand\tdetermined\tthat\tit\tis\tworking\tthe\tway\tyou\twant,\tyou\twill move\tthe\ttransformation\tto\ta\tnew\t.thumbnail-item:hover\tdeclaration\tblock.\tFinally,\tyou will\tadd\ta\ttransition\tdeclaration\tto\t.thumbnail-item. In\tstyles.css,\tbegin\tby\tadding\ta\ttransform\tdeclaration\tto\t.thumbnail-item. ... .thumbnail-item\t{ \t\tdisplay:\tinline-block; \t\tmin-width:\t120px; \t\tmax-width:\t120px; \t\tborder:\t1px\tsolid\trgb(100%,\t100%,\t100%); \t\tborder:\t1px\tsolid\trgba(100%,\t100%,\t100%,\t0.8); \t\ttransform:\tscale(2.2); } ... transform:\tscale(2.2)\ttells\tthe\tbrowser\tthat\tthe\telement\tshould\tbe\tdrawn\tat\t220%\tof\tits original\tsize.\tThere\tare\tmany\tvalues\tthat\tcan\tbe\tused\twith\ttransform,\tincluding\tadvanced 3D\teffects.\tThe\tMDN\thas\tgood\tcoverage\tof\tthem\tat\tdeveloper.mozilla.org\/e\u200b n- US\/d\u200b ocs\/W\u200b eb\/C\u200b SS\/t\u200b ransform. Save\tand\tview\tthe\tchanges\tin\tyour\tbrowser\t(Figure\t7.13).","Figure\t7.13\t\tDramatically\tlarge\totter\tthumbnails You\tcan\tsee\tthat\tthe\tthumbnails\tare\tnow\tmuch\tlarger\tthan\tbefore.\tIn\tfact,\tthey\tare\ttoo large.\tChange\tthe\tvalue\tso\tthat\tthey\tare\tonly\ta\tlittle\tbit\tlarger: ... .thumbnail-item\t{ \t\tdisplay:\tinline-block; \t\tmin-width:\t120px; \t\tmax-width:\t120px; \t\tborder:\t1px\tsolid\trgb(100%,\t100%,\t100%); \t\tborder:\t1px\tsolid\trgba(100%,\t100%,\t100%,\t0.8); \t\ttransform:\tscale(2.2); \t\ttransform:\tscale(1.2); } ... After\tyou\tsave,\tyou\tshould\tsee\tthat\tthe\totter\tthumbnails\tare\tonly\tslightly\tlarger\tthan\ttheir original\tsize\t(Figure\t7.14). Figure\t7.14\t\tReasonably\tlarge\totter\tthumbnails This\tscale\tfor\tthe\tthumbnails\tlooks\tgood,\tso\tyou\tcan\tmove\ton\tto\tthe\tnext\tstep. Adding\ta\tCSS\ttransition Now\tit\tis\ttime\tto\tmove\tthe\tend-state\tstyle\tto\ta\tnew\tstyle\tdeclaration\tand\tset\tup\tthe transition\tfor\tthe\t.thumbnail-item\telement. When\tthe\tuser\thovers\tthe\tmouse\tcursor\tover\ta\tthumbnail,\tthat\tthumbnail\tshould\tincrease its\tscale\tby\t120%.\tAdd\ta\tdeclaration\tblock\tto\tstyles.css\tthat\tuses\tthe\tmodifier",":hover\tto\tdesignate\tstyles\tthat\tshould\tonly\tbe\tapplied\twhen\tthe\tuser\thovers\tover\tthe element. ... .thumbnail-item\t{ \t\tdisplay:\tinline-block; \t\tmin-width:\t120px; \t\tmax-width:\t120px; \t\tborder:\t1px\tsolid\trgb(100%,\t100%,\t100%); \t\tborder:\t1px\tsolid\trgba(100%,\t100%,\t100%,\t0.8); \t\ttransform:\tscale(1.2); } .thumbnail-item:hover\t{ \t\ttransform:\tscale(1.2); } ... The\tproper\tname\tfor\tthis\tmodifier\tis\tpseudo-class.\tThe\tpsuedo-class\t:hover\tmatches\tan element\twhen\tthe\tuser\tholds\tthe\tmouse\tcursor\tover\tit.\tThere\tare\ta\tnumber\tof\tpseudo-class keywords\tthat\tdescribe\tthe\tvarious\tstates\tan\telement\tcan\tbe\tin.\tYou\twill\tencounter\tsome when\tyou\twork\twith\tforms\tlater\tin\tthis\tbook,\tand\tyou\tcan\tsearch\tthe\tMDN\tto\tlearn\tmore. Next,\tmake\tthis\tchange\thappen\tas\ta\ttransition\tby\tadding\ta\ttransition\tdeclaration\tto .thumbnail-item\tin\tstyles.css.\tYou\tneed\tto\tspecify\tthe\tproperty\tto\tanimate\tand\thow long\tthe\tanimation\tshould\ttake. ... .thumbnail-item\t{ \t\tdisplay:\tinline-block; \t\tmin-width:\t120px; \t\tmax-width:\t120px; \t\tborder:\t1px\tsolid\trgb(100%,\t100%,\t100%); \t\tborder:\t1px\tsolid\trgba(100%,\t100%,\t100%,\t0.8); \t\ttransition:\ttransform\t133ms; } .thumbnail-item:hover\t{ \t\ttransform:\tscale(1.2); } ... You\tset\ta\ttransition\tfor\tthe\ttransform\tproperty.\tThis\ttells\tthe\tbrowser\tthat\tit\twill\tneed to\tanimate\tthe\tchange,\tbut\tonly\tfor\tthe\ttransform\tproperty.\tYou\talso\tspecified\tthat\tthe transition\tshould\ttake\tplace\tover\ta\tperiod\tof\t133\tmilliseconds. Save\tand\tgive\tyour\tnew\ttransition\ta\ttry.\tYou\tshould\tsee\tthat\teach\tthumbnail\tenlarges\twhen you\thover\tover\tit.\tWhen\tyou\tmove\tyour\tmouse\taway,\tthe\ttransition\truns\tin\treverse,\tand the\tthumbnail\treturns\tto\tits\toriginal\tsize\t(Figure\t7.15).","Figure\t7.15\t\tTransition\toccurs\twhen\thovering,\treverses\ton\tmouse\tout The\tDevTools\tgive\tyou\ta\thandy\tway\tto\ttest\tpseudo-class\tstates.\tGo\tto\tthe\telements\tpanel and\texpand\tthe\ttags\tuntil\tone\tof\tthe\t<li>\ttags\tis\tdisplayed.\tClick\tthe\ttag\tso\tthat\tit\tis highlighted\tand\tyou\twill\tsee\tan\tellipsis\tto\tthe\tleft.\tClick\tthe\tellipsis,\tand\tin\tthe\tcontextual menu\tthat\tis\trevealed\tchoose\t:hover\tfrom\tthe\tlist\tof\tpseudo-classes\t(Figure\t7.16). Figure\t7.16\t\tToggling\ta\tpseudo-class\tin\tthe\telements\tpanel An\torange\tcircle\tappears\tto\tthe\tleft\tof\tthe\t<li>\ttag\tin\tthe\telements\tpanel,\ttelling\tyou\tthat one\tof\tthe\tpseudo-classes\thas\tbeen\tactivated\tvia\tthe\tDevTools.\tThe\tcorresponding thumbnail\twill\tremain\tin\tthe\t:hover\tstate,\teven\tif\tyou\tmouse\tover\tit\tand\tthen\tmouse\taway from\tit. Open\tthe\tcontextual\tmenu\tagain,\tby\tclicking\tthe\torange\tcircle,\tand\tdisable\tthe\t:hover"]


Like this book? You can publish your book online for free in a few minutes!
Create your own flipbook