《JavaScript DOM 编程艺术》10:应用最佳实践

这是《JavaScript学徒》系列的第十课,今天会进入《JavaScript DOM 编程艺术》第6章,将上一章的最佳实践应用到图片库例子中。

本文同步发表于我的个人网站:

《JavaScript DOM 编程艺术》10:应用最佳实践 - 程式学徒 ZackLive​zacklive.com

教学视频连结

YouTube

B站

优酷

能否平穏退化?

  • Ballon
  • 以这段程式为例,href中我们不使用JavaScript伪协议(javascript:)或者#号,就是为了即使JavaScript不可用,程式仍能打开图片。

    JavaScript是否与HTML标记分离?

    在上面那段程式中,onclick的部分便是JavaScript,它跟HTML混在一起了。这是可以改进的地方。

    首先,将onclick从各连结移除,并为ul加入id = imagegallery。再加入以下函数:

    function prepareGallery() {  if (!document.getElementsByTagName ||      !document.getElementById ||      !document.getElementById("imagegallery")) return false;  var gallery = document.getElementById("imagegallery");  var links = gallery.getElementsByTagName("a");  for ( var i=0; i

    这个函数先检查我们要用的方法,再透过刚加入的id取得图片库中所有连结,最后为每一条连结绑定onclick事件,并赋与它一个函数来执行showPic及返回false。

    prepareGallery函数要在网页载入后马上执行,可以使用之前提到的window.onload,但我们可能有多个需要在载入后马上执行的函数,因此,我们需要以下函数:

    function addLoadEvent(func) {  var oldonload = window.onload;  if (typeof window.onload != 'function') {    window.onload = func;  } else {    window.onload = function() {      oldonload();      func();    }  }}

    这个函数先将旧的window.onload存到一个变量oldonload中,接著判断旧window.onload是否已经是函数,如果不是,代表里面没有任何函数,可以将新函数func直接赋与;如果是,则代表里面存在其他函数,那就将旧函数oldonload和新函数func一起放到一个新的函数里再赋与window.onload。

    我们可以重复使用这个函数,将多个函数放入window.onload:

    addLoadEvent(prepareGallery);

    至此,我们成功将JavaScript和HTML分离。

    最后,我们也应为showPic函数加上检查:

    function showPic(whichpic) {  if (!document.getElementById("placeholder")) return false;  var source = whichpic.getAttribute("href");  var placeholder = document.getElementById("placeholder");  placeholder.setAttribute("src", source);  var text = whichpic.getAttribute("title");  if (description = document.getElementById("description")) description.firstChild.nodeValue = text;  return true;}

    在第二个if的条件当中,我直接进行赋值,这是因为对if来讲,赋值的结果正是被赋值的值。

    至于最后为什么要返回true,这是要告诉prepareGallery,showPic没发生任何错误。前面的prepareGallery,不管showPic是否成功都会返回false,也就是取消连结的跳转动作。这样,万一showPic出错,连结就会失效,不能平稳退化。因此,onclick的函数应改为:

    return !showPic(this);

    这代表showPic成功(showPic返回true),我们应取消连结跳转,即prepareGallery要返回false,与showPic相反;反之,若showPic出错并返回false,prepareGallery则应返回true,让连结进行跳转。

    三元操作符(ternary operator)

    showPic当中还可以加入更多的检查:

    var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : "";

    这里的问号和冒号组成三元操作符,意思是,若问号前的条件成立,取冒号前的值;若不成立,则取冒号后的值。这里便是,若存在title属性,则取该属性为text的值;若不存在,则取空字符串为text的值。

    检查placeholder是否为图片:

    if (placeholder.nodeName != "IMG") return false;

    nodeName属性永远是大写字母。

    这此检查可按个人喜好加入。

    键盘事件

    按下键盘上任一个出键都会触发onkeypress事件,如果我们也想让用户按下键盘任意键来显示图片,可以加入:

    links[i].onclick = function() {  return !showPic(this);}links[i].onkeypress = links[i].onclick;

    但onkeypress会使所有键失去原本的功能,如Tab键,不再能够跳到下一个元素;同时,onclick其实也会被回车键触发,因此,如非必要,不应使用onkeypress。

    加入CSS

    在index.html的head中加入:

    <link rel="stylesheet" href="style.css">

    接着新增style.css,并加入:

    body {  color: #333;  background-color: #ccc;  margin: 1em 10%;}h1 {  color: #333;  background-color: transparent;}a {  color: #c60;  background-color: transparent;  font-weight: bold;  text-decoration: none;}ul {  padding: 0;}li {  float: left;  padding: 1em;  list-style: none;}#imagegallery {  list-style: none;}#imagegallery li {  display: inline;}#imagegallery li a img {  border: 0;}

    DOM Core和HTML-DOM

    DOM Core:任何程式语言都可以使用,不限JavaScript或网页,方法包括

    getElementById

    getElementsByTagName

    getAttribute

    setAttribute

    HTML-DOM:只适用于web文档,较简短:

    DOM Core写法:

    element.getAttribute("src")placeholder.setAttribute("src", source);

    HTMl-DOM写法:

    element.srcplaceholder.src = source

    建议使用DOM Core方法,JavaScript目前已不只用于网页范筹,习惯同一种写法比较有利。

    ©著作权归作者所有,转载或内容合作请联系作者
    • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
      沈念sama阅读 211,123评论 6 490
    • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
      沈念sama阅读 90,031评论 2 384
    • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
      开封第一讲书人阅读 156,723评论 0 345
    • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
      开封第一讲书人阅读 56,357评论 1 283
    • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
      茶点故事阅读 65,412评论 5 384
    • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
      开封第一讲书人阅读 49,760评论 1 289
    • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
      沈念sama阅读 38,904评论 3 405
    • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
      开封第一讲书人阅读 37,672评论 0 266
    • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
      沈念sama阅读 44,118评论 1 303
    • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
      茶点故事阅读 36,456评论 2 325
    • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
      茶点故事阅读 38,599评论 1 340
    • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
      沈念sama阅读 34,264评论 4 328
    • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
      茶点故事阅读 39,857评论 3 312
    • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
      开封第一讲书人阅读 30,731评论 0 21
    • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
      开封第一讲书人阅读 31,956评论 1 264
    • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
      沈念sama阅读 46,286评论 2 360
    • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
      茶点故事阅读 43,465评论 2 348

    推荐阅读更多精彩内容