一、它支持平稳退化吗

<li><a href="images/fireworks.jpg" onclick="showPic(this); return false;" title="A fireworks display">Fireworks</a>
</li>

可以发现,在没有javascript的情况下,浏览器会沿着href属性给出的链接前进,虽然用户体验比用javascript的效果要逊色,但网页的基本功能未受到损害。即,它支持平稳退化。

二、它的javascript与HTML标签是分离的吗

<li><a href="images/fireworks.jpg" onclick="showPic(this); return false;" title="A fireworks display">Fireworks</a>
</li>

很明显,onclick事件处理函数是直接插入到HTML中的,因此不是分离的。理想情况下,应该是在外部文件里完成加添onclick事件处理函数的工作。

首先需要把js代码移动HTML,但需要把js代码与HTML标签关联起来,可以分别给每个图片添加同一个class属性,但过于复杂。我们可以发现图片链接都包含在ul元素里,因此值需要给ul元素设置一个id。

     <ul id="imagegallery"> <li><a href="#" title="A fireworks display">Fireworks</a></li><li><a href="images/coffee.jpg" title="A cup of coffee">Coffee</a></li><li><a href="images/rose.jpg" title="A red rose">Rose</a></li><li><a href="images/bigben.jpg" title="The famous clock">Big Ben</a></li></ul>

1.添加事件处理函数
需要编写一个函数关联到onclick事件上。
【函数任务】

  • 检查当前浏览器是否理解getElemenTagName
  • 检查当前浏览器是否理解getElementsByTagName
  • 检查当前页面是否存在一个id为imagegallery的元素
  • 遍历imagegalley元素中所有的链接
  • 设置onclick事件,让它有相关链接被点击时完成以下事件:把这个链接作为参数传递给showPic函数,并且取消链接被点击时的默认行为。

(1)检查点
首先,需要检查浏览器是否理解getElementsByTagName和getElementById的方法,此外,还需要检查是否存在id等于imagegalley的元素,如果不存在这个元素,那么函数将无需执行。

if(!document.getElementsByTagName) return false;
if(!document.getElementById) return false;
if(!document.getElementById("imagegallery")) return false;

(2)变量里有什么
使用变量gallery来保存图片库。
使用变量links来保存图片库的a标签

var gallery = document.getElementById("imagegallery");
var links = gallery.getElementsByTagName("a");

(3)遍历
接着,需要遍历处理links数组中的各个元素,可以使用for循环来完成。

for(var i=0;i<links.length;i++){}

(4)改变行为
接下来,需要完成的操作是改变links数组中各个元素的行为。首先定义了一个匿名函数,它把links[i]元素的onclick事件处理函数指定为这个匿名函数,这个匿名函数的所有操作将在links[i]元素对应的链接被点击时执行。
传递给showPic函数的参数是this,this代表links[i],表示此时与onclick方法关联的那个元素。此外还需要禁用有关链接的默认行为。

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

(5)完成javascript函数

for(var i=0;i<links.length;i++){links[i].onclick = function(){showPic(this);return false;}
}

2.共享onload事件
我们必须执行prepareGallery函数才能对onclick事件进行绑定,如果立即执行这个函数,它将无法工作,因为在HTML文档加载之前执行脚本DOM是不完整的。

应该让这个函数在网页加载完毕之后执行,网页加载完成之后会触发一个onload事件,我们需要把prepareGallery函数绑定在这个事件上。

window.onload = prepareGallery;

假设需要绑定两个函数,如果把它们逐一绑定到onload事件上,只有最后一个才被实际执行。

有一种解决方案:先创建一个匿名函数来容纳这两个函数,然后把这个匿名函数绑定到onload事件上。

window.onload = function(){firstFunction();secondFunction();
}

还有一个最佳解决方案:编写额外的代码,即addLoadEvent函数,它有一个参数,打算在页面加载完毕时执行的函数名。
【该函数要完成的操作】

  • 把现有的winow.onloa事件处理函数的值存入变量oldload
  • 如果在这个处理函数上没有绑定函数,就把新函数添加给它
  • 如果在这个处理函数上已经绑定函数,就把新函数追加到现有指令的末尾。
function addLoadEvent(func){var oldonload = window.onload;if (typeof window.onload != 'function'){window.onload = func;}else {window.onload = function(){oldonload();func();}}
}

如果需要把prepareGallery与onlad事件绑定,只需要一行代码。

addLoadEvent(prepareGallery);

三、不要做太多的假设
showPic函数负责完成两件事:一是找出id属性值为placeholder的图片并修改其src属性;二是找出id是description的元素并修改其第一个子元素的nodeValue属性。
第一件事实这个函数必须完成的任务,第二件事只是补充。因此,决定把检查工作分成两个步骤:主要placeholder图片存在,即使description元素不存在,切换新图片的操作也照常进行。

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

