javascript 原生常用api 数组方法大全

 <!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			var arr = [
				[1, 2, 2],
				[3, 4, 5, 5],
				[6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
			];
			var newArr = [];

			function changeArr(arr) {
				for(var i = 0; i < arr.length; i++) {
					//遍历arr数组得每一个元素,这里也可以用forEach
					if(arr[i] instanceof Array) {
						//判断元素是否为数组
						changeArr(arr[i])
						//元素为数组则继续调用changeArr方法遍历
					} else {
						newArr.push(arr[i])
						//元素不是数组则可以直接push进新数组
					}
				}
				//此上的判断也可以直接用三元表达式
			}
			changeArr(arr);
			console.log(newArr);    //[1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

		</script>
	</head>

	<body>
	</body>

</html>




方案一(仅去重):

var rusultArr=newArr.reduce(function(rusultArr,a){
         if(rusultArr.indexOf(a)==-1){
                rusultArr.push(a)
                }
                return rusultArr
        },[])


方案二(去重加排序):

rusultArr=Array.from(new Set(newArr)).sort(function(a,b){return a-b})

truncate方法:用于对字符串进行截断处理。当超过限定长度,默认添加3个点号。

function truncate(target, length, truncation) {
    length = length || 30;
    truncation = truncation === void(0) ? '...' : truncation;
    return target.length > length ?
            target.slice(0, length - truncation.length) + truncation : String(target);
}

camelize方法:转换为驼峰风格。

function camelize(target) {
    if (target.indexOf('-') < 0 && target.indexOf('') < 0) {
        return target;//提前判断,提高getStyle等的效率
    }
    return target.replace(/[-][^-]/g, function(match) {
        return match.charAt(1).toUpperCase();
    });
}

underscored方法:转换为下划线风格。

function underscored(target) {
    return target.replace(/([a-z\d])([A-Z])/g, '$1$2').
            replace(/-/g, '').toLowerCase();
}

dasherize方法:转换为连字符风格,即CSS变量的风格。

function dasherize(target) {
    return underscored(target).replace(//g, '-');
}

capitalize方法:首字母大写。

function capitalize(target) {
    return target.charAt(0).toUpperCase() + target.substring(1).toLowerCase();
}

POST和GET的区别,HTTP状态码

POST和GET的区别
GET在浏览器回退时是无害的,而POST会再次提交请求
GET产生的URL地址可以被收藏,而POST不可以
GET请求会被浏览器主动缓存,而POST不会,除非手动设置
GET请求只能进行URL编码,而POST支持多种编码方式
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
GET请求在URL中传送的参数是有长度限制的,而POST没有长度限制
对参数的数据类型,GET只能请求ASCII字符,而POST没有限制
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传敏感信息
GET参数通过URL传递,POST放在Request body中


HTTP状态码
1XX:指示信息-表示请求已接受,继续处理
2XX:成功-表示请求已被成功接收200 OK :客户端请求成功
206 Partial Content:客户发送一个带有Range头的GET请求,服务器完成了它 播放视频和音频
3XX:重定向-要完成请求必须进行更进一步的操作301 Move Permanently:所请求的页面已经转移至新的URL
302 Found:所请求的页面已经临时转移到新的URL
304 Not Modified:客户端有缓冲的文档并发出一个条件性的请求,服务器告诉客户,原来缓冲的文档还可以继续使用
4XX:客户端错误-请求有语法错误或请求无法实现400 Bad Request:客户端请求有语法错误,不能被服务器所理解
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden:对被请求页面的访问被禁止
404 Not Found:请求资源不存在
5XX:服务错误-服务器未能实现合法的请求500 Internal Server Error:服务器发生不可预期的错误原来缓冲的文档还可以继续使用
503 Server Unavailable:请求未完成,服务器临时过载或当机,一段事件后恢复正常

http://www.cnblogs.com/milo-wjh/p/6811868.html

有时可能需要在pagehide事件触发时根据persisted的值采取不同的操作。
对于pageshow事件,如果页面是从bfcache中加载的,那么persisted的值就是true;
对于pagehide事件,如果页面在加载之后会保存在bfcache中,那么persisted的值也会被设置为ture。
因此,当第一次触发pageshow时,persisted的值一定是false,而在第一次触发pagehide时,persisted就会变成true(除非页面不会保存在bfcache中)。指定了onunload事件处理程序的页面会被自动排除在bfcache之外,即使事件处理程序是空的。
具体原因:
onunload最常用于撤销在onload中所执行的操作,而跳过onload后再次显示页面很可能会导致页面不正常。 

微信后退不刷新【JS不执行】:
+    var isPageHide = false;
+    window.addEventListener('pageshow', function () {
+        if (isPageHide) {
+            window.location.reload();
+        }
+    });
+    window.addEventListener('pagehide', function () {
+        isPageHide = true;
+    }); 

http://www.cnblogs.com/blogcxz/p/7341978.html

var a = 1;
 
function foo() {
  if (!a) {
    var a = 2;
  }
  alert(a);
};
 
foo();   //2

 大数相加  http://www.cnblogs.com/kindofblue/p/4672129.html

/*let a;
async function correct() {
    try {
        await Promise.reject('error1')
    } catch (error) {
        console.log(error);
    }
    a = await 1;
    return a;
}

correct().then(v => console.log(a)); // 1
*/


let a;
async function f() {
    await Promise.reject('error');
    a = await 1; // 这段 await 并没有执行
}
f().then(v => console.log(a));
 
@font-face {
  font-family: 'source';
  src: url('../fonts/source.eot');
  src:
    url('../fonts/source.eot?#font-spider') format('embedded-opentype'),
    url('../fonts/source.woff2') format('woff2'),
    url('../fonts/source.woff') format('woff'),
    url('../fonts/source.ttf') format('truetype'),
    url('../fonts/source.svg') format('svg');
  font-weight: normal;
  font-style: normal;
}

.home h1, .demo > .test {
    font-family: 'source';
}
var EventUtil = {   //事件处理程序
    addHandler:function(element,type,handler){
        if(element.addEventListener){//检测是否存在DOM2
            element.addEventListener(type,handler,false)
        }else if(element.attachEvent){//存在ie
            element.attachEvent('on'+type,handler)
        }else{//DOM0
            element['on'+type]=handelr;
        }
    },
    removeHandler:function(element,type,handler){
        if(element.removeEventListener){
            element.removeEventListener(type,handler,false);
        }else if(element.detachEvent){
            element.detachEvent('on'+type,handler);
        }else{
            element['on'+type]=null;
        }
    }
}
构造函数
自己的想法
普通的函数就像是按步骤执行的动作,而构造函数更像是可更改零件的木偶,普通函数可以直接调用,但是构造函数需要new
因为构造函数也是函数,所以可以直接被调用,但是它的返回值为undefine,此时构造函数里面的this对象等于全局this对象
扩展实例和对象的区别,从定义上来讲:1、实例是类的具象化产品,2、而对象是一个具有多种属性的内容结构。funciton Foo(name,age){
  this.name = name;
  this.age = age;
  this.class = 'class-1';
  // return this //默认有这一行
}
var f = new Foo('zhangsan',20); //实例化对象
// var f1 = new Foo('lisi',22) //创建多个对象
构造函数-扩展
var a = {} 其实是 var a = new Object()的语法糖
var a = [] 其实是 var a = new Array()的语法糖
function Foo(){...}其实是 var Foo = new Function(...)
使用 instanceof 判断一个函数是否是一个变量的构造函数如果想判断一个变量是否为“数组”:变量 instanceof Array 

instanceof
用于判断引用类型属于哪个构造函数的方法
f instanceof Foo 的判断逻辑是:
f的__proto__一层一层往上走,是否能对应到Foo.prototype
再试着判断f instanceof Object
magin重叠:边界叠加的大多数问题可以通过添加透明边框或1px的补白来修复。
   
补充解决方案:
1.外层padding
2.透明边框border:1pxsolidtransparent;
3.绝对定位postion:absolute:
4.外层DIVoverflow:hidden;
5.内层DIV 加float:left;display:inline;
6.外层DIV有时会用到zoom:1;
// Adding extend function to Object.prototype
Object.prototype.extend = function(obj) {
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            this[i] = obj[i];
        }
    }
};

var objA = {"name": "colin", "car": "suzuki"};
var objB = {"name": "james", "age": 17};

objA.extend(objB);
objA; // {"name": "james", "age": 17, "car": "suzuki"};

// Lodash
_.assign(objA, objB);



//assign 实现浅复制
var _extends = Object.assign || function(target) {
				for(var i = 1; i < arguments.length; i++) {
					var source = arguments[i];
					for(var key in source) {
						if(Object.prototype.hasOwnProperty.call(source, key)) {
							target[key] = source[key];
						}
					}
				}
				return target;
			};
function sum() {
				var cur = Array.prototype.slice.call(arguments).reduce(function(a,b){
					return a+b; 
				},0);
				function add() {
					return arguments.length==0 ? cur : (cur+=Array.prototype.slice.call(arguments).reduce(function(a,b){return a+b},0), add);
				};
				return arguments.length==0 ? 0 : add;
			}
			console.log(sum());  //0
			console.log(sum(2)(3)());   //5
			console.log(sum(2,3)());    //5
			console.log(sum(2,3,5)());   //10
			console.log(sum(2,3,5)(5)());   //15
			console.log(sum(2,3,5)(5)(5,5)());   //25





function add() {
	var a = arguments[0];
	if(arguments.length == 2) {
		return a + arguments[1];
	} else {
	        return function(b) {
			return a + b;
	        }
	}
}

console.log(add(2, 3));   //5
console.log(add(2)(3));   //5 



add(1)(2)(3)调用方式的方法:
var add = function(a){
    return function(b){
        return function(c){
            return a+b+c;
        };
    };
};
 
add(1)(2)(3); //6


首先要一个数记住每次的计算值,所以使用了闭包,在tmp中记住了x的值,第一次调用add(),初始化了tmp,并将x保存在tmp的作用链中,然后返回tmp保证了第二次调用的是tmp函数,后面的计算都是在调用tmp, 因为tmp也是返回的自己,保证了第二次之后的调用也是调用tmp,而在tmp中将传入的参数与保存在作用链中x相加并付给sum,这样就保证了计算;
但是在计算完成后还是返回了tmp这个函数,这样就获取不到计算的结果了,我们需要的结果是一个计算的数字那么怎么办呢,首先要知道JavaScript中,打印和相加计算,会分别调用toString或valueOf函数,所以我们重写tmp的toString和valueOf方法,返回sum的值;
function add(x) {
    var sum = x;
    var tmp = function (y) {
        sum = sum + y;
        return tmp;
    };
    tmp.toString = function () {
        return sum;
    };
    return tmp;
}
console.log(add(1)(2)(3));  //6
console.log(add(1)(2)(3)(4));   //10
1. for of和迭代器
ES5中,forEach可以用来遍历数组元素,但它的缺陷是不能使用break语句中断循环,也不能使用return语句返回到外层函数。
强大的for-of循环
for (let value of [1, 2, 3]) {
  console.log(value); //输出 1 2 3
}
最简洁、最直接的遍历数组元素的语法
----------------------------------------------------------------------------------------------
这个方法避开了for-in循环的所有缺陷
与forEach()不同的是,它可以正确响应break、continue和return语句其它集合也支持for-of循环
for-of循环不仅支持数组,还支持大多数类数组对象,例如DOM的NodeList对象。
----------------------------------------------------------------------------------------------
它也支持字符串:
for (let chr of "abc12") {
    console.log(chr); // 输出 "a" "b" "c" "1" "2"
}
另外还支持Map和Set对象的遍历。
深入理解
正如其它语言中的for/foreach语句一样,for-of循环语句通过方法调用来遍历各种集合。数组、Map、Set以及我们讨论的其它对象有一个共同点,它们都有一个迭代器方法。
任何对象都可以有/添加迭代器方法。
就像为对象添加myObject.toString()方法,JS知道怎么把这个对象转化为字符串;你为对象添加迭代器方法myObject[Symbol.iterator](),JS也就知道了如何遍历这个对象。
[Symbol.iterator]语法看起来很怪。Symbol是ES6引入的新类型,标准定义了全新的symbol(如Symbol.iterator),来保证不与任何已有代码产生冲突。
任何有迭代器方法[Symbol.iterator]()的对象都是可迭代的。 

     

