《JavaScript_DOM编程艺术》Chapter05 最佳实践,Chapter06 图片库改进版---20210427

Chapter05

链接

伪协议

可以用来链接JavaScript函数的伪协议: javascript:

<a href="javascript:function_name(parameter)">Example</a>

<a href="javascript:pop('http://www.baidu.com/')">Example</a>

但是这种做法非常不好。只有在支持伪协议和JavaScript的浏览器,才可使用。

平稳退化

平稳退化的失败例子:

<!--如果用户禁用JavaScript,则这个链接依然失效-->
<a href="#" onclick="popUp(this.href);return false;">Example</a>

平稳退化的成功例子:

<!--如果用户禁用JavaScript,则这个链接依然有效-->
<a href="http://www.example.com/" onclick="popUp(this.href);return false;">Example</a>

渐进增强

CSS

分离JavaScript

把JavaScript代码打包在prepareLinks函数里,并把这个函数添加到window对象的onload事件上去。
#JavaScript文件

window.onload = prepareLinks;
function prepareLinks(){
 var links = document.getElementsByTagName("a");
 for (var i=0; i<links.length;i++){
 	if (links[i].getAttribute("class") == "popup"){
 		links[i].onclick = function(){
 			popUp(this.getAttribute("href"));
 			return false;
 		}
 	}
 }
}

function popUp(winURL){
	window.open(winURL,"popup","width=320,height=480");
}

向后兼容

网页设计时应考虑到旧版浏览器的解析能力。

对象检测

向后兼容的一种最简单的解决方案。

if (method) {
    //statements
}


window.onload = function(){
	if (!document.getElementsByTagName) return false;
	 var links = document.getElementsByTagName("a");
 	for (var i=0; i<links.length;i++){
 		if (links[i].getAttribute("class") == "popup"){
 		links[i].onclick = function(){
 			popUp(this.getAttribute("href"));
 			return false;
 			}
 		}
 	}
}

但是这个方案的不足是:如果存在检测多个方法或者属性,就会出现非常多的嵌套或者检测语句,让代码显得臃肿难读。

浏览器嗅探技术

除了检测对象是否存在,还可以使用浏览器嗅探(browser snifung)。通过检索浏览器的品牌和版本来改善JS的向后兼容性。但是有风险,因为浏览器有时候信息并不标准,而且浏览器的版本迭代更新导致这个实现起来更难。

性能考虑

为了web的流畅性,应该考虑一些问题。

减少DOM访问和减少标记

尽量少访问DOM和尽量减少标记,在多个函数都会取得一组类似元素的情况下,可以考虑重构代码,把搜索结果保存在一个全局变量里,或者把一组元素直接以参数形式传递给函数。

合并和放置脚本

合并脚本可以减少HTTP请求的次数。
建议把所有的< script>标签都放到文档末尾,标签之前,可以让页面加载更快。
位于块中的脚本会导致浏览器无法并行加载其他文件(如图片或其他脚本),一般来说,根据HTTP规范,浏览器每次从同一域名中最多只能同时下载两个文件,在下载脚本期间,浏览器不会下载其他任何文件,即使是来自不同域名的文件也不会下载,所有其他资源都要等脚本加载完毕后才能下载。所以建议把所有的

压缩脚本

压缩脚本,指的是把脚本文件中不必要的字节(空格、注释等)统统删除。压缩后的代码虽然可读性差,但能大幅减少文件大小。多数情况下,应该有两个版本,一个是工作副本,可以修改代码并添加注释;另一个是压缩副本,用于放在服务器上。通常为了区分非压缩版本,最好在压缩副本的文件名中加上min字样。
压缩工具推荐,Douglas Crockford的JSMin、Google的Closure Compiler。

Chapter06

灵魂5连问:

它支持平稳退化吗?

“如果JavaScript功能被禁用,会怎样?”==>解决

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

它的JavaScript与HTML标记是分离的吗?

  • 添加挂钩
    #gallery.html
        <ul id="imagegallery">
            <li>
                <a href="images/fireworks.jpg" title="A fireworks display" onclick="showPic(this);return false;">Fireworks</a>
            </li>
            <li>
                <a href="images/coffee.jpg" title="A cup of black coffee" onclick="showPic(this);return false;">Coffee</a>
            </li>
            <li>
                <a href="images/rose.jpg" title="A red,red rose" onclick="showPic(this);return false;">Rose</a>
            </li>
            <li>
                <a href="images/bigben.jpg" title="The famous clock" onclick="showPic(this);return false;">Big Ben</a>
            </li>
        </ul>
  • 添加事件处理函数
    #showPic.js
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 = document.getElementsByTagName("a");
    for (var i=0; i<links.length; i++){
        links[i].onclick = function(){
            showPic(this);
            return false;
        }
    }
}
  • 共享onload事件
    #showPic.js
# 方法一:建立匿名函数
window.onload = function(){
	firstFunction();
	secondFunction();
}

# 方法二:建立addLoadEvent函数
function addLoadEvent(func){
	var oldonload = window.onload
	if (typeof window.onload != 'function'){
		window.onload = func;
	}
	else{
		window.onload = function(){
			oldonload();
			func();
		}
	}
}

addLoadEvent(firstFunction);
addLoadEvent(secondFunction);

不要做太多的假设

需要在showPic()检查元素,并对于图片正常但text异常的状况对prepareGallery()作出修改。
#showPic.js

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("title");
    var descrition = document.getElementById("description");
    descrition.firstChild.nodeValue = text;
    }
}

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 = document.getElementsByTagName("a");
    for (var i=0; i<links.length; i++){
        links[i].onclick = function(){
            return !showPic(this);
        }
    }
}

优化

增加三元操作符来检查title属性(这是个费脑子的方法)
#showPic.js

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

键盘访问

最好不要使用onkeypress事件处理函数,用户每按下一个按键都会触发它。建议使用onclick事件处理函数,它也可以使用键盘Enter点击链接。

把JavaScript与CSS结合起来

利用挂钩可以用在CSS样式表里。
#gallery.html

在这里插入代码片

#layout.css

#imagegallery{
    list-style: none;
}
#imagegallery li{
    display: inline;
}

DOM Core和HTML-DOM

以下等价
document.getElementsByTagName("form");
document.forms;

placeholder.setAttribute("src",source);
placeholder.src = source;

综合代码

#showPic.js

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("title")? whichpic.getAttribute("title"):"";
    var descrition = document.getElementById("description");
    descrition.firstChild.nodeValue = text;
    }
}

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 = document.getElementsByTagName("a");
    for (var i=0; i<links.length; i++){
        links[i].onclick = function(){
            return !showPic(this);
        }
    }
}


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

#layout.css

body{
    font-family: "Helvetica","Arial",serif;
    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;
}
img{
    display: block;
    clear: both;
}
#imagegallery{
    list-style: none;
}
#imagegallery li{
    display: inline;
}

#gallery.html

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

上一篇:中国硬质合金行业运行格局及投资战略咨询研究报告2022-2028年


下一篇:建筑五金的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告