改进后的showPic函数不在假设HTML文档里肯定有placeholder图片和description元素,即使文档里没有placeholder图片,也不会发生错误。

可是还有一个问题:如果把placeholder图片删除,那么将会出现,无论点击imagegalley清单里的哪个链接,都不会产生任何反应。这意味着脚本不能实现平稳退化。

问题在于prepareGallery函数做出了一个假设:showPic函数肯定正常返回,因此该函数取消了onclick事件的默认行为。

实际上,是否要返回false以取消onclick事件的默认行为,应该有showPic函数决定:如果图片切换成功,返回true,如果不成功,返回false。

因此,应该在返回前验证showPic函数的返回值,以便决定是否阻止默认行为

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

现在,如果showPic返回true,我们就返回false,浏览器就不会打开默认链接;如果showPic返回false,我们就认为图片没有更新,于是返回true以让默认行为发生。

四、优化

每个链接都有一个title属性,为检查其是否存在:

if (whichpic.getAttribute("title")){var text = whichpic.getAttribute("title");
}else{var text = "";
}

检查placeholder元素是否存在,切为一张图片,可以使用nodeName属性来检查:

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

注意:nodeName属性总是返回一个大写字母的值,即使元素在HTML文档中是小写的。

检查description元素的第一个子元素是否为一个文本节点:

if (description.firstChild.nodeType == 3){description.firstChild.nodeValue = text;}

在增加了几项测试之后,showPic函数的代码变得更多了。在实际工作中, 需要自己决定是否需要这些检查。理想情况下,脚本不应该对HTML文档的结构和内容有太多假设

五、键盘访问
prepareGallery函数的核心代码是:

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

当这个链接被点击时,showPic函数开始执行。
但用户还可以使用键盘来操作,有个onkeypress的事件处理函数,它是专门用来处理键盘事件的,按下键盘的任意键都会触发该事件。

为了让onkeypress事件与onclick事件触发同样的行为,可以把onclick事件的所有功能付给onkeypress。

links[i].onkeypress = links[i].onclick;

小心使用onkeypress:
使用这个事件处理函数很容易出问题,用户每按下一个按键都会触发它。绑定在onkeypress事件上的处理函数上返回的是false,那些只是用键盘访问的用户将永远无法离开当前链接
然而,使用Tab键移动到某个链接然后按下回车键的动作也会触发onclick事件,因为这里不只采用onclick事件处理函数。

六、DOM Core 和HTML-DOM

至此,在编写javascript代码时用到了以下几个DOM方法:
getElementById、getElementsByTagName、getAttribute、setAttribute
这些方法都是DOM Core的组成部分,支持DOM的任何一种程序设计语言都可以使用它们。

在使用javascript语言和DOM为HTML文件编写脚本时,还有许多属性可供选择。

HTML-DOM提供了一个forms对象。

document.getElementsTagName("forms")
可以简化为:document.forms

HTML-DOM还提供了许多描述HTML元素的属性,如src

element.getAttribute("src")
可以简化为:element.src

这些方法和属性可以相互替换,同样的操作可以使用DOM Core和HTML-DOM来实现。通常HTML-DOM会更加简短,但它们只能用来处理Web文档。

完整代码:
html:

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><title>Image Gallery</title><link rel="stylesheet" href="styles/layout.css" media="screen" /></head><body><h1>Snapshots</h1><ul id="imagegallery"><li><a href="images/fireworks.jpg" title="A fireworks display">Fireworks <img src="data:images/small_fireworks.jpg" alt= "Fireworks" /></a>  </li><li><a href="images/coffee.jpg" title="A cup of coffee">Coffee<img src="data:images/small_coffee.jpg" alt = "coffee" /></a></li><li><a href="images/rose.jpg" title="A red rose">Rose<img src="data:images/small_rose.jpg" alt = "rose" /></a></li><li><a href="images/bigben.jpg" title="The famous clock">Big Ben<img src="data:images/small_bigben.jpg" alt = "bigben" /></a></li></ul><img id="placeholder" src="data:images/peng.jpg" alt="my peng" /><p id="description" >Choose an image.</p><script type="text/javascript" src="scripts/myjs.js"></script></body>
</html>

外部javascript:

function addLoadEvent(func){var oldonload = window.onload;if (typeof window.onload != 'function'){window.onload = func;}else {window.onload = function(){oldonload();func();}}
}function prepareGallery(){if(!document.getElementsByTagName) return false;if(!document.getElementById) return false;if(!document.getElementById("imagegallery")) return false;var gallery = document.getElementById("imagegallery");var links = gallery.getElementsByTagName("a");for(var i=0;i<links.length;i++){links[i].onclick = function(){return !showPic(this);}}
}function showPic(whichpic){if (!document.getElementById("placeholder")) return false;var source = whichpic.getAttribute("href");var placeholder = document.getElementById("placeholder");if (placeholder.nodeName != "IMG") return false;placeholder.setAttribute("src",source);if (document.getElementById("description")){var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : "";var description = document.getElementById("description");if (description.firstChild.nodeType == 3){description.firstChild.nodeValue = text;}}return true;
}addLoadEvent(prepareGallery);

