Skip to main content
Jkyo Chen Blog

DOM Scripting

JavaScript 简史 #

JavaScript 的起源 #

DOM #

浏览器战争 #

DHTML #

浏览器之间的冲突 #

// Netscape Navigator 4 浏览器
var xpos = document.layers['myelement'].left;

// IE 4
var xops = document.all['myelement'].leftpos;

指定标准 #

var xpos = document.getElementById('myelement').style.left;

浏览器以外的考虑 #

浏览器战争的结局 #

崭新的起点 #

JavaScript 语法 #

准备工作 #

语法 #

语句 #

注释 #

//

/*
*/

// HTML 风格的注释,但这种做法适用于单行注释
 // HTML 注释可以多行

// 建议使用上面两种

变量 #

var mood = "happy", age = 33; // 一条语句

数据类型 #

字符串 #

// 转义(escaping)
var mood = 'don\'t ash';
var height = "about 5'10\" tall";

数值 #

布尔值 #

数组 #

// Array 关键字声明
var beatles = Array(4); // 长度
var beatles = Array(); // 可变长

beatles[0] = "John";

var beatles = Array("John", "Paul", "George", "Ringo");
var beatles = ["John", "Paul", "George", "Ringo"];
var lennon = ["John", 1940, false]; // 3 种数据类型混在一起存入一个数组

关联数组 #

// 可以使用字符串
var lennon = Array();
lennon["name"] = "John";
lennon["year"] = 1940;
lennon["living"] = false;
// 关联数组。由于可以使用字符串来代替数字值,因而代码更具有可读性。
// 但是这种方法不是个好习惯,不推荐使用。

对象 #

// 创建对象使用 Object 关键字
var lennon = Object();
lennon.name = "John";
lennon.year = 1940;
lennon.living = false;

// 花括号语法
{ propertyName:value, propertyName:value }

var lennon = { name:"John", year:1940, living:false };
// 属性名与 JavaScript 变量的命名规则有相同之处,属性值可以是任何 JavaScript 值,包括其他对象。

操作 #

算术运算符 #

year = year + 1;
year++;
year--;

// 数值和字符串拼接在一起,数值将被自动转换为字符串:
var year = 2005;
var message = "The year is " + year;
message += year;

条件语句 #

if (condition)
{
    statements;
} else
{
}

// 如果 if 语句中的花括号部分只包含着一条语句的话,那就可以不使用花括号。
if (1 > 2) alert("The world has gone mad!");

比较操作符 #

ToNumber(false) === ToNumber("") // 都是 0 ,Number(false);

逻辑操作符 #

循环语句 #

do
{
    statements;
} while (condition);

initialize;
while (condition)
{
    statements;
    increments;
}

for (initial condition; test condition; alter condition)
{
    statements;
}

函数 #

变量的作用域 #

对象 #

// 在 JavaScript 里,属性和方法都使用“点”语法来访问
Object.property
Object.method()

// 实例 是对象的具体个体
var jeremy = new Person;

内建对象 #

// 数组就是其中一种内建对象。
// 创建一个 Array 对象的实例
var beatles = new Array();

Math.routnd(7.561);

var current_date = new Date();

宿主对象 #

DOM #

文档:DOM 中的“D” #

对象:DOM中的“O” #

模型:DOM 中的“M” #

节点 #

元素节点 #

文本节点 #

属性节点 #

CSS #

selector
{
    property: value;
}

class 属性 #

id 属性 #

获取元素 #

getElementById #

var purchases = document.getElementById("purchases");

typeof(purchases); // object

getElementsByTagName #

element.getElementsByTagName(tag);

document.getElementsByTagName("li");

// getElementsByTagName 允许把一个通配符作为它的参数
document.getElementsByTagName("*");

var shopping = document.getElementById("purchases");
var items = shopping.getElementsByTagName("*");

getElementsByClassName #

document.getElementsByClassName("sale");
document.getElementsByClassName("important sale"); // 与类名的实际顺序无关

var shopping = document.getElementById("purchases");
var sales = shopping.getElementsByClassName("sale");
// 不适用于多个类名
function getElementsByClassName(node, classname)
{
    if(node.getElementByClassName)
    {
        return node.getElementsByClassName(classname);
    } else
    {
        var results = new Array();
        var elems = node.getElementsByTagName("*");
        for (var i = 0; i < elems.length; i++)
        {
            if (elems[i].className.indexOf(className) != -1)
            {
                results[results.length] = elems[i];
            }
        }
        return results;
    }
}

