- function inherit(obj) {
- if (obj === null) throw TypeError();
- if (Object.create) return Object.create(obj);
- var t = typeof obj;
- if (t !== "object" && t !== "function") throw TypeError();
- function Fn() {};
- Fn.prototype = obj;
- return new Fn();
- }
- String.prototype.mytrim = function () {
- String.prototype.trim || function () {
- if (!this) return this; //空字符串不做处理
- return this.replace(/^\s+|\s+$/g, "") //使用正则表达式经行空格替换
- }
- }
- var reduce = Array.prototype.reduce ?
- function(ary, fn, initial) {
- if (arguments.length > 2) { //如果reduce()方法存在的话
- return ary.reduce(fn, initial); //如果传入了一个初始值
- } else {
- return ary.reduce(fn); //否则初始值
- }
- }: function(ary, fn, initial) { //以特定的初始值开始,否则第一个值取自ary
- var i = 0,
- len = ary.length,
- accumulator;
- if (arguments.length > 2) {
- accumulator = initial;
- } else { //找到数组中第一个已经定义的索引
- if (len == 0) throw TypeError();
- while (i < len) {
- if (i in ary) {
- accumulator = ary[i++];
- break;
- } else {
- i++;
- }
- }
- if (i == len) throw TypeError();
- }
- while (i < len) { //对于数组中剩下的元素依次调用fn
- if (i in ary) {
- accumulator = fn.call(undefined, accumulator, ary[i], i, ary)
- }
- i++;
- }
- return accumulator;
- }
- function findAll(ary, ele) {
- var results = [],
- len = a.length,
- pos = 0;
- while (pos < len) {
- pos = ary.indexOf(ele, pos);
- if (pos === -1) break;
- results.push(pos);
- pos++;
- }
- return results;
- }
- function classOf(obj) {
- if (obj === null) return "Null";
- if (obj === undefined) return 'Undefined';
- return Object.prototype.toString.call(obj).slice(8, -1);
- }
- function keys(obj) {
- if (typeof obj !== "object") {
- throw TypeError();
- }
- var result = [];
- for (var prop in obj) {
- if (obj.hasOwnProperty(prop)) {
- result.push(prop);
- }
- }
- return result;
- }
- function max() {
- var max = Number.NEGATIVE_INFINITY;
- for (var i = 0; i < arguments.length; i++) {
- if (arguments[i] > max) max = arguments[i];
- }
- return max;
- }
- if (!Function.prototype.bind) {
- Function.prototype.bind = function(obj) {
- var self = this,
- boundArgs = arguments;
- return function() {
- var args = [],
- i;
- for (i = 1; i < boundArgs.length; i++) args.push(boundArgs[i]);
- for (i = 1; i < arguments.length; i++) args.push(arguments[i]);
- return self.apply(obj, args);
- }
- }
- }
- var map = Array.prototype.map ? function (ary, fn) {
- return ary.map(fn);
- } : function (ary, fn) {
- var results = [];
- for (var i = 0, len = ary.length; i < len; i++) {
- if (i in ary) {
- results[i] = fn.call(null, ary[i], i, ary);
- }
- }
- return results;
- }
- Array.prototype.unique = function unique() {
- var obj = {};
- for (var i = 0; i < this.length; i++) {
- var current = this[i];
- if (obj[current] === current) {
- current = this[this.length - 1];
- this.length--;
- i--;
- continue;
- }
- obj[current] = current
- }
- obj = null;
- return this;
- }
- Array.prototype.bubbleSort = function bubbleSort() {
- var temp = null;
- for (var i = 0; i < this.length - 1; i++) {
- for (var k = 0; k < this.length - 1 - i; k++) {
- if (this[k] > this[k + 1]) {
- temp = this[k];
- this[k] = this[k + 1];
- this[k + 1] = temp;
- }
- }
- }
- return this;
- }
- String.prototype.mymatch = function(reg) {
- var ary = [];
- var res = reg.exec(this);
- while (res) {
- ary.push(res[0]);
- res = reg.exec(this);
- }
- return ary;
- }
- /**
- *返回元素ele的第n层祖先元素,如果不存在此类祖先或祖先不是Element,
- *(例如Document或者DocumentFragment)则返回null
- *如果n为0,则返回e本身。如果n为1(或省略),则返回其父元素
- *如果n为2,则返回其祖父元素,依次类推
- */
- function parent(ele, n) {
- if (n === nudefined) n = 1;
- while (n--&&ele) {
- ele = ele.parentNode;
- }
- if (!ele || ele.nodeTope !== 1) return null;
- return ele;
- }
- /**
- *返回元素ele的第n个兄弟元素
- *如果n为正,返回后续的第n个兄弟元素
- *如果n为负,返回前面的第n个兄弟元素
- *如果n为零,返回ele本身
- */
- function sibling(ele, n) {
- while (ele && n !== 0) { //如果ele未定义,即刻返回它
- if (n > 0) { //查找后续的兄弟元素
- if (ele.nextElementSibling) {
- ele = ele.nextElementSibling;
- } else {
- for (ele = ele.nextSibling; ele && ele.nodeType !== 1; ele = ele.nextSibling) /*空循环*/;
- }
- n--;
- } else { //查找前面的兄弟元素
- if (ele.previousElementSibing) {
- ele = ele.previousElementSibling;
- } else {
- for (ele = ele.previousSibling; ele && ele.nodeType !== 1; ele = ele.previousSibling) /*空循环*/;
- }
- n++;
- }
- }
- return ele;
- }
- /**
- *返回元素ele的第n代子元素,如果不存在则为null
- *负值n代表从后往前计数。0表示第一个子元素,而-1代表最后一个,-2代表倒数第二个,依次类推
- */
- function child(ele, n) {
- if (ele.children) { //如果children数组存在
- if (n < 0) n += ele.children.length; //转换负的n为数组索引
- if (n < 0) return null; //如果它仍然为负,说明没有子元素
- return ele.children[n]; //返回指定的子元素
- }
- //如果e没有children数组,找到第一个子元素并向前数,或找到最后一个子元素并往回数
- if (n >= 0) { //n非负:从第一个子元素向前数
- //找到元素e的第一个子元素
- if (ele.firstElementChild) {
- ele = ele.firstElementChild;
- } else {
- for (ele = ele.firstChild; ele && ele.nodeType !== 1; ele = ele.nextSibling) /*空循环*/;
- }
- return sibling(ele, n); //返回第一个子元素的第n个兄弟元素
- } else { //n为负:从最后一个子元素往回数
- if (ele.lastElementChild) {
- ele = ele.lastElementChild;
- } else {
- for (ele = ele.lastChild; ele && ele.nodeType !== 1; ele = ele.previousSibling) /*空循环*/;
- }
- return sibling(ele, n + 1); //+1来转化最后1个子元素为最后1个兄弟元素
- }
- }
- //根据指定表格每行第n个单元格的值,对第一个<tbody>中的行进行排序
- //如果存在comparator函数则使用它,否则按字母表顺序比较
- function sortrows(table, n, comparator) {
- var tbody = table.tBodies[0]; //第一个<tbody>,可能是隐式创建的
- var rows = tbody.getElementsByTagName("tr"); //tbody中的所有行
- rows = Array.prototype.slice.call(rows, 0); //真实数组中的快照
- //基于第n个<td>元素的值对行排序
- rows.sort(function(row1, row2) {
- var cell1 = row1.getElementsByTagName("td")[n]; //获得第n个单元格
- var cell2 = row2.getElementsByTagName("td")[n]; //两行都是
- var val1 = cell1.textContent || cell1.innerText; //获得文本内容
- var val2 = cell2.textContent || cell2.innerText; //两单元格都是
- if (comparator) return comparator(val1, val2); //进行比较
- if (val1 < val2) {
- return - 1;
- } else if (val1 > val2) {
- return 1;
- } else {
- return 0;
- }
- }); //在tbody中按它们的顺序把行添加到最后
- //这将自动把它们从当前位置移走,故没必要预先删除它们
- //如果<tbody>还包含了除了<tr>的任何其他元素,这些节点将会悬浮到顶部位置
- for (var i = 0; i < rows.length; i++) tbody.appendChild(rows[i]);
- }
- //查找表格的<th>元素(假设只有一行),让它们可单击,
- //以便单击列标题,按该列对行排序
- function makeSortable(table) {
- var headers = table.getElementsByTagName("th");
- for (var i = 0; i < headers.length; i++) { (function(n) { //嵌套函数来创建本地作用域
- headers[i].onclick = function() {
- sortrows(table, n);
- };
- } (i)); //将i的值赋给局部变量n
- }
- }
- /**
- *
- *这个模块注册一个可在页面加载完成后自动运行的匿名函数。当执行这个函数时会去文档中查找
- *id为"TOC"的元素。如果这个元素不存在,就创建一个元素
- *
- *生成的TOC目录应当具有自己的CSS样式。整个目录区域的样式className设置为"TOCEntry"
- *同样我们为不同层级的目录标题定义不同的样式。<h1>标签生成的标题
- *className为"TOCLevel1",<h2>标签生成的标题className为"TOCLevel2",以此类推
- *段编号的样式为"TOCSectNum"
- *
- *完整的CSS样式代码如下:
- *
- *#TOC{border:solid black 1px;margin:10px;padding:10px;}
- *.TOCEntry{font-family:sans-serif;}
- *.TOCEntry a{text-decoration:none;}
- *.TOCLevel1{font-size:16pt;font-weight:bold;}
- *.TOCLevel2{font-size:12pt;margin-left:.5in;}
- *.TOCSectNum:after{content:":";}
- *
- *这段代码的最后一行表示每个段编号之后都有一个冒号和空格符。要想隐藏段编号,
- *请使用这行代码:
- *.TOCSectNum{display:none}
- *
- **/
- (function() { //匿名函数定义了一个局部作用域
- //查找TOC容器元素
- //如果不存在,则在文档开头处创建一个
- var toc = document.getElementById("TOC");
- if (!toc) {
- toc = document.createElement("div");
- toc.id = "TOC";
- document.body.insertBefore(toc, document.body.firstChild);
- }
- //查找所有的标题元素
- var headings;
- if (document.querySelectorAll) //我们是否能用这个简单的方法?
- headings = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
- else //否则,查找方法稍微麻烦一些
- headings = findHeadings(document.body, []); //递归遍历document的body,查找标题元素
- function findHeadings(root, sects) {
- for (var c = root.firstChild; c != null; c = c.nextSibling) {
- if (c.nodeType !== 1) continue;
- if (c.tagName.length == 2 && c.tagName.charAt(0) == "H") sects.push(c);
- else findHeadings(c, sects);
- }
- return sects;
- }
- //初始化一个数组来保持跟踪章节号
- var sectionNumbers = [0, 0, 0, 0, 0, 0]; //现在,循环已找到的标题元素
- for (var h = 0; h < headings.length; h++) {
- var heading = headings[h]; //跳过在TOC容器中的标题元素
- if (heading.parentNode == toc) continue; //判定标题的级别
- var level = parseInt(heading.tagName.charAt(1));
- if (isNaN(level) || level < 1 || level > 6) continue; //对于该标题级别增加sectionNumbers对应的数字
- //重置所有标题比它级别低的数字为零
- sectionNumbers[level - 1]++;
- for (var i = level; i < 6; i++) sectionNumbers[i] = 0; //现在,将所有标题级别的章节号组合产生一个章节号, 如2 .3 .1
- var sectionNumber = sectionNumbers.slice(0, level).join(".") //为标题级别增加章节号
- //把数字放在<span>中,使得其可以用样式修饰
- var span = document.createElement("span");
- span.className = "TOCSectNum";
- span.innerHTML = sectionNumber;
- heading.insertBefore(span, heading.firstChild); //用命名的锚点将标题包起来,以便为它增加链接
- var anchor = document.createElement("a");
- anchor.name = "TOC" + sectionNumber;
- heading.parentNode.insertBefore(anchor, heading);
- anchor.appendChild(heading); //现在为该节创建一个链接
- var link = document.createElement("a");
- link.href = "#TOC" + sectionNumber; //链接的目标地址
- link.innerHTML = heading.innerHTML; //链接文本与实际标题一致
- //将链接放在一个div中,div用基于级别名字的样式修饰
- var entry = document.createElement("div");
- entry.className = "TOCEntry TOCLevel" + level;
- entry.appendChild(link); //该div添加到TOC容器中
- toc.appendChild(entry);
- }
- } ());
- /*
- *这个函数用来解析来自URL的查询串中的name=value参数对
- *它将name=value对存储在一个对象的属性中,并返回该对象
- *这样来使用它
- *
- *var args=urlArgs();//从URL中解析参数
- *var q=args.q||"";//如果参数定义了的话就使用参数;否则使用一个默认值
- *var n=args.n?parseInt(args.n):10;
- */
- function urlArgs() {
- var args = {}; //定义一个空对象
- var query = location.search.substring(1); //查找到查询串,并去掉'?'
- var pairs = query.split("&"); //根据"&"符号将查询字符串分隔开
- for (var i = 0; i < pairs.length; i++) { //对于每个片段
- var pos = pairs[i].indexOf('='); //查找"name=value"
- if (pos == -1) continue; //如果没有找到的话,就跳过
- var name = pairs[i].substring(0, pos); //提取name
- var value = pairs[i].substring(pos + 1); //提取value
- value = decodeURIComponent(value); //对value进行解码
- args[name] = value; //存储为属性
- }
- return args; //返回解析后的参数
- }
- /**
- *一个参数,返回元素的textContent或innerText
- *两个参数,用value参数的值设置元素的textContent或innerText
- */
- function textContent(element, value) {
- var content = element.textContent; //检测textContent是否有定义
- if (value === undefined) { //没传递value,因此返回当前文本
- if (content !== undefined) {
- return content;
- } else {
- return element.innerText;
- }
- } else { //传递了value,因此设置文本
- if (content !== undefined) {
- element.textContent = value;
- } else {
- element.innerText = value;
- }
- }
- }
- //根据指定的URL发送一个JSONP请求
- //然后把解析得到的响应数据传递给回调函数
- //在URL中添加一个名为jsonp的查询参数,用于指定该请求的回调函数的名称
- function getJSONP(url, callback) { //为本次请求创建一个唯一的回调函数名称
- var cbnum = "cb" + getJSONP.counter++; //每次自增计数器
- var cbname = "getJSONP." + cbnum; //作为JSONP函数的属性
- //将回调函数名称以表单编码的形式添加到URL的查询部分中
- //使用jsonp作为参数名,一些支持JSONP的服务
- //可能使用其他的参数名,比如callback
- if (url.indexOf("?") === -1) //URL没有查询部分
- url += "?jsonp=" + cbname; //作为查询部分添加参数
- else //否则
- url += "&jsonp=" + cbname; //作为新的参数添加它
- //创建script元素用于发送请求
- var script = document.createElement("script"); //定义将被脚本执行的回调函数
- getJSONP[cbnum] = function(response) {
- try {
- callback(response); //处理响应数据
- } finally { //即使回调函数或响应抛出错误
- delete getJSONP[cbnum]; //删除该函数
- script.parentNode.removeChild(script); //移除script元素
- }
- }; //立即触发HTTP请求
- script.src = url; //设置脚本的URL
- document.body.appendChild(script); //把它添加到文档中
- }
- getJSONP.counter = 0; //用于创建唯一回调函数名称的计数器
- //将child节点插入到parent中,使其成为第n个子节点
- function insertAt(parent, child, n) {
- if (n < 0 || n > parent.childNodes.length) {
- throw new Error("invalid index");
- } else if (n == parent.childNodes.length) {
- parent.appendChild(child);
- } else {
- parent.insertBefore(child, parent.childNodes[n]);
- }
- }
- //为那些不支持它的浏览器实现outerHTML属性
- //假设浏览器确实支持innerHTML,并有个可扩展的Element.prototype,
- //并且可以定义getter和setter
- (function() { //如果outerHTML存在,则直接返回
- if (document.createElement("div").outerHTML) return; //返回this所引用元素的外部HTML
- function outerHTMLGetter() {
- var container = document.createElement("div"); //虚拟元素
- container.appendChild(this.cloneNode(true)); //复制到该虚拟节点
- return container.innerHTML; //返回虚拟节点的innerHTML
- }
- //用指定的值设置元素的外部HTML
- function outerHTMLSetter(value) { //创建一个虚拟元素,设置其内容为指定的值
- var container = document.createElement("div");
- container.innerHTML = value; //将虚拟元素中的节点全部移动到文档中
- while (container.firstChild) //循环,直到container没有子节点为止
- this.parentNode.insertBefore(container.firstChild, this); //删除所被取代的节点
- this.parentNode.removeChild(this);
- }
- //现在使用这两个函数作为所有Element对象的outerHTML属性的getter和setter
- //如果它存在则使用ES5的Object.defineProperty()方法,
- //否则,退而求其次,使用__defineGetter__()和__defineSetter__()
- if (Object.defineProperty) {
- Object.defineProperty(Element.prototype, "outerHTML", {
- get: outerHTMLGetter,
- set: outerHTMLSetter,
- enumerable: false,
- configurable: true
- });
- } else {
- Element.prototype.__defineGetter__("outerHTML", outerHTMLGetter);
- Element.prototype.__defineSetter__("outerHTML", outerHTMLSetter);
- }
- } ());
- //倒序排列节点n的子节点
- function reverse(n) { //创建一个DocumentFragment作为临时容器
- var f = document.createDocumentFragment(); //从后至前循环子节点,将每一个子节点移动到文档片段中
- //n的最后一个节点变成f的第一个节点,反之亦然
- //注意,给f添加一个节点,该节点自动地会从n中删除
- while (n.lastChild) f.appendChild(n.lastChild); //最后,把f的所有子节点一次性全部移回n中
- n.appendChild(f);
- }
- //以一个对象的x和y属性的方式返回滚动条的偏移量
- function getScrollOffsets(w) { //使用指定的窗口,如果不带参数则使用当前窗口
- w = w || window; //除了IE 8及更早的版本以外,其他浏览器都能用
- if (w.pageXOffset != null) return {
- x: w.pageXOffset,
- y: w.pageYOffset
- }; //对标准模式下的IE(或任何浏览器)
- var d = w.document;
- if (document.compatMode == "CSS1Compat") return {
- x: d.documentElement.scrollLeft,
- y: d.documentElement.scrollTop
- }; //对怪异模式下的浏览器
- return {
- x: d.body.scrollLeft,
- y: d.body.scrollTop
- };
- }
- //作为一个对象的w和h属性返回视口的尺寸
- function getViewportSize(w) { //使用指定的窗口,如果不带参数则使用当前窗口
- w = w || window; //除了IE 8及更早的版本以外,其他浏览器都能用
- if (w.innerWidth != null) return {
- w: w.innerWidth,
- h: w.innerHeight
- }; //对标准模式下的IE(或任何浏览器)
- var d = w.document;
- if (document.compatMode == "CSS1Compat") return {
- w: d.documentElement.clientWidth,
- h: d.documentElement.clientHeight
- }; //对怪异模式下的浏览器
- return {
- w: d.body.clientWidth,
- h: d.body.clientWidth
- };
- }
- Function.prototype.getName = function() {
- return this.name || this.toString().match(/function\s*(\w*)\s*\(/)[1];
- }
- //将e转化为相对定位的元素,使之左右"震动"
- //第一个参数可以是元素对象或者元素的id
- //如果第二个参数是函数,以e为参数,它将在动画结束时调用
- //第三个参数指定e震动的距离,默认是5像素
- //第四个参数指定震动多久,默认是500毫秒
- function shake(e, oncomplete, distance, time) { //句柄参数
- if (typeof e === "string") e = document.getElementById(e);
- if (!time) time = 500;
- if (!distance) distance = 5;
- var originalStyle = e.style.cssText; //保存e的原始style
- e.style.position = "relative"; //使e相对定位
- var start = (new Date()).getTime(); //注意,动画的开始时间
- animate(); //动画开始
- //函数检查消耗的时间,并更新e的位置
- //如果动画完成,它将e还原为原始状态
- //否则,它更新e的位置,安排它自身重新运行
- function animate() {
- var now = (new Date()).getTime(); //得到当前时间
- var elapsed = now - start; //从开始以来消耗了多长时间?
- var fraction = elapsed / time; //是总时间的几分之几?
- if (fraction < 1) { //如果动画未完成
- //作为动画完成比例的函数,计算e的x位置
- //使用正弦函数将完成比例乘以4pi
- //所以,它来回往复两次
- var x = distance * Math.sin(fraction * 4 * Math.PI);
- e.style.left = x + "px"; //在25毫秒后或在总时间的最后尝试再次运行函数
- //目的是为了产生每秒40帧的动画
- setTimeout(animate, Math.min(25, time - elapsed));
- } else { //否则,动画完成
- e.style.cssText = originalStyle //恢复原始样式
- if (oncomplete) oncomplete(e); //调用完成后的回调函数
- }
- }
- }
- function fadeOut(e, oncomplete, time) {
- if (typeof e === "string") e = document.getElementById(e);
- if (!time) time = 500; //使用Math.sqrt作为一个简单的“缓动函数”来创建动画
- //精巧的非线性:一开始淡出得比较快,然后缓慢了一些
- var ease = Math.sqrt;
- var start = (new Date()).getTime(); //注意:动画开始的时间
- animate(); //动画开始
- function animate() {
- var elapsed = (new Date()).getTime() - start; //消耗的时间
- var fraction = elapsed / time; //总时间的几分之几?
- if (fraction < 1) { //如果动画未完成
- var opacity = 1 - ease(fraction); //计算元素的不透明度
- e.style.opacity = String(opacity); //设置在e上
- setTimeout(animate, //调度下一帧
- Math.min(25, time - elapsed));
- } else { //否则,动画完成
- e.style.opacity = "0"; //使e完全透明
- if (oncomplete) oncomplete(e); //调用完成后的回调函数
- }
- }
- }
- /*
- *如果e有classList属性则返回它。否则,返回一个为e模拟DOMTokenList API的对象
- *返回的对象有contains()、add()、remove()、toggle()和toString()等方法
- *来检测和修改元素e的类集合。如果classList属性是原生支持的,
- *返回的类数组对象有length和数组索引属性。模拟DOMTokenList不是类数组对象,
- *但是它有一个toArray()方法来返回一个含元素类名的纯数组快照
- */
- function classList(e) {
- if (e.classList) return e.classList; //如果e.classList存在,则返回它
- else return new CSSClassList(e); //否则,就伪造一个
- }
- //CSSClassList是一个模拟DOMTokenList的JavaScript类
- function CSSClassList(e) {
- this.e = e;
- } //如果e.className包含类名c则返回true否则返回false
- CSSClassList.prototype.contains = function(c) { //检查c是否是合法的类名
- if (c.length === 0 || c.indexOf(" ") != -1) throw new Error("Invalid class name:'" + c + "'"); //首先是常规检查
- var classes = this.e.className;
- if (!classes) return false; //e不含类名
- if (classes === c) return true; //e有一个完全匹配的类名
- //否则,把c自身看做一个单词,利用正则表达式搜索c
- //\b在正则表达式里代表单词的边界
- return classes.search("\\b" + c + "\\b") != -1;
- }; //如果c不存在,将c添加到e.className中
- CSSClassList.prototype.add = function(c) {
- if (this.contains(c)) return; //如果存在,什么都不做
- var classes = this.e.className;
- if (classes && classes[classes.length - 1] != "") c = "" + c; //如果需要加一个空格
- this.e.className += c; //将c添加到className中
- }; //将在e.className中出现的所有c都删除
- CSSClassList.prototype.remove = function(c) { //检查c是否是合法的类名
- if (c.length === 0 || c.indexOf(" ") != -1) throw new Error("Invalid class name:'" + c + "'"); //将所有作为单词的c和多余的尾随空格全部删除
- var pattern = new RegExp("\\b" + c + "\\b\\s*", "g");
- this.e.className = this.e.className.replace(pattern, "");
- }; //如果c不存在,将c添加到e.className中,并返回true
- //否则,将在e.className中出现的所有c都删除,并返回false
- CSSClassList.prototype.toggle = function(c) {
- if (this.contains(c)) { //如果e.className包含c
- this.remove(c); //删除它
- return false;
- } else { //否则
- this.add(c); //添加它
- return true;
- }
- }; //返回e.className本身
- CSSClassList.prototype.toString = function() {
- return this.e.className;
- }; //返回在e.className中的类名
- CSSClassList.prototype.toArray = function() {
- return this.e.className.match(/\b\w+\b/g) || [];
- };
- /**
- *一个参数,返回元素的textContent或innerText
- *两个参数,用value参数的值设置元素的textContent或innerText
- */
- function textContent(element, value) {
- var content = element.textContent; //检测textContent是否有定义
- if (value === undefined) { //没传递value,因此返回当前文本
- if (content !== undefined) return content;
- else return element.innerText;
- } else { //传递了value,因此设置文本
- if (content !== undefined) element.textContent = value;
- else element.innerText = value;
- }
- }
textContent属性在除了IE的所有当前的浏览器中都支持。在IE中,可以用Element的innerText属性来代替。
- //返回元素e的纯文本内容,递归进入其子元素
- //该方法的效果类似于textContent属性
- function textContent(e) {
- var child, type, s = ""; //s保存所有子节点的文本
- for (child = e.firstChild; child != null; child = child.nextSibling) {
- type = child.nodeType;
- if (type === 3 || type === 4) //Text和CDATASection节点
- s += child.nodeValue;
- else if (type === 1) //递归Element节点
- s += textContent(child);
- }
- return s;
- }
- //本模块为不支持它的浏览器定义了Element.insertAdjacentHTML
- //还定义了一些可移植的HTML插入函数,它们的名字比insertAdjacentHTML更符合逻辑:
- //Insert.before()、Insert.after()、Insert.atStart()和Insert.atEnd()
- var Insert = (function() { //如果元素有原生的insertAdjacentHTML,
- //在4个函数名更明了的HTML插入函数中使用它
- if (document.createElement("div").insertAdjacentHTML) {
- return {
- before: function(e, h) {
- e.insertAdjacentHTML("beforebegin", h);
- },
- after: function(e, h) {
- e.insertAdjacentHTML("afterend", h);
- },
- atStart: function(e, h) {
- e.insertAdjacentHTML("afterbegin", h);
- },
- atEnd: function(e, h) {
- e.insertAdjacentHTML("beforeend", h);
- }
- };
- }
- //否则,无原生的insertAdjacentHTML
- //实现同样的4个插入函数,并使用它们来定义insertAdjacentHTML
- //首先,定义一个工具函数,传入HTML字符串,返回一个DocumentFragment,
- //它包含了解析后的HTML的表示
- function fragment(html) {
- var elt = document.createElement("div"); //创建空元素
- var frag = document.createDocumentFragment(); //创建空文档片段
- elt.innerHTML = html; //设置元素内容
- while (elt.firstChild) //移动所有的节点
- frag.appendChild(elt.firstChild); //从elt到frag
- return frag; //然后返回frag
- }
- var Insert = {
- before: function(elt, html) {
- elt.parentNode.insertBefore(fragment(html), elt);
- },
- after: function(elt, html) {
- elt.parentNode.insertBefore(fragment(html), elt.nextSibling);
- },
- atStart: function(elt, html) {
- elt.insertBefore(fragment(html), elt.firstChild);
- },
- atEnd: function(elt, html) {
- elt.appendChild(fragment(html));
- }
- }; //基于以上函数实现insertAdjacentHTML
- Element.prototype.insertAdjacentHTML = function(pos, html) {
- switch (pos.toLowerCase()) {
- case "beforebegin":
- return Insert.before(this, html);
- case "afterend":
- return Insert.after(this, html);
- case "afterbegin":
- return Insert.atStart(this, html);
- case "beforeend":
- return Insert.atEnd(this, html);
- }
- };
- return Insert; //最后返回4个插入函数
- } ());
- /**
- *Drag.js:拖动绝对定位的HTML元素
- *
- *这个模块定义了一个drag()函数,它用于mousedown事件处理程序的调用
- *随后的mousemove事件将移动指定元素,mouseup事件将终止拖动
- *这些实现能同标准和IE两种事件模型一起工作
- *
- *参数:
- *
- *elementToDrag:接收mousedown事件的元素或某些包含元素
- *它必须是定位的元素,元素的样式必须是行内样式
- *它的style.left和style.top值将随着用户的拖动而改变
- *
- *event:mousedown事件对象
- **/
- function drag(elementToDrag, event) { //初始鼠标位置,转换为文档坐标
- var startX = event.clientX;
- var startY = event.clientY; //在文档坐标下,待拖动元素的初始位置
- //因为elementToDrag是绝对定位的,
- //所以我们可以假设它的offsetParent就是文档的body元素
- var origX = parseFloat(elementToDrag.style.left);
- var origY = parseFloat(elementToDrag.style.top); //计算mousedown事件和元素左上角之间的距离
- //我们将它另存为鼠标移动的距离
- if (document.addEventListener) { //标准事件模型
- //在document对象上注册捕获事件处理程序
- document.addEventListener("mousemove", moveHandler, true);
- document.addEventListener("mouseup", upHandler, true);
- } else if (document.attachEvent) { //用于IE5~8的IE事件模型
- //在IE事件模型中,
- //捕获事件是通过调用元素上的setCapture()捕获它们
- elementToDrag.setCapture();
- elementToDrag.attachEvent("onmousemove", moveHandler);
- elementToDrag.attachEvent("onmouseup", upHandler); //作为mouseup事件看待鼠标捕获的丢失
- elementToDrag.attachEvent("onlosecapture", upHandler);
- }
- //我们处理了这个事件,不让任何其他元素看到它
- if (event.stopPropagation) event.stopPropagation(); //标准模型
- else event.cancelBubble = true; //IE
- //现在阻止任何默认操作
- if (event.preventDefault) event.preventDefault(); //标准模型
- else event.returnValue = false; //IE
- /**
- * 当元素正在被拖动时, 这就是捕获mousemove事件的处理程序
- *它用于移动这个元素
- **/
- function moveHandler(e) {
- if (!e) e = window.event; //IE事件模型
- //移动这个元素到当前鼠标位置,
- //通过滚动条的位置和初始单击的偏移量来调整
- var targetLeft = e.clientX - startX + origX;
- var targetTop = e.clientY - startY + origY;
- var minLeft = 0;
- var minTop = 0;
- var maxLeft = (document.documentElement.clientWidth || document.body.clientWidth) - elementToDrag.offsetWidth;
- var maxTop = (document.documentElement.clientHeight || document.body.clientHeight) - elementToDrag.offsetHeight;
- targetLeft = targetLeft > maxLeft ? maxLeft: (targetLeft < minLeft ? minLeft: targetLeft);
- targetTop = targetTop > maxTop ? maxTop: (targetTop < minTop ? minTop: targetTop);
- elementToDrag.style.left = targetLeft + "px";
- elementToDrag.style.top = targetTop + "px";
- if (e.stopPropagation) e.stopPropagation(); //标准
- else e.cancelBubble = true; //IE
- }
- /**
- *这是捕获在拖动结束时发生的最终mouseup事件的处理程序
- **/
- function upHandler(e) {
- if (!e) e = window.event; //IE事件模型
- //注销捕获事件处理程序
- if (document.removeEventListener) { //DOM事件模型
- document.removeEventListener("mouseup", upHandler, true);
- document.removeEventListener("mousemove", moveHandler, true);
- } else if (document.detachEvent) { //IE 5+事件模型
- elementToDrag.detachEvent("onlosecapture", upHandler);
- elementToDrag.detachEvent("onmouseup", upHandler);
- elementToDrag.detachEvent("onmousemove", moveHandler);
- elementToDrag.releaseCapture();
- }
- //并且不让事件进一步传播
- if (e.stopPropagation) e.stopPropagation(); //标准模型
- else e.cancelBubble = true; //IE
- }
- }
来源: http://www.jqhtml.com/9539.html