前端如何设置缓存
通过meta标签的http-equiv属性进行设置
         <meta http-equiv="pragram" content="no-cache">
         <meta http-equiv="cache-control" content="no-cache, must-revalidate">
在ajax请求中通过setRequestHeaders这个方法设置如果还有其他的设置方法,欢迎留言指教。

var target = { a: 1 };

var source1 = { b: 2 };
var source2 = { c: 3 };

Object.assign(target, source1, source2);    //改变了target ,注意和{...a,...b}的区别
target // {a:1, b:2, c:3}   

 

 

 

   

var a={
  "a":{
    "b":{
       "c":100,
       "d":200
     }
  }
};
var b={
  "a":{
    "b":{
       "e":100
     }
  }
}

console.log({...{},...a,...b})

console.log(a)


//ES5
"use strict";

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var a = {
  "a": {
    "b": {
      "c": 100,
      "d": 200
    }
  }
};
var b = {
  "a": {
    "b": {
      "e": 100
    }
  }
};

console.log(_extends({}, a, b));

console.log(a);

 
构造函数 new
JS中的函数即可以是构造函数又可以当作普通函数来调用,当使用new来创建对象时,
对应的函数就是构造函数,通过对象来调用时就是普通函数。
普通函数的创建有:显式声明、匿名定义、new Function() 等三种方式。
当通过new来创建一个新对象时,JS底层将新对象的原型链指向了构造函数的原型对象,
于是就在新对象和函数对象之间建立了一条原型链,通过新对象可以访问到函数对象原型prototype中的方法和属性。

1.创建一个新的空对象;
2.将this绑定到该对象;
3.添加一个名为__proto__的新属性,并且指向构造函数的原型(prototype);
4.返回该this对象。

 

setTimeout(fn, 0) 的作用

setTimeout(0)单线程和异步队列

setTimeout和setInterval是JS内置的两个定时器,使用很简单,但这两个方法背后的原理却不简单。
我们知道,JS是单线程语言,在浏览器中,当JS代码被加载时,浏览器会为其分配一个主线程来执行任务(函数),
主线程会形成一个全局执行环境,执行环境采用栈的方式将待执行任务按顺序依次来执行。
但在浏览器中有一些任务是非常耗时的,比如http请求、定时器、事件回调等,为了保证其他任务的执行效率不被影响,
JS在执行环境中维护了一个异步队列(也叫工作线程),并将这些任务放入队列中进行等待,这些任务的执行时机并不确定,
只有当主线程的任务执行完成以后,才会去检查异步队列中的任务是否需要开始执行。这就是为什么setTimeout(fn,0)
 始终要等到最后执行的原因。关于单线程和异步队列问题请参考:setTimeout(0)
Array的reduce方法   //educe需要两个参数,一个是回调函数,
一个是初始值,没有初始值,会默认把数组第一个当初始值,并从第二个开始
arr.reduce(callback,[initialValue])
callback
    执行数组中每个值的函数,包含四个参数
    accumulator上一次调用回调返回的值,或者是提供的初始值(initialValue)
    currentValue数组中正在处理的元素
    currentIndex数据中正在处理的元素索引,如果提供了 
    initialValue ,从0开始;否则从1开始array调用 reduce 的数组
initialValue可选项,其值用于第一次调用 callback 的第一个参数。
var sum = [0, 1, 2, 3].reduce(function(a, b) {
    return a + b;
}, 0);
// sum is 6



var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
var countedNames = names.reduce(function(allNames, name) { 
  if (name in allNames) {
    allNames[name]++;
  }
  else {
    allNames[name] = 1;
  }
  return allNames;
}, {});   //{}就是上面的allNames,这里当做默认值
// countedNames is { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

 

Array.from()   //扩展运算符(…)也可以将某些数据结构转为数组
将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)
//类似数组的对象
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function (p) {
  console.log(p);
});
// arguments对象
function foo() {
  var args = Array.from(arguments);
  // ...
}


Array.of()
用于将一组值,转换为数组
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

 

深拷贝浅拷贝

1、浅拷贝  //Object.assign() //浅拷贝,类似{...obj1,...obj2} 都是浅拷贝
拷贝就是把父对象的属性,全部拷贝给子对象。
接下来,我们看一个拷贝的例子:
function extendCopy(b) {
  var a = {};
  for (var i in b) {
    a[i] = b[i];
  }
  return a;
}
调用的时候,这样写:
// 调用
var copyA = {
  titleA: '标题A'
};
var copyB = extendCopy(copyA);
console.log(copyB.titleA); // 标题A
但是,这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。
接下来,我们看一个篡改的示例:
function extendCopy(b) {
  var a = {};
  for (var i in b) {
    a[i] = b[i];
  }
  return a;
}
// 调用
var copyA = {
  arrayA: [1, 2, 3, 4]
};
var copyB = extendCopy(copyA);
copyB.arrayA.push(5);
console.log(copyA.arrayA); // [1, 2, 3, 4, 5]
结果是增加了一个5。
所以,extendCopy() 只是拷贝了基本类型的数据,我们把这种拷贝叫做“浅拷贝”。


//数组深拷贝   [].concat(arr1),   var =[...arr1],   arr1.slice(0)



2、深拷贝
function deepCopy(p, c) {
  var c = c || {};
  for (var i in p) {
    if (typeof p[i] === 'object') {
      c[i] = (p[i].constructor === Array) ? [] : {};
      deepCopy(p[i], c[i]);
    } else {
      c[i] = p[i];
    }
  }
  return c;
}
// 调用
var copyA = {
    arrayA: [1, 2, 3, 4]
};
var copyB = deepCopy(copyA);
copyB.arrayA.push(5);
console.log(copyA.arrayA); // [1, 2, 3, 4]

 

Element.matches 精确匹配

document.getElementById('list').addEventListener('click', function (e) {
  // 兼容性处理
  var event = e || window.event;
  var target = event.target || event.srcElement;
  if (target.matches('li.class-1')) {
    console.log('the content is: ', target.innerHTML);
  }
});
移动端touch事件(区分webkit 和 winphone)
当用户手指放在移动设备在屏幕上滑动会触发的touch事件
以下支持webkit
touchstart——当手指触碰屏幕时候发生。不管当前有多少只手指
touchmove——当手指在屏幕上滑动时连续触发。通常我们再滑屏页面,会调用event的preventDefault()可以阻止默认情况的发生:阻止页面滚动
touchend——当手指离开屏幕时触发
touchcancel——系统停止跟踪触摸时候会触发。例如在触摸过程中突然页面alert()一个提示框,此时会触发该事件,这个事件比较少用TouchEvent
touches:屏幕上所有手指的信息
targetTouches:手指在目标区域的手指信息
changedTouches:最近一次触发该事件的手指信息
touchend时,touches与targetTouches信息会被删除,changedTouches保存的最后一次的信息,最好用于计算手指信息参数信息(changedTouches[0])
clientX、clientY在显示区的坐标
target:当前元素


全局错误监控
监听window上的error事件,过滤事件代理的error。
手动触发一个dom事件,需要3步,如果你对document.createEvent,�不是很熟悉,可以点击查看。
创建一个事件对象 document.createEvent(event)
初始化事件对象 event.initEvent(type, bubbles, true)
分发事件 dom.dispatchEvent(event)
Object.preventExtensions(obj)  让一个对象变的不可扩展,也就是永远不能再添加新的属性。
Object.isExtensible(obj) 判断一个对象是否是可扩展的
Object.seal(obj)让一个对象密封(只能读写 不能新增)
Object.isSealed(obj)判断一个对象是否密封
Object.isFrozen(arr)  让一个对象被冻结(只能读)
Object.isFrozen(obj):判断一个对象是否被冻结
Object.keys(obj) 返回一个由给定对象的所有可枚举自身属性的属性名组成的数组
Object.getOwnPropertyNames(obj):返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性)组成的数组
Object.is(value1, value2):判断两个值是否是同一个值,Object.is它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
Object.create(proto [, propertiesObject ]) 是E5中提出的一种新的对象创建方式,第一个参数是要继承的原型,如果不是一个子函数,可以传一个null,第二个参数是对象的属性描述符,这个参数是可选的。
Object.assign 把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。【浅复制】
//var copy = Object.assign({}, obj);
Object.defineProperty() 定义单个对象属性或方法(可以设置读写可枚举)
Object.defineProperties() 定义多个对象属性或方法(可以设置读写可枚举)

Object.assign() //浅拷贝,类似{...obj1,...obj2} 都是浅拷贝
Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)

var target = { a: 1 };
var source1 = { b: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

//如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

var obj1 = {a: {b: 1}};
var obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2

对于这种嵌套的对象,一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。
var target = { a: { b: 'c', d: 'e' } }
var source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }
停止jq中的ajax请求用abort()函数   


<html>  
<head>  
<mce:script type="text/javascript"><!--  
var currentAjax = null;  
function startAjax(){  
    //方法就是将XHR对象指向currentAjax,再调用currentAjax的.abort()来中止请求  
    currentAjax = $.ajax({  
           type:'POST',  
           beforeSend:function(){},  
           url:'test.php',  
           data:'username=xxx',  
           dataType:'JSON',  
           error:function(){alert('error')},  
           success:function(data){alert(data)}  
    });  
}  
function stopAjax(){  
    //如若上一次AJAX请求未完成,则中止请求  
    if(currentAjax) {currentAjax.abort();}  
}  
// --></mce:script>  
</head>  
<body>  
<input type="button" value="触发请求" onclick="startAjax()" />  
<input type="button" value="停止请求" onclick="stopAjax()" />  
</body>  
</html>  
JSONP 超时:

  设置超时标志位flag=false,当超时后将flag=true;
  异步加载JS文件并执行回调函数:
  
  function loadJS(src, callback){
    var script = document.createElement('script');
    var head = document.getElementsByTagName('head')[0];
    var loaded;
    script.src = src;
    if(typeof callback === 'function'){
        script.onload = script.onreadystatechange = function(){
            if(!loaded && (!script.readyState || /loaded|complete/.test(script.readyState))){
                script.onload = script.onreadystatechange = null;
                loaded = true;
                callback();
            }
        }
    }
    head.appendChild(script);
}

加setTimeout 超时后,当超时后将标志位设为true,在onload 里面判断flag为true的时候直接return 掉,
后面的回调函数就不会运行了,JOSNP也就失去了作用!






//获取元素的绝对位置
				function getPosition(node) {
					var width = node.offsetWidth; //元素宽度
					var height = node.offsetHeight; //元素高度
					var left = node.offsetLeft; //获取元素相对于其根元素的left值var left
					var top = node.offsetTop; //获取元素相对于其根元素的top值var top
					current = node.offsetParent; // 取得元素的offsetParent

					// 一直循环直到根元素  
					while(current != null) {  
						left += current.offsetLeft;  
						top += current.offsetTop;  
						current = current.offsetParent;  
					}
					return {
						"width": width,
						"height": height,
						"left": left,
						"top": top
					};
				}





// 动画结束时事件
o.addEventListener("webkitAnimationEnd", function() {
    console.log("动画结束");
})

-webkit-animation动画有三个事件:
开始事件: webkitAnimationStart
结束事件:  webkitAnimationEnd
重复运动事件: webkitAnimationIteration// 动画开始时事件


o.addEventListener("webkitAnimationStart", function() {
    console.log("动画开始");
})
// 动画重复运动时事件
o.addEventListener("webkitAnimationIteration", function() {
    console.log("动画重复运动");
})
// 动画结束时事件
o.addEventListener("webkitAnimationEnd", function() {
    console.log("动画结束");
})











首先我们需要在高度过渡动画完成后执行数字跳动动画,这里我们需要监听'transitionend'事件,对于这个事件需要特别注意的点:
每个过渡属性完成后多会触发一次transitionend;
transitionend事件支持冒泡,如果子元素也有过渡效果的话,一定要阻止冒泡。    // watch : 
    active (newValue) {
        if (newValue) {
            this.$refs.zfbitem.addEventListener('transitionend', this.transitionAction, false);
        }
    }

    // methods:
    transitionAction (e) {
        //不再需要监听时,一定要移除监听
        this.$refs.zfbitem.removeEventListener('transitionend', this.transitionAction, false);
        this.numberBounce();
    }