获取和设置属性 #

getAttribute #

object.getAttribute(attribute)

if(something) 等价于 if(something != null) 完全等价

setAttribute #

object.setAttribute(attribute, value)

var shopping = document.getElementById("purchases");
shopping.setAttribute("title", "a list of goods");

案例研究:JavaScript 图片库 #

事件处理函数 #

event = "Javascript statement(s)"
// JavaScript 代码包含在一对引号之间。我们可以把任意数量的 JavaScript 语句放在这对引号之间,只要把各条语句用分号隔开即可。
onclick="return false"; // 点击不会触发

函数扩展 #

childNodes 属性 #

nodeType 属性 #

nodeValue 属性 #

description.nodeValue; // null
// 文本也是另一种节点,是 description 节点的第一个子节点
description.childNodes[0].nodeValue;

firstChild 和 lastChild 属性 #

最佳实践 #

过去的错误 #

不要怪罪 JavaScript #

Flash 的遭遇 #

质疑一切 #

平稳退化 #

window.open(url, name, features)
// 三个参数都是可选的
// url 是想在新窗口里打开的网页的 URL 地址。如果省略这个参数,屏幕上将弹出一个空白的浏览器窗口
// name 是新窗口的名字。可以在代码中通过这个名字与新窗口进行通信。
// features 是一个以逗号分隔的字符串,其内容是新窗口的各种属性。新窗口的尺寸以及新窗口被启用或禁用的各种浏览功能。(新窗口的浏览功能要少而精)

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

"javascript:" 伪协议 #

Example
// 这条语句在支持 "javascript:" 伪协议的浏览器中运行正常
// 较老的浏览器则会去尝试打开那个链接但失败
// 支持这种伪协议但禁用了 JavaScript 功能的浏览器会什么也不做。

内嵌的事件处理函数 #

Example

// # 符号是一个仅供文档内部使用的链接记号(单就这条指令而言,"#" 是未指向任何目标的内部链接)。在某些浏览器里,"#" 链接指向当前文档的开头。
// 把 href 属性设置为 "#" 只是为了创建一个空链接。

谁关心这个 #

// 为其中的 JavaScript 代码预留出退路,在链接里把 href 属性设置为真实存在的 URL 地址,让它成为一个有效的链接。
Example

Example

// 使用 DOM 提供的 this.href 属性
Example

向 CSS 学习 #

结构与样式的分离 #

渐进增强 #

分离 JavaScript #

element.event = action...
getElementById(id).event = action

// 多个元素
getElementByTagName 和 getAttribute 把事件添加到有特定属性的一组元素上。

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;
        };
    }
}
// 把这个函数添加到 window 对象的 onload 事件上去。
window.onload=prepareLinks;
function prepareLinks()
{
    var links = document.getElementByTagName("a");
    ..
}

向后兼容 #

对象检测 #

// 在使用对象检测时,一定要删掉方法名后面的圆括号,如果不删掉,测试的将是方法的结果,无论方法是否存在。
function myFunction()
{
    if (document.getElementById)
    {
        statements using getElementById
    }
}
if (!getElementById) return false;
if (!getElementById || !getElementById) return false;

if (!document.getElementByTagName) return false;

浏览器嗅探技术 #

性能考虑 #

尽量少访问 DOM 和尽量减少标记 #

if (document.getElementsByTagName("a").length > 0)
{
    var links = document.getElementsByTagName("a");
    for (var i = 0; i < links.length; i++)
    {
        //..
    }
}
// 只要是查询 DOM 中的某些元素,浏览器都会搜索整个 DOM 树,从中查找可能匹配的元素。
// 这段代码使用两次 getElementByTagName 方法去执行相同的操作,浪费一次搜索。应该把搜索结果存到变量中,重用。

合并和放置脚本 #

压缩脚本 #

案例研究:图片库改进版 #

共享 onload 事件 #

// 让这个函数在网页加载完毕之后立刻执行。
window.onload = prepareGallery;

// 多个绑定函数
window.onload = firstFunction;
window.onload = secondFunction; // 它们当中只有最后那个才会被实际执行,每个事件处理函数只能绑定一条指令。

