【javascript】JS+DOM实现图片库(改进版)
一、它支持平稳退化吗
<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实现图片库(改进版)相关推荐
- js语法+dom+js图片库+最佳实践+图片库改进版
[2]js语法 [2.2.4]数据类型 类型1)字符串 var mood = 'happy'; var moood = "happy"; 类型2)数值: var age = 33. ...
- 深入理解JavaScript系列(23):JavaScript与DOM(上)——也适用于新手
文档对象模型Document Object Model DOM(Document Object Model,文档对象模型)是一个通过和JavaScript进行内容交互的API. Javascript和 ...
- Javascript中DOM技术的的简单学习
第十四课 DOM技术概述 1:DOM概述 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构 ...
- java创建node类型数据类型_[Java教程]js DOM Node类型
[Java教程]js DOM Node类型 0 2015-12-18 16:00:08 DOM(文档对象模型)是针对HTML和 DOM可以将任何HTML或 以下面为例: My article Hell ...
- Javascript操作DOM常用API总结
文本整理了javascript操作DOM的一些常用的api,根据其作用整理成为创建,修改,查询等多种类型的api,主要用于复习基础知识,加深对原生js的认识. 基本概念 在讲解操作DOM的api之前, ...
- JavaScript与DOM编程
文章目录 JavaScript JS简介 常量与变量 数组 创建数组 访问数组:通过指定数组名以及索引号,可以访问某个特定的元素 对象 1.系统所提供对象 2.自定义对象 访问对象 函数 第一种 第二 ...
- 【repost】Javascript操作DOM常用API总结
Javascript操作DOM常用API总结 文本整理了javascript操作DOM的一些常用的api,根据其作用整理成为创建,修改,查询等多种类型的api,主要用于复习基础知识,加深对原生js的认 ...
- JavaScript中DOM操作
Web前端基础修炼 HTML基本标签详解与运行截图 CSS基本操作详解及截图演示 JavaScript基础(ECMAScript) JavaScript中DOM操作 JavaScript中BOM操作 ...
- 【JavaScript】DOM 操作元素样式和元素类名
文章目录 [JavaScript]DOM 操作元素样式和元素类名 一. 操作元素样式 (1)操作行内元素 1. 获取元素的样式 2. 设置元素的样式 (2) 操作非行内元素和行内元素 1. 获取元素的 ...
最新文章
- 【2020 Fall】哥伦比亚大学最新《机器学习》课程
- linux 进程 ctrl-c,ctrl-z,ctrl-d
- Linux下编译vtk的java版本,Ubuntu 16.04 编译VTK7.1
- lvs负载均衡—高可用集群(keepalived)
- html 只能输入正数,vue 限制input只能输入正数
- 网页loading效果 可以通过js控制旋转速度
- 6. 同步化器(Synchronizers)
- 从单张图重建三维人体模型综述(五)
- 云平台仿真框架cloudsim介绍
- oracle 物化视图 on demand,oracle物化视图的两个典型应用场景
- Android 9.0中sdcard 的权限和挂载问题
- CAN 错误帧和原理
- [译] 我无法想象没有 Git 别名的的场景
- 软件工程——自我介绍
- 计算机科学 中文核心,什么是最快的计算机科学中文核心期刊?
- APIX_身份证图像识别技术(附代码)
- 初中地理历史计算机教师资格证,初中地理教师资格证好考吗
- ssh隧道原理及三种隧道转发模式
- 面向接口编程,接口是什么,有什么作用?
- 2023年云计算的发展趋势如何?还值得学习就业吗?