一、节点
1.1 节点属性
Node.nodeName   //返回节点名称,只读
Node.nodeType   //返回节点类型的常数值,只读
Node.nodeValue  //返回Text或Comment节点的文本值,只读
Node.textContent  //返回当前节点和它的所有后代节点的文本内容,可读写
Node.baseURI    //返回当前网页的绝对路径

Node.ownerDocument  //返回当前节点所在的顶层文档对象,即document
Node.nextSibling  //返回紧跟在当前节点后面的第一个兄弟节点
Node.previousSibling  //返回当前节点前面的、距离最近的一个兄弟节点
Node.parentNode   //返回当前节点的父节点
Node.parentElement  //返回当前节点的父Element节点
Node.childNodes   //返回当前节点的所有子节点
Node.firstChild  //返回当前节点的第一个子节点
Node.lastChild   //返回当前节点的最后一个子节点

//parentNode接口
Node.children  //返回指定节点的所有Element子节点
Node.firstElementChild  //返回当前节点的第一个Element子节点
Node.lastElementChild   //返回当前节点的最后一个Element子节点
Node.childElementCount  //返回当前节点所有Element子节点的数目。
1.2 操作
Node.appendChild(node)   //向节点添加最后一个子节点
Node.hasChildNodes()   //返回布尔值,表示当前节点是否有子节点
Node.cloneNode(true);  // 默认为false(克隆节点), true(克隆节点及其属性,以及后代)
Node.insertBefore(newNode,oldNode)  // 在指定子节点之前插入新的子节点
Node.removeChild(node)   //删除节点,在要删除节点的父节点上操作
Node.replaceChild(newChild,oldChild)  //替换节点
Node.contains(node)  //返回一个布尔值,表示参数节点是否为当前节点的后代节点。
Node.compareDocumentPosition(node)   //返回一个7个比特位的二进制值,表示参数节点和当前节点的关系
Node.isEqualNode(noe)  //返回布尔值,用于检查两个节点是否相等。所谓相等的节点,指的是两个节点的类型相同、属性相同、子节点相同。
Node.normalize()   //用于清理当前节点内部的所有Text节点。它会去除空的文本节点,并且将毗邻的文本节点合并成一个。

//ChildNode接口
Node.remove()  //用于删除当前节点
Node.before()  //
Node.after()
Node.replaceWith()
1.3 Document节点
1.3.1 Document节点的属性
document.doctype   //
document.documentElement  //返回当前文档的根节点
document.defaultView   //返回document对象所在的window对象
document.body   //返回当前文档的<body>节点
document.head   //返回当前文档的<head>节点
document.activeElement  //返回当前文档中获得焦点的那个元素。

//节点集合属性
document.links  //返回当前文档的所有a元素
document.forms  //返回页面中所有表单元素
document.images  //返回页面中所有图片元素
document.embeds  //返回网页中所有嵌入对象
document.scripts  //返回当前文档的所有脚本
document.styleSheets  //返回当前网页的所有样式表

//文档信息属性
document.documentURI  //表示当前文档的网址
document.URL  //返回当前文档的网址
document.domain  //返回当前文档的域名
document.lastModified  //返回当前文档最后修改的时间戳
document.location  //返回location对象,提供当前文档的URL信息
document.referrer  //返回当前文档的访问来源
document.title    //返回当前文档的标题
document.characterSet属性返回渲染当前文档的字符集,比如UTF-8、ISO-8859-1。
document.readyState  //返回当前文档的状态
document.designMode  //控制当前文档是否可编辑,可读写
document.compatMode  //返回浏览器处理文档的模式
document.cookie   //用来操作Cookie
1.3.2 Document节点的方法
(1)读写方法
document.open()   //用于新建并打开一个文档
document.close()   //不安比open方法所新建的文档
document.write()   //用于向当前文档写入内容
document.writeIn()  //用于向当前文档写入内容,尾部添加换行符。
(2)查找节点
document.querySelector(selectors)   //接受一个CSS选择器作为参数,返回第一个匹配该选择器的元素节点。
document.querySelectorAll(selectors)  //接受一个CSS选择器作为参数,返回所有匹配该选择器的元素节点。
document.getElementsByTagName(tagName)  //返回所有指定HTML标签的元素
document.getElementsByClassName(className)   //返回包括了所有class名字符合指定条件的元素
document.getElementsByName(name)   //用于选择拥有name属性的HTML元素(比如<form>、<radio>、<img>、<frame>、<embed>和<object>等)
document.getElementById(id)   //返回匹配指定id属性的元素节点。
document.elementFromPoint(x,y)  //返回位于页面指定位置最上层的Element子节点。
(3)生成节点
document.createElement(tagName)   //用来生成HTML元素节点。
document.createTextNode(text)   //用来生成文本节点
document.createAttribute(name)  //生成一个新的属性对象节点,并返回它。
document.createDocumentFragment()  //生成一个DocumentFragment对象
(4)事件方法
document.createEvent(type)   //生成一个事件对象,该对象能被element.dispatchEvent()方法使用
document.addEventListener(type,listener,capture)  //注册事件
document.removeEventListener(type,listener,capture)  //注销事件
document.dispatchEvent(event)  //触发事件
(5)其他
document.hasFocus()   //返回一个布尔值,表示当前文档之中是否有元素被激活或获得焦点。
document.adoptNode(externalNode)  //将某个节点,从其原来所在的文档移除,插入当前文档,并返回插入后的新节点。
document.importNode(externalNode, deep)   //从外部文档拷贝指定节点,插入当前文档。
1.4 Element节点
1.4.1 Element节点的属性
(1)特性属性
Element.attributes  //返回当前元素节点的所有属性节点
Element.id  //返回指定元素的id属性,可读写
Element.tagName  //返回指定元素的大写标签名
Element.innerHTML   //返回该元素包含的HTML代码,可读写
Element.outerHTML  //返回指定元素节点的所有HTML代码,包括它自身和包含的的所有子元素,可读写
Element.className  //返回当前元素的class属性,可读写
Element.classList  //返回当前元素节点的所有class集合
Element.dataset   //返回元素节点中所有的data-*属性。
(2)尺寸属性
Element.clientHeight   //返回元素节点可见部分的高度
Element.clientWidth   //返回元素节点可见部分的宽度
Element.clientLeft   //返回元素节点左边框的宽度
Element.clientTop   //返回元素节点顶部边框的宽度
Element.scrollHeight  //返回元素节点的总高度
Element.scrollWidth  //返回元素节点的总宽度
Element.scrollLeft   //返回元素节点的水平滚动条向右滚动的像素数值,通过设置这个属性可以改变元素的滚动位置
Element.scrollTop   //返回元素节点的垂直滚动向下滚动的像素数值
Element.offsetHeight   //返回元素的垂直高度(包含border,padding)
Element.offsetWidth    //返回元素的水平宽度(包含border,padding)
Element.offsetLeft    //返回当前元素左上角相对于Element.offsetParent节点的垂直偏移
Element.offsetTop   //返回水平位移
Element.style  //返回元素节点的行内样式
(3)节点相关属性
Element.children   //包括当前元素节点的所有子元素
Element.childElementCount   //返回当前元素节点包含的子HTML元素节点的个数
Element.firstElementChild  //返回当前节点的第一个Element子节点  
Element.lastElementChild   //返回当前节点的最后一个Element子节点  
Element.nextElementSibling  //返回当前元素节点的下一个兄弟HTML元素节点
Element.previousElementSibling  //返回当前元素节点的前一个兄弟HTML节点
Element.offsetParent   //返回当前元素节点的最靠近的、并且CSS的position属性不等于static的父元素。
1.4.2 Element节点的方法
(1)位置方法
getBoundingClientRect()  
// getBoundingClientRect返回一个对象,包含top,left,right,bottom,width,height // width、height 元素自身宽高
// top 元素上外边界距窗口最上面的距离
// right 元素右外边界距窗口最上面的距离
// bottom 元素下外边界距窗口最上面的距离
// left 元素左外边界距窗口最上面的距离
// width 元素自身宽(包含border,padding) 
// height 元素自身高(包含border,padding) 

getClientRects()   //返回当前元素在页面上形参的所有矩形。

// 元素在页面上的偏移量  
var rect = el.getBoundingClientRect()  
return {   
  top: rect.top + document.body.scrollTop,   
  left: rect.left + document.body.scrollLeft  
}
(2)属性方法
Element.getAttribute():读取指定属性  
Element.setAttribute():设置指定属性  
Element.hasAttribute():返回一个布尔值,表示当前元素节点是否有指定的属性  
Element.removeAttribute():移除指定属性
(3)查找方法
Element.querySelector()  
Element.querySelectorAll()  
Element.getElementsByTagName()  
Element.getElementsByClassName()
(4)事件方法
Element.addEventListener():添加事件的回调函数  
Element.removeEventListener():移除事件监听函数  
Element.dispatchEvent():触发事件

//ie8
Element.attachEvent(oneventName,listener)
Element.detachEvent(oneventName,listener)

// event对象  
var event = window.event||event;    

// 事件的目标节点  
var target = event.target || event.srcElement;

// 事件代理  
ul.addEventListener('click', function(event) {   
  if (event.target.tagName.toLowerCase() === 'li') {   
    console.log(event.target.innerHTML)   
  }  
});
(5)其他
Element.scrollIntoView()   //滚动当前元素,进入浏览器的可见区域

//解析HTML字符串,然后将生成的节点插入DOM树的指定位置。
Element.insertAdjacentHTML(where, htmlString); 
Element.insertAdjacentHTML('beforeBegin', htmlString); // 在该元素前插入  
Element.insertAdjacentHTML('afterBegin', htmlString); // 在该元素第一个子元素前插入 
Element.insertAdjacentHTML('beforeEnd', htmlString); // 在该元素最后一个子元素后面插入 
Element.insertAdjacentHTML('afterEnd', htmlString); // 在该元素后插入

Element.remove()  //用于将当前元素节点从DOM中移除
Element.focus()   //用于将当前页面的焦点,转移到指定元素上
二、CSS操作
(1)类名操作
//ie8以下
Element.className  //获取元素节点的类名
Element.className += ' ' + newClassName  //新增一个类名

//判断是否有某个类名
function hasClass(element,className){
  return new RegExp(className,'gi').test(element.className);
}

//移除class
function removeClass(element,className){
  element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'),'');
}

//ie10 
element.classList.add(className)  //新增
element.classList.remove(className)  //删除
element.classList.contains(className)  //是否包含
element.classList.toggle(className)  //toggle class
(2)style操作
element.setAttribute('style','')

element.style.backgroundColor = 'red'

element.style.cssText //用来读写或删除整个style属性

element.style.setProperty(propertyName,value)  //设置css属性
element.style.getPropertyValue(property)  //获取css属性
element.style.removeProperty(property)  //删除css属性
操作非内联样式
//ie8
element.currentStyle[attrName]
//ie9+
window.getComputedStyle(el,null)[attrName] 
window.getComputedStyle(el,null).getPropertyValue(attrName)
//伪类
window.getComputedStyle(el,':after')[attrName]
三、对象
3.1 Object对象
(1)生成实例对象
var o = new Object()
(2)属性
Object.prototype   //返回原型对象
(3)方法
Object.keys(o)   //遍历对象的可枚举属性
Object.getOwnPropertyName(o)   //遍历对象不可枚举的属性
对象实例的方法
valueOf():返回当前对象对应的值。  
toString():返回当前对象对应的字符串形式。  
toLocaleString():返回当前对象对应的本地字符串形式。  
hasOwnProperty():判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性。 
isPrototypeOf():判断当前对象是否为另一个对象的原型。
propertyIsEnumerable():判断某个属性是否可枚举。
3.2 Array对象
(1)生成实例对象
var a = new Array()
(2)属性
a.length  //长度
(3)Array.isArray()
Array.isArray(a)   //用来判断一个值是否为数组
(4)Array实例的方法