window.onload = function()
{
    firstFunction();
    secondFunction();
} // 在需要绑定的函数不是很多的场合,这是最简单的解决方案。
function addLoadEvent(func)
{
    var oldonload = window.onload;
    if (typeof window.onload != 'function')
    {
        window.onload = func;
    } else
    {
        window.onload = function()
        {
            oldonload();
            func();
        }
    }
}

// 这将把那些在页面加载完毕时执行的函数创建为一个队列。

不要做太多的假设 #

links[i].onclick = function ()
{
  return !showPic(this);
};
// 如果 showPic 返回 true 我们就返回 false,浏览器不会打开那个链接
// 如果 showPic 返回 false ,那么我们认为图片没有更新,于是返回 true 以允许默认行为发生。

优化 #

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

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

variable = condition ? if true : if false;

if (placeholder.nodeName != "IMG") return false;
// nodeName 属性总是返回一个大写字母的值,即使元素在 HTML 文档里是小写字母。

键盘访问 #

// 让 onkeypress 事件与 onclick 事件触发同样的行为
// 复制一份
links[i].onclick = function()
{
    return showPic(this) ? false : true;
}
links[i].onkeypress = function()
{
    return showPic(this) ? false : true;
}
// 或者
links[i].onkeypress = links[i].onclick;

把 JavaScript 与 CSS 结合起来 #

DOM Core 和 HTML-DOM #

getElementById
getElementByTagName
getAttribute
setAttribute
// 这些方法是 DOM Core 的组成部分。它们并不专属于 JavaScript ,支持 DOM 的任何一种程序设计语言都可以使用它们。
// 可以处理任何一种标记语言(xml)编写处理啊的文档。

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

// HTML-DOM提供了一个 forms 对象
document.getElementByTagName("form")
document.forms

// HTML-DOM 还提供了许多描述各种 HTML 元素的属性。
element.getAttribute("src")
element.src
var source = whichpic.href;
placeholder.src = source;

小结 #

动态创建标记 #

一些传统方法 #

document.write #