【javascript】JS+DOM实现图片库(改进版)相关推荐

  1. js语法+dom+js图片库+最佳实践+图片库改进版

    [2]js语法 [2.2.4]数据类型 类型1)字符串 var mood = 'happy'; var moood = "happy"; 类型2)数值: var age = 33. ...

  2. 深入理解JavaScript系列(23):JavaScript与DOM(上)——也适用于新手

    文档对象模型Document Object Model DOM(Document Object Model,文档对象模型)是一个通过和JavaScript进行内容交互的API. Javascript和 ...

  3. Javascript中DOM技术的的简单学习

    第十四课 DOM技术概述 1:DOM概述 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构 ...

  4. java创建node类型数据类型_[Java教程]js DOM Node类型

    [Java教程]js DOM Node类型 0 2015-12-18 16:00:08 DOM(文档对象模型)是针对HTML和 DOM可以将任何HTML或 以下面为例: My article Hell ...

  5. Javascript操作DOM常用API总结

    文本整理了javascript操作DOM的一些常用的api,根据其作用整理成为创建,修改,查询等多种类型的api,主要用于复习基础知识,加深对原生js的认识. 基本概念 在讲解操作DOM的api之前, ...

  6. JavaScript与DOM编程

    文章目录 JavaScript JS简介 常量与变量 数组 创建数组 访问数组:通过指定数组名以及索引号,可以访问某个特定的元素 对象 1.系统所提供对象 2.自定义对象 访问对象 函数 第一种 第二 ...

  7. 【repost】Javascript操作DOM常用API总结

    Javascript操作DOM常用API总结 文本整理了javascript操作DOM的一些常用的api,根据其作用整理成为创建,修改,查询等多种类型的api,主要用于复习基础知识,加深对原生js的认 ...

  8. JavaScript中DOM操作

    Web前端基础修炼 HTML基本标签详解与运行截图 CSS基本操作详解及截图演示 JavaScript基础(ECMAScript) JavaScript中DOM操作 JavaScript中BOM操作 ...

  9. 【JavaScript】DOM 操作元素样式和元素类名

    文章目录 [JavaScript]DOM 操作元素样式和元素类名 一. 操作元素样式 (1)操作行内元素 1. 获取元素的样式 2. 设置元素的样式 (2) 操作非行内元素和行内元素 1. 获取元素的 ...

最新文章

  1. 【2020 Fall】哥伦比亚大学最新《机器学习》课程
  2. linux 进程 ctrl-c,ctrl-z,ctrl-d
  3. Linux下编译vtk的java版本,Ubuntu 16.04 编译VTK7.1
  4. lvs负载均衡—高可用集群(keepalived)
  5. html 只能输入正数,vue 限制input只能输入正数
  6. 网页loading效果 可以通过js控制旋转速度
  7. 6. 同步化器(Synchronizers)
  8. 从单张图重建三维人体模型综述(五)
  9. 云平台仿真框架cloudsim介绍
  10. oracle 物化视图 on demand,oracle物化视图的两个典型应用场景
  11. Android 9.0中sdcard 的权限和挂载问题
  12. CAN 错误帧和原理
  13. [译] 我无法想象没有 Git 别名的的场景
  14. 软件工程——自我介绍
  15. 计算机科学 中文核心,什么是最快的计算机科学中文核心期刊?
  16. APIX_身份证图像识别技术(附代码)
  17. 初中地理历史计算机教师资格证,初中地理教师资格证好考吗
  18. ssh隧道原理及三种隧道转发模式
  19. 面向接口编程,接口是什么,有什么作用?
  20. 2023年云计算的发展趋势如何?还值得学习就业吗?

热门文章

  1. Android自定义控件——模拟抛体加速减速效果
  2. matlab水汽计算公式,[转载]matlab 解方程组
  3. jquery ui table
  4. 好奇那些进了大厂的程序员面试前都做了哪些准备?Android大厂面试官全套教程教你:这样准备面试顺利拿到offer
  5. Android蓝牙手柄摇杆 十字按键监听手机focus焦点
  6. 【MyBatis动态SQL批量修改数据出现报错问题】
  7. 快手主播怎么引流?直播带货将面向多样化发展
  8. 云测 Testing 兼职众测平台题目及答案
  9. 不谋全局者不足以谋一域,不谋万世者不足以谋一时
  10. 转自猎豹移动CEO傅盛:深度学习是什么?