[1, [2, [3, 4]]].toString() // "1,2,3,4"

a.valueof()   //返回数组本身
a.toString()  //返回数组的字符串形式
a.push(value,vlaue....)   //用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。
pop()   //用于删除数组的最后一个元素,并返回该元素
join()  //以参数作为分隔符,将所有数组成员组成一个字符串返回。如果不提供参数,默认用逗号分隔。
concat()  //用于多个数组的合并。它将新数组的成员,添加到原数组的尾部,然后返回一个新数组,原数组不变。
shift()  //用于删除数组的第一个元素,并返回该元素。
unshift(value)  //用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度。
reverse()   //用于颠倒数组中元素的顺序,返回改变后的数组
slice(start_index, upto_index);   //用于提取原数组的一部分,返回一个新数组,原数组不变。第一个参数为起始位置(从0开始),第二个参数为终止位置(但该位置的元素本身不包括在内)。如果省略第二个参数,则一直返回到原数组的最后一个成员。负数表示倒数第几个。
splice(index, count_to_remove, addElement1, addElement2, ...);   //用于删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,返回值是被删除的元素。第一个参数是删除的起始位置,第二个参数是被删除的元素个数。如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。
sort()   //对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。如果想让sort方法按照自定义方式排序,可以传入一个函数作为参数,表示按照自定义方法进行排序。该函数本身又接受两个参数,表示进行比较的两个元素。如果返回值大于0,表示第一个元素排在第二个元素后面;其他情况下,都是第一个元素排在第二个元素前面。
map()   //对数组的所有成员依次调用一个函数,根据函数结果返回一个新数组。
map(elem,index,arr)   //map方法接受一个函数作为参数。该函数调用时,map方法会将其传入三个参数,分别是当前成员、当前位置和数组本身。
forEach()   //遍历数组的所有成员,执行某种操作,参数是一个函数。它接受三个参数,分别是当前位置的值、当前位置的编号和整个数组。
filter()   //参数是一个函数,所有数组成员依次执行该函数,返回结果为true的成员组成一个新数组返回。该方法不会改变原数组。
some()    //用来判断数组成员是否符合某种条件。接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值。该函数接受三个参数,依次是当前位置的成员、当前位置的序号和整个数组。只要有一个数组成员的返回值是true,则整个some方法的返回值就是true,否则false。
every()   //用来判断数组成员是否符合某种条件。接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值。该函数接受三个参数,依次是当前位置的成员、当前位置的序号和整个数组。所有数组成员的返回值都是true,才返回true,否则false。
reduce()   //依次处理数组的每个成员,最终累计为一个值。从左到右处理(从第一个成员到最后一个成员)
reduceRight()  //依次处理数组的每个成员,最终累计为一个值。从右到左(从最后一个成员到第一个成员)
indexOf(s)   //返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1。可以接受第二个参数,表示搜索的开始位置
lastIndexOf()  //返回给定元素在数组中最后一次出现的位置,如果没有出现则返回-1。
3.3 Number对象
(1)生成对象
var n = new Number()
(2)Number对象的属性
Number.POSITIVE_INFINITY:正的无限,指向Infinity。  
Number.NEGATIVE_INFINITY:负的无限,指向-Infinity。  
Number.NaN:表示非数值,指向NaN。  
Number.MAX_VALUE:表示最大的正数,相应的,最小的负数为-Number.MAX_VALUE。  
Number.MIN_VALUE:表示最小的正数(即最接近0的正数,在64位浮点数体系中为5e-324),相应的,最接近0的负数为-Number.MIN_VALUE。  
Number.MAX_SAFE_INTEGER:表示能够精确表示的最大整数,即9007199254740991。  
Number.MIN_SAFE_INTEGER:表示能够精确表示的最小整数,即-9007199254740991。
(4)Number对象实例的方法
toString()   //用来将一个数值转为字符串形式.可以接受一个参数,表示输出的进制。如果省略这个参数,默认将数值先转为十进制,再输出字符串;否则,就根据参数指定的进制,将一个数字转化成某个进制的字符串。
toFixed()   //用于将一个数转为指定位数的小数,返回这个小数对应的字符串。
toExponential()  //用于将一个数转为科学计数法形式。可传入一个参数,参数表示小数点后有效数字的位数,范围为0到20,超出这个范围,会抛出一个RangeError。
toPrecision()  //用于将一个数转为指定位数的有效数字。
3.4 String 对象
(1)生成实例对象
var s = new String()
(2)String对象的属性
s.length   //返回字符串的长度
(3)方法
s.chatAt(index)   //返回指定位置的字符    //"123456"[0] == "1"
s.fromCharCode()    //该方法的参数是一系列Unicode码点,返回对应的字符串。
s.charCodeAt(index)    //返回给定位置字符的Unicode码点(十进制表示)
s.concat(s2)  //用于连接两个字符串
s.slice(start,end)   //用于从原字符串取出子字符串并返回,不改变原字符串。第一个参数是子字符串的开始位置,第二个参数是子字符串的结束位置(不含该位置)。如果参数是负值,表示从结尾开始倒数计算的位置,即该负值加上字符串长度。
s.substring(start,end)  //用于从原字符串取出子字符串并返回,不改变原字符串.第一个参数表示子字符串的开始位置,第二个位置表示结束位置。
s.substr(start,length)   //用于从原字符串取出子字符串并返回,不改变原字符串。第一个参数是子字符串的开始位置,第二个参数是子字符串的长度。如果第一个参数是负数,表示倒数计算的字符位置。如果第二个参数是负数,将被自动转为0,因此会返回空字符串。
s.indexOf(s)   //返回给定元素在字符串中第一次出现的位置,如果没有出现则返回-1。可以接受第二个参数,表示搜索的开始位置 
s.lastIndexOf()  //返回给定元素在字符串中最后一次出现的位置,如果没有出现则返回-1。
s.trim()  //用于去除字符串两端的空格,返回一个新字符串
s.toLowerCase()  //用于将一个字符串全部转为小写,返回一个新字符串,不改变原字符串。
s.toUpperCase()  //全部转为大写
s.localeCompare(s2)  //用于比较两个字符串。它返回一个整数,如果小于0,表示第一个字符串小于第二个字符串;如果等于0,表示两者相等;如果大于0,表示第一个字符串大于第二个字符串。
s.match(regexp)   //用于确定原字符串是否匹配某个子字符串,返回一个数组,成员为匹配的第一个字符串。如果没有找到匹配,则返回null。
s.search()  //返回值为匹配的第一个位置。如果没有找到匹配,则返回-1。
s.replace(oldValue,newValue)  //用于替换匹配的子字符串,一般情况下只替换第一个匹配(除非使用带有g修饰符的正则表达式)。
s.split()  //按照给定规则分割字符串,返回一个由分割出来的子字符串组成的数组。还可传入第二个参数,决定了返回数组的成员数。
3.5 Math对象
(1)属性
Math.E:常数e。  
Math.LN2:2的自然对数。  
Math.LN10:10的自然对数。  
Math.LOG2E:以2为底的e的对数。  
Math.LOG10E:以10为底的e的对数。  
Math.PI:常数Pi。  
Math.SQRT1_2:0.5的平方根。  
Math.SQRT2:2的平方根。
(2)数学方法
Math.abs():返回参数的绝对值  
Math.ceil():向上取整,接受一个参数,返回大于该参数的最小整数。 
Math.floor():向下取整  
Math.max(n,n1,...):可接受多个参数,返回最大值  
Math.min(n,n1,..):可接受多个参数,返回最小值  
Math.pow(n,e):指数运算, 返回以第一个参数为底数、第二个参数为幂的指数值。 
Math.sqrt():返回参数值的平方根。如果参数是一个负值,则返回NaN。  
Math.log():返回以e为底的自然对数值。
Math.exp():返回e的指数,也就是常数e的参数次方。
Math.round():四舍五入  
Math.random():返回0到1之间的一个伪随机数,可能等于0,但是一定小于1。
(3)三角函数方法
Math.sin():返回参数的正弦  
Math.cos():返回参数的余弦  
Math.tan():返回参数的正切  
Math.asin():返回参数的反正弦(弧度值)  
Math.acos():返回参数的反余弦(弧度值)  
Math.atan():返回参数的反正切(弧度值)
3.6 JSON对象
(1)方法
JSON.stringify()   
//用于将一个值转为字符串。该字符串应该符合JSON格式,并且可以被JSON.parse方法还原。
//(JSON.stringify(obj, selectedProperties))还可以接受一个数组,作为第二个参数,指定需要转成字符串的属性。
//还可以接受第三个参数,用于增加返回的JSON字符串的可读性。如果是数字,表示每个属性前面添加的空格(最多不超过10个);如果是字符串(不超过10个字符),则该字符串会添加在每行前面。

JSON.parse()   //用于将JSON字符串转化成对象。
3.7 console对象
(1)方法
console.log(text,text2,...)   //用于在console窗口输出信息。它可以接受多个参数,将它们的结果连接起来输出。如果第一个参数是格式字符串(使用了格式占位符),console.log方法将依次用后面的参数替换占位符,然后再进行输出。
console.info()   //在console窗口输出信息,同时,会在输出信息的前面,加上一个蓝色图标。
console.debug()  //在console窗口输出信息,同时,会在输出信息的前面,加上一个蓝色图标。
console.warn()  //输出信息时,在最前面加一个黄色三角,表示警告;
console.error()  //输出信息时,在最前面加一个红色的叉,表示出错,同时会显示错误发生的堆栈
console.table()  //可以将复合类型的数据转为表格显示。
console.count()  //用于计数,输出它被调用了多少次。
console.dir()    //用来对一个对象进行检查(inspect),并以易于阅读和打印的格式显示。
console.dirxml()  //用于以目录树的形式,显示DOM节点。
console.assert()  //接受两个参数,第一个参数是表达式,第二个参数是字符串。只有当第一个参数为false,才会输出第二个参数,否则不会有任何结果。

//这两个方法用于计时,可以算出一个操作所花费的准确时间。
console.time()
console.timeEnd()
//time方法表示计时开始,timeEnd方法表示计时结束。它们的参数是计时器的名称。调用timeEnd方法之后,console窗口会显示“计时器名称: 所耗费的时间”。

console.profile()  //用来新建一个性能测试器(profile),它的参数是性能测试器的名字。
console.profileEnd()  //用来结束正在运行的性能测试器。

console.group()
console.groupend()
//上面这两个方法用于将显示的信息分组。它只在输出大量信息时有用,分在一组的信息,可以用鼠标折叠/展开。
console.groupCollapsed()  //用于将显示的信息分组,该组的内容,在第一次显示时是收起的(collapsed),而不是展开的。

console.trace()  //显示当前执行的代码在堆栈中的调用路径。
console.clear()  //用于清除当前控制台的所有输出,将光标回置到第一行。


正则表达式:
只允许输入汉字:onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')" 
只允许输入数字:onkeyup="this.value=this.value.replace(/\D/g,'')"
[1, [2, [3, 4]]].toString() // "1,2,3,4"
0、常用选择器
$('#div1')   //id为div1的节点,如<div id='div1'></div> 

$('span')   //所有的span结点,一个包装集
$('p span')   //p标签下的所有span节点,后代节点
$('p>span')   //p标签下的所有span子节点,子代节点

$('.red')  //使用样式red的节点,如<span class="red"></span>

$('*')  //所有节点

$("div,span,p.cls")  //选取所有<div>,<span>和拥有class为cls的<p>标签的一组元素


1、基本筛选器
$('span:first')    //第一个节点
$('span:last')     //最后一个节点

$("td:even")     //索引为偶数的节点,从 0 开始
$("td:odd")      //索引为奇数的节点,从 0 开始
 
$("td:eq(1)")    //给定索引值的节点
$("td:gt(0)")    //大于给定索引值的节点
$("td:lt(2)")    //小于给定索引值的节点

$(":focus")      //当前获取焦点的节点
$(":animated")   //正在执行动画效果的节点


2、内容选择器
$("div:contains('hello')")    //包含hello文本的节点
$("td:empty")    //不包含子节点或者文本的空节点
$("div:has(p)")  //含有选择器所匹配的节点
$("td:parent")   //含有子节点或者文本的节点