document.write("

This is inserted.

") // 违背了 "行为应该与表现分离" 的原则。

innerHTML 属性 #

window.onload = functiton()
{
    var testdiv = document.getElementById("testdiv");
    testdiv.innerHTML = "

I inserted this content.

"; } // testdiv 元素里有没有 HTML 内容无关紧要:一旦你使用了 innerHTML 属性,它的全部内容都将被替换。 // innerHTML 属性不会返回任何对刚插入的内容的引用。

DOM 方法 #

createElement 方法 #

var para = document.createElement("p");
// 新创建的 p 元素已经存在,但它还不是任何一颗 DOM 节点树的组成部分。称为文档碎片。
// 已经像任何其他的节点那样有了自己的 DOM 属性。
// 元素节点

appendChild 方法 #

// 成为这个文档某个现有节点的一个字节点。
parent.appendChild(child);

var testdiv = document.getElementById("testdiv");
var para = document.createElement("p");
testdiv.appendChild(para);
// 合并为 1 行,使得代码很难阅读和理解。

createTextNode 方法 #

document.createTextNode(text);

var txt = document.createTextNode("Hello World!");
para.appendChild(text);

重回图片库 #

// 这个XHTML 文件中有一个图片和一段文字仅仅是为 showPic 脚本服务的。
document.getElementsByTagName("body")[0].appendChild(placeholder);
    document.getElementsByTagName("body")[0].appendChild(description);

// HTML-DOM
document.body.appendChild(placeholder);
document.body.appendChild(description);

在已有元素前插入一个新元素 #

parentElement.insertBefore(newElement, targetElement);
// 元素节点的父元素必须是另一个元素节点(属性节点和文本节点的子元素不允许是元素节点)

var gallery = document.getElementById("imagegallery");
gallery.parentNode.insertBefore(placeholder, gallery);

在现有方法后插入一个新元素 #

function insertAfter(newElement, targetElement)
{
    var parent = targetElement.parentNode;
    if (parent.lastChild === targetElement)
    {
        parent.appendChild(newElement);
    } else
    {
        parent.insertBefore(newElement, targetElement.nextSibling);
    }
}

Ajax #

XMLHttpRequest 对象 #

// getHTTPObject.js
function getHTTPObject()
{
    if (typeof XMLHttpRequest === "undefined")
    {
        XMLHttpRequest = function ()
        {
            try
            {
                return new ActiveXObject("Msxml2.XMLHTTP.6.0");
            }
            catch (e)
            {
            }
            try
            {
                return new ActiveXObject("Msxml2.XMLHTTP.3.0");
            }
            catch (e)
            {
            }
            try
            {
                return new ActiveXObject("Msxml2.XMLHTTP");
            }
            catch (e)
            {
            }
            return false;
        };
        return new XMLHttpRequest();
    }
}

// getNewContent.js
function getNewContent()
{
    var request = getHTTPObject();
    if (request)
    {
        request.open("GET", "example.txt", true); // 指定服务器上将要访问的文件,指定请求类型。第三个参数用于指定请求是否以异步方式发送和处理。
        request.onreadystatechange = function()
        {
            if (request.readyState === 4)
            {
                var para = document.createElement("p");
                var txt = document.createTextNode(request.responseText);
                para.appendChild(txt);
                document.getElementById("new").appendChild(para);
            }
        };
        request.send(null);
    } else
    {
        alert("Sorry, your brower does't support XMLHTTPRequest");
    }
}
addLoadEvent(getNewContent());

渐进增强与 Ajax #

Hijax - 渐进增强地使用 Ajax #

充实文档的内容 #

不应该做什么 #

把 "不可见" 变成 "可见" #

选用 HTML,XHTML 还是 HTML5 #

显示 "缩略语列表" #

function displayAbbreviations()
{
    var abbreviations = document.getElementsByTagName("abbr");
    if (abbreviations.length < 1) return false;
    var defs = new Array();
    for (var i = 0; i < abbreviations.length; i++)
    {
        var current_abbr = abbreviations[i];
        var definition = current_abbr.getAttribute("title");
        var key = current_abbr.lastChild.nodeValue;
        defs[key] = definition;
    }
}

创建标记 #

function displayAbbreviations()
{
    if (!document.getElementsByTagName) return false;
    if (!document.createElement) return false;
    if (!document.createTextNode) return false;

    var abbreviations = document.getElementsByTagName("abbr");
    if (abbreviations.length < 1) return false;
    var defs = new Array();

    for (var i = 0; i < abbreviations.length; i++)
    {
        var current_abbr = abbreviations[i];
        var definition = current_abbr.getAttribute("title");
        var key = current_abbr.lastChild.nodeValue;
        defs[key] = definition;
    }

    var dlist = document.createElement("dl");
    for (key in defs)
    {
        var definition = defs[key];
        var dtitle = document.createElement("dt");
        var dtitle_text = document.createTextNode(key);
        dtitle.appendChild(dtitle_text);
        var ddesc = document.createElement("dd");
        var ddesc_text = document.createTextNode(definition);
        ddesc.appendChild(ddesc_text);
        dlist.appendChild(dtitle);
        dlist.appendChild(ddesc);
    }

    var header = document.createElement("h2");
    var header_text = document.createTextNode("Abbreviations");
    header.appendChild(header_text);
    document.getElementsByTagName("body")[0].appendChild(header);
    document.getElementsByTagName("body")[0].appendChild(dlist);
}

addLoadEvent(displayAbbreviations);

一个浏览器 "地雷" #

显示 "文献来源链接表" #

function displayCitations()
{
    if (!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false;
    var quotes = document.getElementsByTagName("blockquote");
    for (var i = 0; i < quotes.length; i++)
    {
        if (!quotes[i].getAttribute("cite")) continue;
        var url = quotes[i].getAttribute("cite");

        var quoteChildren = quotes[i].getElementsByTagName("*");
        if (quoteChildren.length < 1) continue;
        var elem = quoteChildren[quoteChildren.length - 1];

        var link = document.createElement("a");
        var link_text = document.createTextNode("source");
        link.appendChild(link_text);
        link.setAttribute("href", url);

        var superscript = document.createElement("sup");
        superscript.appendChild(link);
        elem.appendChild(superscript);
    }
}
addLoadEvent(displayCitations);

显示 "快捷键清单" #

检索和添加信息 #

CSS-DOM #

三位一体的网页 #

--

分离 #

style 属性 #

获取样式 #

// 在某些浏览器中 color 属性以 RGN(红,绿,蓝)格式的颜色值(153,153,153)返回。

设置样式 #

何时该用 DOM 脚本设置样式 #

根据元素在节点树里的位置来设置样式 #

input[type*="text"]
{
    font-size: 1.2em;
}
p: first-of-type
{
    font-size: 2em;
    font-weight: bold;
}
function styleHeaderSiblings()
{
    if (!document.getElementsByTagName) return false;
    var headers = document.getElementsByTagName("h1");
    for (var i = 0; i < headers.length; i++)
    {
        var elem = getNextElement(headers[i].nextSibling);
        elem.style.fontWeight = "bold";
        elem.style.fontSize = "1.2em";
    }
}

function getNextElement(node)
{
    if (node.nodeType == 1)
    {
        return node;
    }
    if (node.nextSibling)
    {
        return getNextElement(node.nextSibling);
    }
    return null;
}

addLoadEvent(styleHeaderSiblings);

根据某种条件反复设置某种样式 #

// 如果支持 CSS 3
tr:nth-child(odd)
{
    background-color: #ffc;
}

tr:nth-child(even)
{
    background-color: #fff;
}
function stripeTables()
{
    if (!document.getElementsByTagName) return false;
    var tables = document.getElementsByTagName("table");
    var odd, rows;
    for (var i = 0; i < tables.length; i++)
    {
        odd = false;
        rows = tables[i].getElementsByTagName("tr");
        for (var j = 0; j < rows.length; j++)
        {
            if (odd === true)
            {
                rows[j].style.backgroundColor = "#ffc";
                odd = false;
            } else
            {
                odd = true;
            }
        }
    }
}
addLoadEvent(stripeTables);

响应事件 #

tr:hover
{
    font-weight: bold;
}

function highlightRows()
{
    if (!document.getElementsByTagName) return false;
    var rows = document.getElementsByTagName("tr");
    for (var i = 0; i < rows.length; i++)
    {
        rows[i].onmouseover = function()
        {
            this.style.fontWeight = "bold";
        };
        rows[i].onmouseout = function()
        {
            this.style.fontWeight = "normal";
        };
    }
}

addLoadEvent(highlightRows);

className 属性 #

elem.className += " intro";// 注意 intro 的一个字符时空格

function addClass(element, value)
{
    if (!element.className)
    {
        element.className = value;
    } else
    {
        newClassName = element.className;
        newClassName += " ";
        newClassName += value;
        element.className = newClassName;
    }
}

对函数进行抽象 #

function styleElementSiblings(tag, theclass)
{
    if (!document.getElementsByTagName) return false;
    var elems = document.getElementsByTagName(tag);
    var elem;
    for (var i = 0; i < elems.length; i++)
    {
        elem = getNextElement(elems[i].nextSibling);
        addClass(elem, theclass)
    }
}

用 JavaScript 实现动画效果 #

动画基础知识 #

位置 #

时间 #

variable = setTimeout("function", interval);
// 第一个参数是将要执行的函数名
// 第二个参数,以毫秒为单位设定里需要经过多长时间后才开始执行第一个参数所给出的函数。

clearTimeout(variable) // 取消某个正在排队等待执行的函数

movement = setTimeout("moveMessage()", 5000);

时间递增量 #

parseInt(string) // 把字符串里的数值信息提取出来。
parseInt("39 steps") // 39

parseFloat(string) // 返回浮点数

抽象 #

function moveElement(elementID, final_x, final_y, interval)
{
    if (!document.getElementById) return false;
    if (!document.getElementById(elementID)) return false;
    var elem = document.getElementById(elementID);
    var xpos = parseInt(elem.style.left);
    var ypos = parseInt(elem.style.top);

    if (xpos === final_x && ypos === final_y) return true;
    if (xpos < final_x) xpos++;
    if (xpos > final_x) xpos--;
    if (ypos < final_y) ypos++;
    if (ypos > final_y) ypos--;
    elem.style.left = xpos + "px";
    elem.style.top = ypos + "px";

    var repeat ="moveElement('" + elementID + "'," + final_x + "," + final_y +"," + interval + ")";
    setTimeout(repeat, 10);
}

addLoadEvent(moveElement);

实用的动画 #

提出问题 #

解决问题 #

CSS #

变量作用域问题 #

function moveElement(elementID, final_x, final_y, interval)
{
    if (!document.getElementById) return false;
    if (!document.getElementById(elementID)) return false;
    var elem = document.getElementById(elementID);
    if (elem.movement)
    {
        clearTimeout(elem.movement);
    }

    var xpos = parseInt(elem.style.left);
    var ypos = parseInt(elem.style.top);

    if (xpos === final_x && ypos === final_y) return true;
    if (xpos < final_x) xpos++;
    if (xpos > final_x) xpos--;
    if (ypos < final_y) ypos++;
    if (ypos > final_y) ypos--;
    elem.style.left = xpos + "px";
    elem.style.top = ypos + "px";

    var repeat ="moveElement('" + elementID + "'," + final_x + "," + final_y +"," + interval + ")";
    elem.movement = setTimeout(repeat, 10);
}

addLoadEvent(moveElement);

改进动画效果 #

Math.ceil(number); // 这将把浮点数向 "大于" 方向舍入为与之最接近的整数。
Math.floor(number); // 向 "小于" 方向舍入为与之最接近的整数。
Math.round(number); // 舍入与之最接近的整数。

function moveElement(elementID, final_x, final_y, interval)
{
    if (!document.getElementById) return false;
    if (!document.getElementById(elementID)) return false;
    var elem = document.getElementById(elementID);
    if (elem.movement)
    {
        clearTimeout(elem.movement);
    }

    var xpos = parseInt(elem.style.left);
    var ypos = parseInt(elem.style.top);
    var dist = 0;

    if (xpos === final_x && ypos === final_y) return true;
    if (xpos < final_x)
    {
        dist = Math.ceil((final_x - xpos) / 10);
        xpos = xpos + dist;
    }
    if (xpos > final_x)
    {
        dist = Math.ceil((xpos - final_x) / 10);
        xpos = xpos - dist;
    }
    if (ypos < final_y)
    {
        dist = Math.ceil((final_y - ypos));
        ypos = ypos + dist;
    }
    if (ypos > final_y)
    {
        dist = Math.ceil((ypos - final_y));
        ypos = ypos - dist;
    }
    elem.style.left = xpos + "px";
    elem.style.top = ypos + "px";

    var repeat ="moveElement('" + elementID + "'," + final_x + "," + final_y +"," + interval + ")";
    elem.movement = setTimeout(repeat, 10);
}

addLoadEvent(moveElement);

添加安全检查 #

if (!elem.style.left) elem.style.left = "0px";
if (!elem.style.top) elem.style.top = "0px";

生成 HTML 标记 #

HTML5 #

忠告 #

// Modernizer 修改  class 属性,就与可用的 HTML5 特性添加额外的类名。


// 类名中就会间或出现 feature 和 no-feature
// 根据这些类名,可以在 CSS 中定义响应的增强和退化版本,改善用户体验
.multiplebgs article p
{
    // 为支持多背景浏览器编写的样式
}
.no-multiplebgs article p
{
    // 为不支持多背景浏览器编写的后备样式
}


// 一定要放在 `` 元素中。以便它在文档呈现之前能够创建好新的 HTML5 元素。

示例 #

Canvas #

音频和视频 #



混乱的时候 #

自定义控件 #

表单 #

// 检查某个输入类型的控件 inputtypes.type
if (!Modernizr.inputtypes.date)
{
    // 生成日期选择器的脚本
}

// 检查某个属性 input.attribute
if (!Modernizr.input.placeholder)



if (!Modernizr.input.placeholder)
{
    var input = document.getElementById("first-name");
    input.onfocus = function()
    {
        var text = this.placeholder || this.getAttribute("placeholder");
        if (this.text == text)
        {
            this.value = "";
        }
    }
    input.onblur = function()
    {
        if (this.value == "")
        {
            this.value = this.placeholder || this.getAttrubute("placeholder");
        }
    }
    // 在 onblur 处理函数运行时中添加占位符文本
    input.onblue();
}

综合示例 #

增强表单 #

request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// 这个头部信息对于 POST 请求是必需的,它表示请求中包含 URL 编码的表单。


var matches = request.responseText.match(/
([\s\S]+)<\/article>/); // 数组 matches 的第一个元素(索引为 0)是 responseText 中与整个模式匹配的部分,即包括 `
` `
` 的部分。 // 因为模式中包含一个捕获组(一对圆括号),因此 matches 的第二个元素(索引为 1)是 responseText 中与捕获组中的模式匹配部分。

压缩代码 #