3、表单选择器
$("input:checked")    //所有选中的节点
$("select option:selected")    //select中所有选中的option节点

$(":input")      //匹配所有 input, textarea, select 和 button 节点
$(":text")       //所有的单行文本框
$(":password")   //所有密码框
$(":radio")      //所有单选按钮
$(":checkbox")   //所有复选框
$(":submit")     //所有提交按钮
$(":reset")      //所有重置按钮
$(":button")     //所有button按钮
$(":file")       //所有文件域


4、筛选与查找
$("p").eq(0)       //当前操作中第N个jQuery对象,类似索引
$('li').first()    //第一个节点
$('li').last()     //最后一个节点
$(this).hasClass("node")    //节点是否含有某个特定的类,返回布尔值
$('li').has('ul')  //包含特定后代的节点

$("div").children()      //div中的每个子节点,第一层
$("div").find("span")    //查找div下的所有span节点

$("p").next()          //紧邻p节点后的一个同辈节点
$("p").nextAll()         //p节点之后所有的同辈节点
$("#node").nextUntil("#node2")    //id为"#node"节点之后到id为'#node2'之间所有的同辈节点,掐头去尾

$("p").prev()            //紧邻p节点前的一个同辈节点
$("p").prevAll()         //p节点之前所有的同辈节点
$("#node").prevUntil("#node2")    //id为"#node"节点之前到id为'#node2'之间所有的同辈节点,掐头去尾

$("p").parent()          //每个p节点的父节点
$("p").parents()         //每个p节点的所有祖先节点,body,html
$("#node").parentsUntil("#node2")    //id为"#node"节点到id为'#node2'之间所有的父级节点,掐头去尾

$("div").siblings()      //所有的同辈节点,不包括自己


5、属性操作
$("img").attr("src");           //返回文档中所有图像的src属性值
$("img").attr("src","node.jpg");    //设置所有图像的src属性
$("img").removeAttr("src");       //将文档中图像的src属性删除

$("input[type='checkbox']").prop("checked", true);    //选中复选框
$("input[type='checkbox']").prop("checked", false);   //不选中复选框
$("img").removeProp("src");       //删除img的src属性


6、样式操作
$("p").addClass("selected");      //为p节点加上 'selected' 类
$("p").removeClass("selected");    //从p节点中删除 'selected' 类
$("p").toggleClass("selected");    //如果存在就删除,否则就添加HTML代码/文本/值


7、内容操作
$('p').html();               //返回p节点的html内容
$("p").html("Hello <b>hello</b>!");  //设置p节点的html内容
$('p').text();               //返回p节点的文本内容
$("p").text("hello");           //设置p节点的文本内容
$("input").val();             //获取文本框中的值
$("input").val("hello");          //设置文本框中的内容
 

8、CSS操作
$("p").css("color");          //访问查看p节点的color属性
$("p").css("color","red");    //设置p节点的color属性为red
$("p").css({ "color": "red", "background": "yellow" });    //设置p节点的color为red,background属性为yellow(设置多个属性要用{}字典形式)


9、定位与偏移
$('p').offset()     //节点在当前视口的相对偏移,对象 {top: 5, left: 9}
$('p').offset().top
$('p').offset().left
$("p").position()   //节点相对父节点的偏移,对可见节点有效,Object {top: 5, left: 8}

$(window).scrollTop()    //获取滚轮滑的高度
$(window).scrollLeft()   //获取滚轮滑的宽度
$(window).scrollTop('25')    //设置滚轮滑的高度为25


10、尺寸
$("p").height();    //获取p节点的高度
$("p").width();     //获取p节点的宽度

$("p:first").innerHeight()    //获取第一个匹配节点内部区域高度(包括补白、不包括边框)
$("p:first").innerWidth()     //获取第一个匹配节点内部区域宽度(包括补白、不包括边框)

$("p:first").outerHeight()    //匹配节点外部高度(默认包括补白和边框)
$("p:first").outerWidth()     //匹配节点外部宽度(默认包括补白和边框)
$("p:first").outerHeight(true)    //为true时包括边距


11、DOM内部插入
$("p").append("<b>hello</b>");    //每个p节点内后面追加内容
$("p").appendTo("div");        //p节点追加到div内后
$("p").prepend("<b>Hello</b>");  //每个p节点内前面追加内容
$("p").prependTo("div");        //p节点追加到div内前


12、DOM外部插入
$("p").after("<b>hello</b>");     //每个p节点同级之后插入内容
$("p").before("<b>hello</b>");    //在每个p节点同级之前插入内容
$("p").insertAfter("#node");     //所有p节点插入到id为node节点的后面
$("p").insertBefore("#node");    //所有p节点插入到id为node节点的前面


13、DOM替换
$("p").replaceWith("<b>Paragraph. </b>");    //将所有匹配的节点替换成指定的HTML或DOM节点
$("<b>Paragraph. </b>").replaceAll("p");     //用匹配的节点替换掉所有 selector匹配到的节点


14、DOM删除
$("p").empty();     //删除匹配的节点集合中所有的子节点,不包括本身
$("p").remove();    //删除所有匹配的节点,包括本身
$("p").detach();    //删除所有匹配的节点(和remove()不同的是:所有绑定的事件、附加的数据会保留下来)


15、DOM复制
$("p").clone()      //克隆节点并选中克隆的副本
$("p").clone(true)   //布尔值指事件处理函数是否会被复制
 

16、DOM加载完成事件
$(document).ready(function(){
  您的代码...
});

//缩写
$(function($) {
  您的代码...
});


17、绑定事件
//bind 为每个匹配节点绑定事件处理函数,绑定多个用{}。
$("p").bind("click", function(){
  alert( $(this).text() );
});
$('#div1').bind({
    "mouseover":function () {
     $('#div1').parent().removeClass("hide");
     },"mouseout":function () {
     $('#div1').parent().addClass("hide");
}
});         

$("p").one( "click", function(){})    //事件绑定后只会执行一次
$("p").unbind( "click" )        //反绑一个事件

// 与bind 不同的是当时间发生时才去临时绑定。
$("p").delegate("click",function(){
  您的代码
});

$("p").undelegate();       //p节点删除由 delegate() 方法添加的所有事件
$("p").undelegate("click")   //从p节点删除由 delegate() 方法添加的所有click事件

$("p").click();      //单击事件
$("p").dblclick();    //双击事件
$("input[type=text]").focus()  //节点获得焦点时,触发 focus 事件
$("input[type=text]").blur()   //节点失去焦点时,触发 blur事件
$("button").mousedown()//当按下鼠标时触发事件
$("button").mouseup()  //节点上放松鼠标按钮时触发事件
$("p").mousemove()     //当鼠标指针在指定的节点中移动时触发事件
$("p").mouseover()     //当鼠标指针位于节点上方时触发事件
$("p").mouseout()     //当鼠标指针从节点上移开时触发事件
$(window).keydown()    //当键盘或按钮被按下时触发事件
$(window).keypress()   //当键盘或按钮被按下时触发事件,每输入一个字符都触发一次
$("input").keyup()     //当按钮被松开时触发事件
$(window).scroll()     //当用户滚动时触发事件
$(window).resize()     //当调整浏览器窗口的大小时触发事件
$("input[type='text']").change()    //当节点的值发生改变时触发事件
$("input").select()    //当input 节点中的文本被选择时触发事件
$("form").submit()     //当提交表单时触发事件
$(window).unload()     //用户离开页面时


18、事件对象
$("p").click(function(event){  
 alert(event.type); //"click"  
}); 

(evnet object)属性方法:
event.pageX   //事件发生时,鼠标距离网页左上角的水平距离
event.pageY   //事件发生时,鼠标距离网页左上角的垂直距离
event.type   //事件的类型
event.which   //按下了哪一个键
event.data   //在事件对象上绑定数据,然后传入事件处理函数
event.target  //事件针对的网页节点
event.preventDefault()  //阻止事件的默认行为(比如点击链接,会自动打开新页面)
event.stopPropagation()  //停止事件向上层节点冒泡


19、动态事件绑定
 $("p").on("click",'span',function(){
alert( $(this).text() );
});
//当p中增加span时仍然有效


20、动画效果
$("p").show()        //显示隐藏的匹配节点
$("p").show("slow");    //参数表示速度,("slow","normal","fast"),也可为600毫秒
$("p").hide()        //隐藏显示的节点
$("p").toggle();      //切换 显示/隐藏

$("p").slideDown("600");    //用600毫秒时间将段落滑下
$("p").slideUp("600");     //用600毫秒时间将段落滑上
$("p").slideToggle("600");  //用600毫秒时间将段落滑上,滑下淡入淡出

$("p").fadeIn("600");        //用600毫秒时间将段落淡入
$("p").fadeOut("600");       //用600毫秒时间将段落淡出
$("p").fadeToggle("600");     //用600毫秒时间将段落淡入,淡出
$("p").fadeTo("slow", 0.6);    //用600毫秒时间将段落的透明度调整到0.6
 

21、工具方法
$("#form1").serialize()    //序列表表格内容为字符串。
$("select, :radio").serializeArray();  //序列化表单元素为数组返回 JSON 数据结构数据
$.trim()   //去除字符串两端的空格
$.each()   //遍历一个数组或对象,for循环
$.inArray() //返回一个值在数组中的索引位置,不存在返回-1  
$.grep()   //返回数组中符合某种标准的节点
$.extend({a:1,b:2},{b:3,c:4},{c:5:d:6})  //将多个对象,合并到第一个对象{a:1,b:3,c:5,d:6}
$.makeArray() //将对象转化为数组
$.type()    //判断对象的类别(函数对象、日期对象、数组对象、正则对象等等
$.isArray() //判断某个参数是否为数组
$.isEmptyObject() //判断某个对象是否为空(不含有任何属性)
$.isFunction()    //判断某个参数是否为函数
$.isPlainObject() //判断某个参数是否为用"{}"或"new Object"建立的对象
$.support()       //判断浏览器是否支持某个特性

22、AJAX
//保存数据到服务器,成功时显示信息
$.ajax({
   type: "POST",
   url: "some.php",
   data: "name=John&location=Boston",
   success: function(msg){
     alert( "Data Saved: " + msg );
   }
});

//加载 feeds.html 文件内容。
$("#feeds").load("feeds.html");

//请求 test.php 网页,传送2个参数,忽略返回值。
$.get("test.php", { name: "John", time: "2pm" } );

//从 Flickr JSONP API 载入 4 张最新的关于猫的图片。
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format
=json&jsoncallback=?", function(data){
  $.each(data.items, function(i,item){
    $("<img/>").attr("src", item.media.m).appendTo("#images");
    if ( i == 3 ) return false;
  });
});

//加载并执行 test.js ,成功后显示信息
$.getScript("test.js", function(){
  alert("Script loaded and executed.");
});

//向页面 test.php 发送数据,并输出结果(HTML 或 XML,取决于所返回的内容):
$.post("test.php", { name: "John", time: "2pm" },
   function(data){
     alert("Data Loaded: " + data);
   });
   
//AJAX 请求完成时执行函数。
 $("#msg").ajaxComplete(function(event,request, settings){
   $(this).append("<li>请求完成.</li>");
 });
 
//AJAX 请求失败时显示信息。
$("#msg").ajaxError(function(event,request, settings){
     $(this).append("<li>出错页面:" + settings.url + "</li>");
});

//AJAX 请求发送前显示信息。
 $("#msg").ajaxSend(function(evt, request, settings){
   $(this).append("<li>开始请求: " + settings.url + "</li>");
 });
 
 //AJAX 请求开始时显示信息。
 $("#loading").ajaxStart(function(){
   $(this).show();
 });
 
//AJAX 请求结束后隐藏信息。
 $("#loading").ajaxStop(function(){
   $(this).hide();
 });
 
//当 AJAX 请求成功后显示消息。
 $("#msg").ajaxSuccess(function(evt, request, settings){
   $(this).append("<li>请求成功!</li>");
 });
 
//请求前过滤
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) { 
   // Modify options, control originalOptions, store jqXHR, etc 
 });
 
 //设置全局 AJAX 默认选项,设置 AJAX 请求默认地址为 "/xmlhttp/",禁止触发全局 AJAX 事件,用 POST 代替默认 GET 方法。其后的 AJAX 请求不再设置任何选项参数。
$.ajaxSetup({
  url: "/xmlhttp/",
  global: false,
  type: "POST"
});
$.ajax({ data: myData });






JavaScript中巧用位运算
日常前端开发中我们很少用到位运算,容易让人遗忘,让我们一起回顾下一下js中的位运算。
位运算详细说明查看JavaScript|MDN
下面主要回顾一下一些常用的位运算的巧用。
将十进制转化为二进制
var number = 3;
var result = number.toString(2);

var result2 = 14..toString(2); // "1110"


我们使用位运算来代替Math.floor()来向下取整
var data = 2.2352524535;
var result = data | 0; // 2


var re2 = ~~data; // 2

将颜色从RGA转换为Hex格式

var color = {r: 186, g: 218, b: 85};

// RGB to HEX
var rgb2hex = function(r, g, b) {
    return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).substr(1);
}
rgb2hex(color.r, color.g, color.b);//"#bada55"

区分两个数的大小
// variables
var a = 9285;
var b = 3569;

// 取大
var max = a ^ ((a ^ b) & -(a < b));//9285;

// 取小
var min =  b ^ ((a ^ b) & -(a < b);//3569

交换变量
var a = 10;
var b = 99;

a = (b^=a^=b)^a;

console.log(a) // 99
console.log(b) // 10

判断正负
function isPos(n) {
  return (n === (n >>> 0)) ? true : false;  
}
isPos(-1); // false
isPos(1); // true

Document

每个在浏览器中加载的页面都有一个document对象。通过document对象可以访问页面的内容(比如dom树,和内部的元素)

document对象可以由以下几种方法获取

1. 通常情况下直接使用`document`或`window.document`取得`document`对象
2. 通过iframe的`contentDocument`属性获取
3. The responseXML of an XMLHttpRequest object
4. 通过`node`或`element`对象的`ownerDocument`属性获取

所有的document对象都是通过Document接口实现的

PropertiesDocument.body

返回当前文档的<body><frameset>元素,如果元素不存在则返回null

<body id="oldBodyElement"></body>

例(在页面加载完成后执行):

alert(document.body.id);    //'oldBodyElement'

// 创建一个新的body元素
var aNewBodyElement = document.createElement("body");
aNewBodyElement.id = "newBodyElement";

// 把创建好的body元素赋给document.body
document.body = aNewBodyElement;
alert(document.body.id);    //"newBodyElement"

给文档设置一个新的body需要先删除已经存在的<body>元素

Document.documentElement

它是一个只读属性,返回文档的根节点元素(例如对于html文档来说,返回的是<html>元素)

例:

var rootElement = document.documentElement;
var firstTier = rootElement.childNodes;

// 遍历根节点的直接子元素
for (var i = 0; i < firstTier.length; i++) {
   // 对每一个直接子元素做些事情
   // as firstTier[i]
}

Notes:

* 这个属性可以很方便的获取文档的直接子元素
* html文档只包含一个子节点`<html>`,xml文档通常会包含多个子节点。
* 通常要使用`document.documentElement`而不是`document.firstChild`去获取根节点元素

Document.forms

返回当前文档中form元素的集合(一个HTMLCollection对象)

例:

<body>
<form id="robby">
    <input type="button" onclick="alert(document.forms[0].id);" value="robby's form" />
</form>

<form id="dave">
    <input type="button" onclick="alert(document.forms[1].id);" value="dave's form" />
</form>

<form id="paul">
    <input type="button" onclick="alert(document.forms[2].id);" value="paul's form" />
</form>
</body>
var forms = document.forms;
alert(forms.length);    //3
var form1 = forms[0];   //取得第一个form元素

Document.head

返回当前文档的<head>元素,如果文档中大于一个<head>元素,返回第一个元素。

Notes:

这个属性是只读的,试图给这个属性赋值都会出错。

Document.images

返回当前文档image元素的集合

例子:

var ilist = document.images;

for(var i = 0; i < ilist.length; i++) {
    if(ilist[i].src == "banner.gif") {
        // found the banner
    }
}

Notes:

* document.images.length返回当前页面的图片数
* document.images它是html dom的一部分,只工作在html中

Document.scripts

返回文档的script元素列表(是一个HTMLCollection对象)

例子:

var scripts = document.scripts;

if (scripts.length) {
    alert("This page has scripts!");
}

Document.title

获取或设置文档的标题

例子:

<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title> 
</head>
<body>

<script>
alert(document.title); // displays "Hello World!"
document.title = "Goodbye World!";
alert(document.title); // displays "Goodbye World!"
</script>

</body>
</html>

Document.anchors

返回文档中的锚点列表

例子:

<h1>Title</h1>
<h2><a name="contents">Contents</a></h2>
<h2><a name="plants">Plants</a></h2>
<h2><a name="veggies">Veggies</a></h2>
// document.anchors返回一个数组包含3个值,[<a name="contents">Contents</a>, <a name="plants">Plants</a>, <a name="veggies">Veggies</a>]
alert(document.anchors.length); //3

Notes:

返回的锚点集合中只包含带有name属性的<a>,并不包含使用id属性创建的锚点(<a>标签的name属性在html5已经不支持,html5推荐使用id属性来设置锚点)

Document.links

links属性返回文档中带href属性的<area>元素和<a>元素的集合

<a href="http://baidu.com">baidu</a>
<a href="http://taobao.com">taobao</a>
<area shape="" coords="" href="" alt=""/>
alert(document.links.length);     //3

Document.location

Document.location是一个只读属性,返回一个Location对象,它包含了当前文档URL的信息以及提供了一些方法来改变URL地址或者是加载另一个URL

Document.URL

返回当前文档的url,但不能设置url

document.location = 'http://www.mozilla.org';   //Equivalent to
document.location.href = 'http://www.mozilla.org';

Document.referrer

返回链接到当前文档的url(之前link过来的路径)

Document.domain

获取或设置文档的域名

Document.activeElement

返回当前文档焦点所在的元素

Example

<input type="text">
var input = document.querySelector('input');
input.focus();
console.log(document.activeElement === input);  //true

注:当文档加载完成后,document.activeElement 返回document.body,在文档加载期间document.activeElement是null.

Document.readyState

当文档正在加载时返回"loading",解析完成但仍然加载资源返回"interactive",所有的资源全部加载完成返回"complete"。

document.onreadystatechange = function () {
    if (document.readyState === 'complete') {
        console.log('complete');
    }

    if (document.readyState === 'interactive') {
        console.log('interactive');
    }
};

// output
// interactive
// complete

readystatechange事件当readyState属性改变时触发。

Document.cookie

设置或读取当前文档的cookie

  • 读取所有cookie: allCookies = document.cookie;读取后的cookie是一个键值对的字符串

  • 设置新的cookie: document.cookie = newCookie;

Document.defaultView

返回文档对应的window对象

MethodsDocument.getElementById()

通过元素id返回元素的引用,如果在文档中找不到id,返回null(id是大小写敏感的)

Document.getElementsByTagName()

根据标签名返回元素的集合(一个HTMLCollection对象)

Document.getElementsByName()

根据节点的属性name值返回元素的集合(一个NodeList对象)

Example

<div id="div1" name="test"></div>
<div id="div2" name="test"></div>
<div id="div3" name="test"></div>
// 返回一个HTMLCollection对象
var divs = document.getElementsByTagName('div');
console.log(divs);

// 返回一个NodeList对象
var names = document.getElementsByName('test');
console.log(names);

// divs[0]和names[0]都返回了第一个div元素的引用
console.log(divs[0] === names[0]);

Document.getElementsByClassName()

根据类名返回元素的集合(一个类数组的对象HTMLCollection),当作用在document上,将搜索整个文档的。也可以通过element.getElementsByClassName()作用在指定的节点元素上查找。

var elements = document.getElementsByClassName(names); // or:
var elements = rootElement.getElementsByClassName(names);
  • elements是一个动态元素的集合。
  • names要查找的类名的字符串,如果有多个类名时,需要用空格分开。
  • getElementsByClassName可以作用在任意元素上,不仅仅是document对象

Example1

// Get all elements that have a class of 'test'
document.getElementsByClassName('test');

// Get all elements that have both the 'red' and 'test' classes
document.getElementsByClassName('red test');

// Get all elements that have a class of 'test', inside of an element that has the ID of 'main'
document.getElementById('main').getElementsByClassName('test');

Example2

<ul>
    <li class="test"></li>
    <li class="test"></li>
    <li class="test"></li>
</ul>
var lis = document.getElementsByClassName('test');

console.log(lis.length);   //3
console.log(lis instanceof HTMLCollection);  //true

Document.querySelector()

通过匹配css选择器,返回第一个匹配的元素。

var element = document.querySelector(selectors);
  • element 是返回的一个元素对象
  • selectors 是一组匹配的选择器

Example

<ul>
    <li class="test" id="l1"></li>
    <li class="test" id="l2"></li>
    <li class="test" id="l3"></li>
    <li class="test" id="l4"></li>
    <li class="test" id="l5"></li>
</ul>
var ul = document.querySelector('.test');   // equal to "document.querySelector('#l1')"
console.log(ul);    //<li class="test" id="l1"></li>

Document.querySelectorAll()

通过匹配css选择器返回NodeList对象

Example1

<ul>
    <li class="test"></li>
    <li class="test"></li>
    <li class="test"></li>
    <li class="test"></li>
    <li class="test"></li>
</ul>
var uls = document.querySelectorAll('.test');
console.log(uls.length);    //5

Example2 返回div元素带有calss为'note'或'alert'元素的集合

var matches = document.querySelectorAll("div.note, div.alert");

Document.createElement()

创建一个html元素

var element = document.createElement(tagName);
  • element 创建后的元素对象
  • tagName 要创建元素的标签名

Document.createTextNode()

创建一个文本节点

var text = document.createTextNode(data);
  • text 创建后的文本节点
  • data 文本字符串

Document.createAttribute()

创建一个属性节点

attribute = document.createAttribute(name)
  • attribute 创建的属性节点.
  • name 属性名.

Example

初始html为:

<div>
    <span id="childSpan">foo bar</span>
</div>
var sp1 = document.createElement('span');
sp1.setAttribute('id', 'newSpan');

// 创建属性节点a,属性名为myattr
var a = document.createAttribute('myattr');
// 设置属性值为my_value
a.value = 'my_value';
// 通过setAttributeNode设置节点属性
sp1.setAttributeNode(a);

var sp1_content = document.createTextNode('new replacement span element.');
sp1.appendChild(sp1_content);

var sp2 = document.getElementById('childSpan');
var parentDiv = sp2.parentNode;

parentDiv.appendChild(sp1);

现在html为:

<div>
    <span id="childSpan">foo bar</span>
    <span id="newSpan" myattr="my_value">new replacement span element.</span>
</div>

Document.hasFocus()

指示文档或文档中的任何元素是否处于焦点状态。这个方法用来检查在文档中是否有焦点元素

Example

<p>Click anywhere in the document (the right frame) to get focus. If you click outside the document, it will lose focus.</p>

<p id="demo"></p>
setInterval(myFunction, 1);

function myFunction() {
    var x = document.getElementById("demo");
    if (document.hasFocus()) {
        x.innerHTML = "The document has focus.";
    } else {
        x.innerHTML = "The document DOES NOT have focus.";
    }
}

Document.createDocumentFragment()

创建一个空的文档片段

多次使用节点方法(如:appendChild)绘制页面,每次都要刷新页面一次。效率也就大打折扣了,而使用document.createDocumentFragment()创建一个文档碎片,把所有的新结点附加在其上,然后把文档碎片的内容一次性添加到document中,这也就只需要一次页面刷新就可

var ul = document.getElementsByTagName('ul')[0];
var docfrag = document.createDocumentFragment();
var browserList = ["Internet Explorer", "Mozilla Firefox", "Safari", "Chrome", "Opera"];
browserList.forEach(function (item) {
  var li = document.createElement('li');
  li.textContent = item;
  docfrag.appendChild(li);
});
ul.appendChild(docfrag);

 

 

Js 数组——filter()、map()、some()、every()、forEach()、lastIndexOf()、indexOf()

filter():  

 语法:

var filteredArray = array.filter(callback[, thisObject]);

参数说明:

callback: 要对每个数组元素执行的回调函数。
thisObject : 在执行回调函数时定义的this对象。

//过滤掉小于 10 的数组元素:

//代码:
function isBigEnough(element, index, array) {
    return (element >= 10);
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// 12, 130, 44
//结果:[12, 5, 8, 130, 44].filter(isBigEnough) : 12, 130, 44 

功能说明:

对数组中的每个元素都执行一次指定的函数(callback),并且创建一个新的数组,该数组元素是所有回调函数执行时返回值为 true 的原数组元素。它只对数组中的非空元素执行指定的函数,没有赋值或者已经删除的元素将被忽略,同时,新创建的数组也不会包含这些元素。

回调函数可以有三个参数:当前元素,当前元素的索引和当前的数组对象。

如参数 thisObject 被传递进来,它将被当做回调函数(callback)内部的 this 对象,如果没有传递或者为null,那么将会使用全局对象。

filter 不会改变原有数组,记住:只有在回调函数执行前传入的数组元素才有效,在回调函数开始执行后才添加的元素将被忽略,而在回调函数开始执行到最后一个元素这一期间,数组元素被删除或者被更改的,将以回调函数访问到该元素的时间为准,被删除的元素将被忽略。

map():

//将所有的数组元素转换为大写:

var strings = ["hello", "Array", "WORLD"];
function makeUpperCase(v)
{
    return v.toUpperCase();
}
var uppers = strings.map(makeUpperCase);
// uppers is now ["HELLO", "ARRAY", "WORLD"]
// strings is unchanged
//结果:["hello", "Array", "WORLD"].map(makeUpperCase) : HELLO, ARRAY, WORLD 

some():

对数组中的每个元素都执行一次指定的函数(callback),直到此函数返回 true,如果发现这个元素,some 将返回 true,如果回调函数对每个元素执行后都返回 false ,some 将返回 false。它只对数组中的非空元素执行指定的函数,没有赋值或者已经删除的元素将被忽略。

//检查是否有数组元素大于等于10:

function isBigEnough(element, index, array) {
    return (element >= 10);
}
var passed = [2, 5, 8, 1, 4].some(isBigEnough);
// passed is false
passed = [12, 5, 8, 1, 4].some(isBigEnough);
// passed is true
//结果:
//[2, 5, 8, 1, 4].some(isBigEnough) : false 
//[12, 5, 8, 1, 4].some(isBigEnough) : true 

every():

对数组中的每个元素都执行一次指定的函数(callback),直到此函数返回 false,如果发现这个元素,every 将返回 false,如果回调函数对每个元素执行后都返回 true ,every 将返回 true。它只对数组中的非空元素执行指定的函数,没有赋值或者已经删除的元素将被忽略

//测试是否所有数组元素都大于等于10:

function isBigEnough(element, index, array) {
    return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed is false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// passed is true
//结果:
//[12, 5, 8, 130, 44].every(isBigEnough) 返回 : false 
//[12, 54, 18, 130, 44].every(isBigEnough) 返回 : true 

forEach():

//打印数组内容:

function printElt(element, index, array) {
    document.writeln("[" + index + "] is " + element + "<br />");
}
[2, 5, 9].forEach(printElt);
// Prints:
// [0] is 2
// [1] is 5
// [2] is 9
//结果:
//[0] is 2
//[1] is 5
//[2] is 9

lastIndexOf():

语法

var index = array.lastIndexOf(searchElement[, fromIndex]);

参数说明

searchElement: 要搜索的元素

fromIndex : 开始搜索的位置,默认为数组的长度(length),在这样的情况下,将搜索所有的数组元素。搜索是反方向进行的。

功能说明

比较 searchElement 和数组的每个元素是否绝对一致(===),当有元素符合条件时,返回当前元素的索引。如果没有发现,就直接返回 -1 。

//查找符合条件的元素:

var array = [2, 5, 9, 2];
var index = array.lastIndexOf(2);
// index is 3
index = array.lastIndexOf(7);
// index is -1
index = array.lastIndexOf(2, 3);
// index is 3
index = array.lastIndexOf(2, 2);
// index is 0
index = array.lastIndexOf(2, -2);
// index is 0
index = array.lastIndexOf(2, -1);
// index is 3
//结果:
//[2, 5, 9, 2].lastIndexOf(2) : 3 
//[2, 5, 9, 2].lastIndexOf(7) : -1 
//[2, 5, 9, 2].lastIndexOf(2, 3) : 3 
//[2, 5, 9, 2].lastIndexOf(2, 2) : 0 
//[2, 5, 9, 2].lastIndexOf(2, -2) : 0 
//[2, 5, 9, 2].lastIndexOf(2, -1) : 3 

indexOf():

功能与lastIndexOf()一样,搜索是正向进行的

//查找符合条件的元素:

var array = [2, 5, 9];
var index = array.indexOf(2);
// index is 0
index = array.indexOf(7);
// index is -1
//结果:
//[2, 5, 9].indexOf(2) : 0 
//[2, 5, 9].indexOf(7) : -1 

JavaScript中提供了多种数组方法,如下:

  1. 转换方法—toLocaleString()方法、toString()方法、valueOf()方法
  2. 栈方法——push()方法、pop()方法
  3. 队列方法——shift()方法、unshift()方法
  4. 重排序方法——reverse()方法、sort()方法
  5. 操作方法——concat()方法、slice()方法、splice()方法
  6. 位置方法——indexOf()方法、lastIndexOf()方法
  7. 迭代方法——every()方法、filter()方法、forEach()方法、map()方法、some()方法
  8. 归并方法——reduce()方法、reduceRight()方法

转换方法:

①:toString()方法返回由数组中每个值的字符串形式拼接并且以逗号相隔的字符串
②:valueOf()方法返回的还是数组
③:toLocaleString()方法也会返回一个数组值以逗号相隔的字符串,但与toString()方法不同的是在返回日期对象时格式不同。

具体看一下例子:

var colors=["red","blue","green"];
console.log(colors.toString());    //"red,blue,green"
console.log(colors.valueOf());    //red,blue,green
console.log(colors.toLocaleString());    //"red,blue,green"

//toLocaleString()方法与toString()方法在返回日期对象时格式不同
var today=new Date();
console.log(today.toString());    //    Sun Mar 05 2017 12:57:11 GMT+0800 (中国标准时间)
console.log(today.toLocaleString());    //    2017/3/5 下午12:57:11

栈方法:

①:push()方法可以接受任意数量的参数,逐个添加到数组末尾,返回修改后数组的长度
②:pop()方法从数组末尾移除最后一项,返回被移除的项
具体看下面例子:

var arr=new Array();    //使用构造函数创建数组
var count=arr.push("red","blue");    //push()返回数组长度

console.log("count="+count);    //count=2
console.log(arr);    //red,blue

count=arr.push("black");    //count=3

var item=arr.pop();
console.log("item="+item);//pop返回被移除的项--item=black

队列方法:

①:shift()方法移除数组的第一次项并返回该项
②:unshift()方法在数组前端添加任意项,并返回新数组的长度

具体看一下例子:

var colors=new Array();    //创建数组
var count=colors.unshift("red","green");    //在数组前端添加两项
console.log(count);    //2

count=colors.unshift("black");     //此时数组各项顺序为"black","red","green"
console.log(count)    //3

item=colors.shift();
console.log(item);    //black

作者: 关于郑州想的都是你 

链接:http://www.imooc.com/article/16735

来源:慕课网

 

一、题目

 用JS代码求出页面上一个元素的最终的background-color,不考虑IE浏览器,不考虑元素float情况。

二、题目解析

 1.考察底层JavaScript基础
 前端开发,日常最常接触的就是页面样式的编写。而摆脱jQuery等工具库,用原生js获取样式,是每个前端程序猿进阶阶段必须掌握的技能。

 2.考察面试者的思维缜密程度和开发经验
 如果认为单单求元素计算后的样式,就有点too young了。页面的样式的复杂,永远是最虐心的。就算前端有多牛逼,一听到兼容IE6,论谁都会心塞😓。所以还要考虑特殊的情况:display,opacity,visibility的取值。

三、理论基础

 1. 内联样式
 内联样式可以通过元素的style属性获取,如果style属性有background-color值,则可以直接获取出来 (暂不考虑!important) 。

 2. 外联的层叠样式
 DOM2样式规范在document.defaultView中包含了一个getComputedStyle()方法。该方法返回一个只读的CSSStyleDeclaration对象,其中包含特定元素的所有计算样式。

四、解题

4.1 将所有工具方法封装在WDS(wall dom script)命名空间中

(function(WDS, undefined){
  // 封装代码...
})(window.WDS || (window.WDS = {}));

 代码封装在命名空间里,不会造成无意间的代码污染。

4.2 工具方法camelize

// 字符串转换为驼峰写法
function camelize(str) {
    return str.replace(/-(\w)/g, function (strMatch, p1){
        return p1.toUpperCase();
    });
}

 该方法是为了方便后续getStyle()方法的编写,而独立出来的。
 作用是将连字符类的css属性值,转换成驼峰写法。
 例如:将background-color转换为backgroundColor

4.3 获取特定元素的计算样式

// 获取元素计算后的样式
function getStyle(elem, property){
    if(!elem || !property){
        return false;
    }

    var value = elem.style[camelize(property)], // 先获取是否有内联样式
        css; // 获取的所有计算样式

    // 无内联样式,则获取层叠样式表计算后的样式
    if(!value){
        if(document.defaultView && document.defaultView.getComputedStyle){
            css = document.defaultView.getComputedStyle(elem, null);
            value = css ? css.getPropertyValue(property) : null;
        }
    }

    return value;
}

 做到这一步,第一个考察点基本就满足了。也能获知面试者是否具备足够扎实的js基础。
 另外,像安全保护性的判断if(!elem || !property)和功能嗅探if(document.defaultView && document.defaultView.getComputedStyle),都能很好地体现开发者的代码逻辑和开发经验。

4.4 排除特殊情况

// 检测获取的背景色是否有效
function checkBgValue(elem){
    var value = getStyle(elem, 'background-color'),
        hasColor = value ? true : false; // 是否有颜色

    // 排除特殊情况
    if(value == "transparent" || value == "rgba(0, 0, 0, 0)"){
        // 未设置background-color,或者设置为跟随父节点
        hasColor = false;
    }else if(getStyle(elem, 'opacity') == "0"){
        // dom节点透明度为全透明
        hasColor = false;
    }else if(getStyle(elem, 'visibility') == "hidden"){
        // dom节点不可见
        hasColor = false;
    }else if(getStyle(elem, 'display') == "none"){
        // dom节点不可见
        hasColor = false;
    }

    return hasColor;
}

4.5 获取div在页面最终显示的颜色

// 获取div最终显示的颜色
function getRealBg(elem){
    if(checkBgValue(elem)){
        return getStyle(elem, 'background-color');
    }else if(elem != document.documentElement){
        return getRealBg(elem.parentNode);
    }

    return '';
}

 获取样式值采用递归方式处理。
 如果能顺利获取到元素样式,且不触发4.4 排除特殊情况中的一种,则直接返回结果。
 触发了特殊情况,则需要查找父节点以及更上层的节点的样式,来获取肉眼能看到,显示在页面上的background-color值。
 在向上回溯的过程中,如果已经回溯到html根节点,则可以停止回溯。所以加了判断else if(elem != document.documentElement)

五、遗漏的大boss

5.1 大boss !important
 如果乱用 !important,对大型项目的维护和开发,绝对是一场噩梦。因为优先级规则的计算,!important永远处在食物链的最顶层。
 当前题目不考虑这种情况,也是我的偷懒😆。确实很棘手,就不写这个逻辑分支的代码了。这里提醒一下~

5.2 大boss 父节点及根节点设置了不可见css属性
 只要设置该css语句:html {display:none;},页面所有元素立刻消失不见。而任意特定元素的上级节点,只要设置了 opacity,display,visibility,判断逻辑瞬间变得复杂起来。所以,这个浑水我也不趟 O(∩_∩)O哈哈~

六、改进的点

 其实特殊情况排除的判断,我偷懒没做到最好——rgb颜色值和特定颜色值(比如red)没有进行统一的转换,只是加了生硬的判断if(value == "transparent" || value == "rgba(0, 0, 0, 0)")
 有兴趣的可以搜索下颜色值转换的js方法,这里我就不写了。

七、源码和demo

源码地址https://github.com/wall-wxk/blogDemo/blob/master/2017/02/05/getStyle.html
demohttps://wall-wxk.github.io/blogDemo/2017/02/05/getStyle.html

补充

 谢谢@烟雨雾岚 的提醒的新思路:canvas截图+Js获取图片某点颜色,这样可以完美解决所有的问题。

 

 

 

一、值

1)数字

JavaScript只有一种数值类型:number(数字),包括“整数”和带小数的十进制数。

//数字的语法
var a = 5E10; // 50000000000
a.toExponential();  // "5e+10"
var b = a * a;  // 2.5e+21 
var c = 1 / a; // 2e-11
var d = 0.42;
var e = .42; //数字前面的0可以省略
var f = 42.; //小数点后小数部分最后面的0也可以省略

由于数字值可以使用Number对象进行封装,因此数字值可以调用Number.prototype中的方法。例如,tofixed(..)方法可指定小数部分的显示位数:

// 无效语法:
42.toFixed( 3 );    // SyntaxError
// 下面的语法都有效:
a = (42).toFixed(3); // "42.000" 
b = 0.42.toFixed(3); // "0.420" 
c = 42..toFixed(3); // "42.000"
d = 42 .toFixed(3); // "42.000"

2)整数检测

//整数检测
if (!Number.isInteger) {
  Number.isInteger = function(num) {
    return typeof num == "number" && num % 1 == 0;
  };
}
//安全整数检测
if (!Number.isSafeInteger) {
  Number.isSafeInteger = function(num) {
    return Number.isInteger(num) &&
      Math.abs(num) <= Number.MAX_SAFE_INTEGER;
  };
}

3)null与undefined

特殊数值undefined与null。它们的名称既是类型也是值。

null指空值(empty value),曾赋过值,但是目前没有值。null是一个特殊关键字,不是标识符,我们不能将其当作变量来使用和赋值。

undefined指没有值(missing value),从未赋值。undefined是一个标识符,可以被当作变量来使用和赋值。

//将undefined当作变量来使用和赋值
function foo() {
  "use strict";
  var undefined = 2;
  console.log(undefined); // 2
}
foo();

4)不是数字的数字

NaN意指“不是一个数字”(not a number),将它理解为“无效数值”、“失败数值”或者“坏数值”可能更准确些。

NaN是一个特殊值,它和自身不相等,是唯一一个非自反(自反,即x === x不成立)的值。而NaN != NaN为true。

var a = 2 / "foo"; // NaN
typeof a === "number"; // true
if (!Number.isNaN) {
  Number.isNaN = function(n) { //非数字类型的值在isNaN中也会返回true
    return (
      typeof n === "number" &&
      window.isNaN(n)
    );
  };
}
//利用NaN不等于自身这个特点
if (!Number.isNaN) {
  Number.isNaN = function(n) {
    return n !== n;
  };
}

5)零值

加法和减法运算不会得到负零(negative zero)。负零在开发调试控制台中通常显示为“-0”,但在一些老版本的浏览器中仍然会显示为“0”。

//零值
a = 0 / -3; // -0
b = 0 * -3; // -0
c = +"-0"; // -0
d = Number("-0"); // -0
e = JSON.parse("-0"); // -0
//值比较
-0 == 0; // true
-0 === 0; // true
0 > -0; // false
//-0的判断方式
function isNegZero(n) {
  n = Number(n);
  return (n === 0) && (1 / n === -Infinity);
}
isNegZero(-0); // true
isNegZero(0 / -3); // true
isNegZero(0); // false

6)特殊等式

NaN和-0在相等比较时的表现有些特别。

由于NaN和自身不相等,所以必须使用ES6中的Number.isNaN(..)。 而-0等于0(对于===也是如此),因此我们必须使用isNegZero(..)这样的工具函数。

//特殊等式
if (!Object.is) {
  Object.is = function(v1, v2) {
    // 判断是否是-0
    if (v1 === 0 && v2 === 0) {
      return 1 / v1 === 1 / v2;
    }
    // 判断是否是NaN
    if (v1 !== v1) {
      return v2 !== v2;
    }
    // 其他情况
    return v1 === v2;
  };
}

7)值和引用

JavaScript引用指向的是值。如果一个值有10个引用,这些引用指向的都是同一个值,它们相互之间没有引用/指向关系。

向函数传递值的时候,实际是将引用值的一个复本传递进去,不管是基本类型还是对象。

//基本类型
var a = 2;
var b = a; // b是a的值的一个副本
b++;
a; // 2
b; // 3

//变量引用同一个值
var c = [1, 2, 3];
var d = c; // d是[1,2,3]的一个引用
d.push(4);
c; // [1,2,3,4]
d; // [1,2,3,4]

//变量引用不同的值
var a = [1, 2, 3];
var b = a;
b = [4, 5, 6]; //给b重新赋值,引用新的值,不影响a的引用
a; // [1,2,3]
b; // [4,5,6]

//函数内让参数重新引用值
function foo2(x) {
  x.push(4);
  x; // [1,2,3,4]
  
  x = [4, 5, 6];// 然后重新引用新的值
  x.push(7);
  x; // [4,5,6,7]
}
var a = [1, 2, 3];
//向函数传递a的时候,实际是将引用a的一个复本赋值给x,而a仍然指向[1,2,3]
foo2(a);
a; // 是[1,2,3,4],不是[4,5,6,7]

上面的源码可以在此次浏览

 

二、原生函数

常用的原生函数有:String()、Number()、Boolean()、Array()、Object()、Function()、RegExp()、Date()、Error()、Symbol()。

1)内部属性[[Class]]

这个属性无法直接访问,一般通过Object.prototype.toString(..)来查看。

//内部属性[[Class]]
Object.prototype.toString.call([1, 2, 3]); // "[object Array]" 
Object.prototype.toString.call(/regex-literal/i); // "[object RegExp]"
//基本类型
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"

虽然Null()和Undefined()这样的原生构造函数并不存在,但是内部[[Class]]属性值仍然是"Null"和"Undefined"。

基本类型值被各自的封装对象自动包装,所以它们的内部[[Class]]属性值分别为"String"、"Number"和"Boolean"。

Object.prototype.toString.call("abc"); // "[object String]"
Object.prototype.toString.call(42); // "[object Number]"
Object.prototype.toString.call(true); // "[object Boolean]"

2)封装对象包装

由于基本类型值没有.length和.toString()这样的属性和方法,需要通过封装对象才能访问,此时JavaScript会自动为基本类型值包装(box或者wrap)一个封装对象:

//封装对象
var a = "abc";
a.length; // 3
a.toUpperCase(); // "ABC"

如果想要自行封装基本类型值,可以使用 Object(..) 函数(不带 new 关键字)

//自行封装基本类型
var a = "abc";
var b = new String(a);
var c = Object(a);

typeof a; // "string" 
typeof b; // "object" 
typeof c; // "object"
b instanceof String; // true 
c instanceof String; // true
Object.prototype.toString.call(b); // "[object String]" 
Object.prototype.toString.call( c ); // "[object String]"

3)拆封

如果想要得到封装对象中的基本类型值,可以使用valueOf()函数:

//拆封
var a = new String("abc");
var b = new Number(42);
var c = new Boolean(true);

console.log(a.valueOf()); // "abc"
console.log(b.valueOf()); // 42
console.log(c.valueOf()); // true

在需要用到封装对象中的基本类型值的地方会发生隐式拆封。

 

 

/*========================常用函数========================*/

/*时间格式化*/
Date.prototype.Format = function (fmt) {
    var o = {
        "M+": this.getMonth() + 1, /*月份*/
        "d+": this.getDate(), /*日*/
        "h+": this.getHours(), /*小时*/
        "m+": this.getMinutes(), /*分*/
        "s+": this.getSeconds(), /*秒*/
        "q+": Math.floor((this.getMonth() + 3) / 3), /*季度*/
        "S": this.getMilliseconds() /*毫秒*/
    };
    if (/(y+)/.test(fmt))
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt))
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
};

/*IE浏览器不支持date(time),所以用此方法转换*/
function NewDate(fmt) {
    /*首先将日期分隔 ,获取到日期部分 和 时间部分*/
    var day = fmt.split(' ');
    /*获取日期部分的年月日*/
    var days = day[0].split('-');
    /*获取时间部分的 时分秒*/
    var mi = day[day.length - 1].split(':');
    /*获取当前date类型日期*/
    var date = new Date();
    /*给date赋值  年月日*/
    date.setUTCFullYear(days[0], days[1] - 1, days[2]);
    /*给date赋值 时分秒  首先转换utc时区 :+8*/
    date.setUTCHours(mi[0] - 8, mi[1], mi[2]);
    return date;
}

/*为空判断*/
function isEmpty(s) {
    switch (typeof(s)) {
        case 'string':
            return !s.length;
            break;
        case 'array':
        case 'object':
            for (var i in s) return false;
            return true;
            break;
        case 'undefined':
            return true;
            break;
        default:
            return !s;
            break;
    }
}

/*数字判断*/
function isNumber(s) {
    return typeof(s) == 'number' ? true : false;
}

/*整数判断*/
function isInt(s) {
    var re = /^-?\d*$/;
    return re.test(s);
}

/*正整数判断*/
function isUInt(s) {
    var re = /^\d*$/;
    return re.test(s) && s >= 0;
}

/*小数判断*/
function isDecimal(s, bit) {
    if (!arguments[1]) bit = -1;
    if (bit == -1) {
        var re = /^-?\d*.?\d*$/;
        return re.test(s);
    } else {
        var re = new RegExp('^-?\\d*.?\\d{0,' + bit + '}$');
        return re.test(s);
    }
}

/*正小数判断*/
function isUDecimal(s, bit) {
    if (!arguments[1]) bit = -1;
    if (bit == -1) {
        var re = /^\d*.?\d*$/;
        return re.test(s) && s >= 0;
    } else {
        var re = new RegExp('^\\d*.?\\d{0,' + bit + '}$');
        return re.test(s) && s >= 0;
    }
}

/*字符串判断*/
function isString(s) {
    return typeof(s) == 'string';
}

/*========================/常用函数========================*/

js onkeyup replace 自动替换

检测浮点数 只能是整数或者小数 
多余的就replace 掉 的表单验证


function checkFloatNum(obj)
{
    //先把非数字的都替换掉,除了数字和.
    obj.value = obj.value.replace(/[^\d.]/g,"");
    //必须保证第一个为数字而不是.
    obj.value = obj.value.replace(/^\./g,"");
    //保证只有出现一个.而没有多个.
    obj.value = obj.value.replace(/\.{2,}/g,".");
    //保证.只出现一次,而不能出现两次以上
    obj.value = obj.value.replace(".","$#$").replace(/\./g,"").replace("$#$",".");
}





function GetURLval(url) {
				var vars ={},
					hash;
				if(!url) url = window.location.href; 
				var hashes = url.slice(url.indexOf('?') + 1).split('&');
				for(var i = 0; i < hashes.length; i++) {
					hash = hashes[i].split('=');
					vars[hash[0]]=decodeURIComponent(hash[1]);
				}
				return vars;
			}
			
			console.log(GetURLval());
			console.log(GetURLval('?a=111&b=222&c=李四'));
  function isString(str){
        if(Object.prototype.toString.call(str) === "[object String]"){
            console.log("是字符串");
            return true;
        }else{
            console.log("不是字符串");
            return false;
        }
    }
 // e.g.: http://domain.com/path/to/picture.jpg?size=1280×960 -> picture.jpg
  function getImageName(url) {
    return isString(url) ? url.replace(/^.*\//, '').replace(/[\?&#].*$/, '') : '';
  }  

  

 
posted @ 2017-10-21 19:08  最骚的就是你  阅读(920)  评论(2编辑  收藏  举报