javascript常用方法和技巧

浏览器变编辑器
data:text/html, <style type="text/css">#e{position:absolute;top:;right:;bottom:;left:;}</style><div id="e"></div><script src="http://d1n0x3qji82z53.cloudfront.net/src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script><script>var e=ace.edit("e");e.setTheme("ace/theme/monokai");e.getSession().setMode("ace/mode/javascript");</script>

深度拷贝

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 strRandom = "qwertyuioplkjhgfdsazxcvbnm0123456789";
function getRamdomStr(){
var str = "", len = strRandom.length,
index = Math.floor(len*Math.random());
str = strRandom.substring(index-1,index);
return str;
}
function generateClassName(){
var arr = [];
for(var i = 0; i< 12; i++){
arr.push(getRamdomStr());
}
return arr.join("");
}

curry化函数
//   【通用curry化函数】
function curry(fn) {
var slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function () {
var new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
}
} // 测试
function add(x, y) {
return x + y;
}
// 将一个函数curry化获得一个新的函数
var newadd = curry(add, 5);
console.log(newadd(4)); // 另一种选择--直接调用新函数
console.log(curry(add, 6)(7));

计数器

var setup = function () {
var count = 0;
return function () {
return (count += 1);
};
}; // 用法
var next = setup();
next();

获取地址参数

var getValueParam = function(key){
var url = window.location.href,
para = url.split('?')[1],
arrparam = [],
val = undefined;
if(para.length){
arrparam = para.split('&');
for( var i = 0; i<arrparam.length; i++ ){
if(arrparam[i].split("=")[0] == key){
val = arrparam[i].split("=")[1];
break;
}
}
}
return val;
};

php数组赋值js变量

var data = <?php echo json_encode($data) ?>

弹出居中

function getValue ($target){
var h = $(document).scrollTop()+($(window).height()-$target.height())/2;
var w = ($(window).width()-$target.width())/2
return {
t : h,
l : w
}
}

form表单Ajax提交

$('form').submit(function(e){
e.preventDefault();
var postData = $(this).serializeArray();
var formURL = $(this).attr("action");
$.ajax({
url : formURL,
type: "POST",
data : postData,
dataType : "json",
success:function(data, textStatus, jqXHR)
{
if(textStatus == 'success'){
console.log(data, textStatus, jqXHR);
}
//data: return data from server
},
error: function(jqXHR, textStatus, errorThrown)
{
//if fails
}
});
});

腾讯视频嵌入代码

<iframe class="video_iframe" style=" z-index:1; " src="http://v.qq.com/iframe/player.html?vid=m0144ws2h0q&amp;width=300&amp;height=200&amp;auto=0" allowfullscreen="" frameborder="0" height="200" width="300"></iframe>

网页代码编辑器

data:text/html, <style type="text/css">.e{position:absolute;top:0;right:0;bottom:0;left:0;}</style><div class="e" id="editor"></div><script src="http://d1n0x3qji82z53.cloudfront.net/src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script><script>var e=ace.edit("editor");e.setTheme("ace/theme/monokai");e.getSession().setMode("ace/mode/javascript");</script>
【scp】
上端口大写P 为参数,2222 表示更改SSH端口后的端口,如果没有更改SSH端口可以不用添加该参数
获取文件:
scp -P 2222 root@www.legcloud.com:/root/test.tar.gz /home/test.tar.gz
上传目录:
scp -P 2222 -r /home/dirname/ root@www.legcloud.com:/root/dirname/

判断是否为数组的函数: isArray()

//   支付宝同学在用的
if (value instanceof Array ||
(!(value instanceof Object) &&
(Object.prototype.toString.call((value)) == '[object Array]') ||
typeof value.length == 'number' &&
typeof value.splice != 'undefined' &&
typeof value.propertyIsEnumerable != 'undefined' &&
!value.propertyIsEnumerable('splice'))) {
return 'array';
} // 最直接的、简单的方式(在不同 iframe 中创建的 Array 并不共享 prototype)
var arr = [];
arr instanceof Array; // true
arr.constructor == Array; //true // 基于iframe的情况 使用 Douglas Crockford 的方法是可以解决这个问题(《JavaScript 语言精粹》P61)
var is_array = function(value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
}; // 更简单的方法,也是jQuery 正在使用的。淘宝的 kissy 也是使用这种方式
var isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
} // 大而全而cool 判断类型
var is = function (obj,type) {
return (type === "Null" && obj === null) ||
(type === "Undefined" && obj === void 0 ) ||
(type === "Number" && isFinite(obj)) ||
Object.prototype.toString.call(obj).slice(8,-1) === type;
}

1、&&和if

//  &&和
var a = ;
a == && ( b = ,console.log(b)) ; // 0 // 上面代码等同于
var a = ;
if( a == ){
b = ,console.log(b);
}
a == && ( b = ,console.log(b)) // 0 // 以下还会返回值
var a = ;
a != && ( b = ,console.log(b)) ; // false

2、判断IE

常规的判断已经阻挡不了NB的IE了,没有msie。。用它:
// IE11
!!navigator.userAgent.match(/Trident\/\./)
// 或者
Object.hasOwnProperty.call(window, "ActiveXObject") && !window.ActiveXObject // IE6
var ie6 = !-[1,]&&!window.XMLHttpRequest; // IE7
var ie7 = (navigator.appName == "Microsoft Internet Explorer" && navigator.appVersion.match(/7./i)=="7.")

3、移动端常用

//   移动端判断屏幕高度
document.documentElement.clientHeight
// browser info and capability
var _ua = window.navigator.userAgent;
// isRetina
window.devicePixelRatio && window.devicePixelRatio > 1
// isIDevice
(/iphone|ipod|ipad/i).test(_ua)
// isMobileChrome
_ua.indexOf('Android') > -1 && (/Chrome\/[.0-9]*/).test(_ua)
// isMobileIE
_ua.indexOf('Windows Phone') > -1
// isMobileSafari
isIDevice && _ua.indexOf('Safari') > -1 && _ua.indexOf('CriOS') < 0;
// isTablet
(isMobileSafari && _ua.indexOf('iPad') > -1) || (isMobileChrome && _ua.indexOf('Mobile') < 0);

Platform = {

list :[{"name":"iOS",

"value" : 1

},{"name":"Android",

"value" :2

},{"name":"weixin",

"value" :3

}],

getName : function(){

var name = this.getInfo().name;

return name;

},

getValue : function(){

var val = this.getInfo().value;

return val;

},

getInfo : function(){

var list = this.list,

regObj = this.judgeReg,

obj = {"name":"weixin","value":2};

for(var i=0;i<list.length; i++){

if(regObj[list[i]['name']]){

obj = list[i];

break;

}

}

return obj;

},

judgeReg : {

"iOS" : !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),

"Android" : navigator.userAgent.indexOf('Android') > -1 || navigator.userAgent.indexOf('Linux') > -1,

"weixin" :  /MicroMessenger/.test(navigator.userAgent)

}

};

  横竖屏函数判断
function orientationChange() {
switch (window.orientation) {
case 0: // Portrait
case 180: // Upside-down Portrait
// Javascript to setup Portrait view
alert('Portrait');
break;
case -90: // Landscape: turned 90 degrees counter-clockwise
case 90: // Landscape: turned 90 degrees clockwise
// Javascript to steup Landscape view
alert('Landscape');
break;
}
}
window.addEventListener(("onorientationchange" in window || "orientation" in window) ? "orientationchange" : "resize", orientationChange, false);

4、deffer

var Promise = function () {
this.thens = [];
};
Promise.prototype = {
resolve: function () {
var t = this.thens.shift(), n;
t && (n = t.apply(null, arguments), n instanceof Promise && (n.thens = this.thens));
},
then: function (n) {
return this.thens.push(n), this;
}
}
function f1() {
var promise = new Promise();
setTimeout(function () { alert(1);
promise.resolve();
}, 5500) return promise;
} function f2() {
var promise = new Promise();
setTimeout(function () { alert(2);
promise.resolve();
}, 1500) return promise;
} function f3() {
var promise = new Promise();
setTimeout(function () { alert(3);
promise.resolve();
}, 1500) return promise; } function f4() {
alert(4);
} f1().then(f2).then(f3).then(f4);

5、更多常用方法

String.prototype.isMobile = function(){
var pattern = /^0{0,1}(13[0-9]|14[6|7]|15[0-3]|15[5-9]|18[0-9]|17[0-9])[0-9]{8}$/;
return pattern.test( this );
}
String.prototype.isEmail = function(){
var pattern = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
return pattern.test( this );
}
String.prototype.isUrl = function(){
var pattern = /([\w-]+\.)+[\w-]+.([^a-z])(\[\w-\.\?%&=]*)?|[a-zA-Z0-9\-\.][\w-]+.([^a-z])(\[\w-\.\?%&=]*)?/;
return pattern.test( this );
}
String.prototype.isChinese = function(){
var pattern = /^[\u4e00-\u9fa5]+$/;
return pattern.test( this );
}
String.prototype.isEnglish = function(){
var pattern = /^[a-zA-Z]+$/;
return pattern.test( this );
}
var BASE = {
// html模板替换,用于html和数据相分离
// 模板中的变量用‘{}’包起来,‘{}’内的字符作为变量替换掉需要的内容
// 模板写法: var dom = '<li class="item {selected}" val="{value}">{text}</li>'
// 【方法调用】:BASE.regReplace(dom,{selected:1,value:2,text:3});
// 输出结果:"<li class="item 1" val="2">3</li>"
regReplace : function(str,data,reg){
if (!reg){
reg = /\{\w*\}/g;
}
return str.replace(reg,function(match,pos){
var s = '';
var command = match.substring(1,match.length-1);
if (data[command]){
s = data[command];
}
return s;
});
},
// 在数组中查找元素,如果存在,返回所在下标,如果不存在,则返回-1
// 【方法调用】:BASE.isInArr(1,[2,3,1]);
isInArr : function(item, arr){
if( arr.length > 0 ){
for( var i = 0; i < arr.length; i++ ){
if( arr[i] == item ){
return i;
break;
}
}
return -1;
}else{
return -1;
}
},
// 在数组中删除指定元素,如果存在,返回删除后的数组,如果不存在,返回undefined
// 【方法调用】:BASE.removeInArr(1,[2,3,1]);
removeInArr : function(item, arr){
var index = this.isInArr(item, arr);
if (index > -1) {
arr.splice(index, 1);
return arr;
}else{
return undefined;
}
},
// 得到最大天数
getMaxDays : function(year, month){
var dt = new Date(year, month - 1, '01');
dt.setDate(1);
dt.setMonth(dt.getMonth() + 1);
cdt = new Date(dt.getTime()-1000*60*60*24);
return cdt.getDate();
},
getCookie : function (a) {
var b;
b = a + "=";
offset = document.cookie.indexOf(b);
if (offset != -1) {
offset += b.length;
end = document.cookie.indexOf(";", offset);
if (end == -1) {
end = document.cookie.length;
}
return document.cookie.substring(offset, end);
}
else {
return "";
}
}
};

6、图片尺寸

//  传统做法
var imgLoad = function (url, callback) {
var img = new Image(); img.src = url;
if (img.complete) {
callback(img.width, img.height);
} else {
img.onload = function () {
callback(img.width, img.height);
img.onload = null;
};
}; };
// 1、保证回调执行顺序:error > ready > load;2、回调函数this指向img本身
// 2、增加图片完全加载后的回调、提高性能 /**
* 图片头数据加载就绪事件 - 更快获取图片尺寸
* @param {String} 图片路径
* @param {Function} 尺寸就绪
* @param {Function} 加载完毕 (可选)
* @param {Function} 加载错误 (可选)
* @example imgReady('http://x.autoimg.cn/www/common/images/logo.png', function () {
alert('size ready: width=' + this.width + '; height=' + this.height);
});
*/
var imgReady = (function () {
var list = [], intervalId = null, // 用来执行队列
tick = function () {
var i = 0;
for (; i < list.length; i++) {
list[i].end ? list.splice(i--, 1) : list[i]();
};
!list.length && stop();
}, // 停止所有定时器队列
stop = function () {
clearInterval(intervalId);
intervalId = null;
}; return function (url, ready, load, error) {
var onready, width, height, newWidth, newHeight,
img = new Image(); img.src = url; // 如果图片被缓存,则直接返回缓存数据
if (img.complete) {
ready.call(img);
load && load.call(img);
return;
}; width = img.width;
height = img.height; // 加载错误后的事件
img.onerror = function () {
error && error.call(img);
onready.end = true;
img = img.onload = img.onerror = null;
}; // 图片尺寸就绪
onready = function () {
newWidth = img.width;
newHeight = img.height;
if (newWidth !== width || newHeight !== height ||
// 如果图片已经在其他地方加载可使用面积检测
newWidth * newHeight > 1024
) {
ready.call(img);
onready.end = true;
};
};
onready(); // 完全加载完毕的事件
img.onload = function () {
// onload在定时器时间差范围内可能比onready快
// 这里进行检查并保证onready优先执行
!onready.end && onready(); load && load.call(img); // IE gif动画会循环执行onload,置空onload即可
img = img.onload = img.onerror = null;
}; // 加入队列中定期执行
if (!onready.end) {
list.push(onready);
// 无论何时只允许出现一个定时器,减少浏览器性能损耗
if (intervalId === null) intervalId = setInterval(tick, 40);
};
};
})();
调用例子: imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
alert('size ready: width=' + this.width + '; height=' + this.height);
});

7、iframe跨域

function Messenger(win) {
// save the pointer to the window which is interacting with
this.win = win;
this.init();
} // postMessage API is supported
Messenger.prototype.init = function () {
var self = this;
var receiver = function (event) {
// Some IE-component browsers fails if you compare
// window objects with '===' or '!=='.
if (event.source != self.win) return;
(self.onmessage || function () {}).call(self, event.data);
};
if (window.addEventListener)
window.addEventListener('message', receiver, false);
else if (window.attachEvent)
window.attachEvent('onmessage', receiver);
}; Messenger.prototype.send = function (data) {
this.win.postMessage(data, '*');
}; Messenger.initInParent = function (frame) {
return new this(frame.contentWindow);
}; Messenger.initInIframe = function () {
return new this(window.parent);
}; // in IE, postMessage API is not supported
if (!window.postMessage && window.attachEvent) {
// redefine the init method
Messenger.prototype.init = function () {
var isSameOrigin = false;
// test if the two document is same origin
try {
isSameOrigin = !!this.win.location.href;
} catch (ex) {}
if (isSameOrigin) {
this.send = this.sendForSameOrigin;
this.initForSameOrigin();
return;
} // different origin case
// init the message queue, which can guarantee the messages won't be lost
this.queue = [];
if (window.parent == this.win) {
this.initForParent();
} else {
this.initForFrame();
}
}; Messenger.prototype.initForSameOrigin = function () {
var self = this;
document.attachEvent('ondataavailable', function (event) {
if (!event.eventType ||
event.eventType !== 'message' ||
event.eventSource != self.win)
return;
(self.onmessage || function () {}).call(self, event.eventData);
});
}; Messenger.prototype.sendForSameOrigin = function (data) {
var self = this;
setTimeout(function () {
var event = self.win.document.createEventObject();
event.eventType = 'message';
event.eventSource = window;
event.eventData = data;
self.win.document.fireEvent('ondataavailable', event);
});
}; // create two iframe in iframe page
Messenger.prototype.initForParent = function () {
var fragment = document.createDocumentFragment();
var style = 'width: 1px; height: 1px; position: absolute; left: -999px; top: -999px;';
var senderFrame = document.createElement('iframe');
senderFrame.style.cssText = style;
fragment.appendChild(senderFrame);
var receiverFrame = document.createElement('iframe');
receiverFrame.style.cssText = style;
fragment.appendChild(receiverFrame); document.body.insertBefore(fragment, document.body.firstChild);
this.senderWin = senderFrame.contentWindow;
this.receiverWin = receiverFrame.contentWindow; this.startReceive();
}; // parent page wait the messenger iframe is ready
Messenger.prototype.initForFrame = function () {
this.senderWin = null;
this.receiverWin = null; var self = this;
this.timerId = setInterval(function () {
self.waitForFrame();
}, 50);
}; // parent page polling the messenger iframe
// when all is ready, start trying to receive message
Messenger.prototype.waitForFrame = function () {
var senderWin;
var receiverWin;
try {
senderWin = this.win[1];
receiverWin = this.win[0];
} catch (ex) {}
if (!senderWin || !receiverWin) return;
clearInterval(this.timerId); this.senderWin = senderWin;
this.receiverWin = receiverWin;
if (this.queue.length)
this.flush();
this.startReceive();
}; // polling the messenger iframe's window.name
Messenger.prototype.startReceive = function () {
var self = this;
this.timerId = setInterval(function () {
self.tryReceive();
}, 50);
}; Messenger.prototype.tryReceive = function () {
try {
// If we can access name, we have already got the data.
this.receiverWin.name;
return;
} catch (ex) {} // if the name property can not be accessed, try to change the messenger iframe's location to 'about blank'
this.receiverWin.location.replace('about:blank');
// We have to delay receiving to avoid access-denied error.
var self = this;
setTimeout(function () {
self.receive();
}, 0);
}; // recieve and parse the data, call the listener function
Messenger.prototype.receive = function () {
var rawData = null;
try {
rawData = this.receiverWin.name;
} catch (ex) {}
if (!rawData) return;
this.receiverWin.name = ''; var self = this;
var dataList = rawData.substring(1).split('|');
for (var i = 0; i < dataList.length; i++) (function () {
var data = decodeURIComponent(dataList[i]);
setTimeout(function () {
(self.onmessage || function () {}).call(self, data);
}, 0);
})();
}; // send data via push the data into the message queue
Messenger.prototype.send = function (data) {
this.queue.push(data);
if (!this.senderWin) return;
this.flush();
}; Messenger.prototype.flush = function () {
var dataList = [];
for (var i = 0; i < this.queue.length; i++)
dataList[i] = encodeURIComponent(this.queue[i]);
var encodedData = '|' + dataList.join('|');
try {
this.senderWin.name += encodedData;
this.queue.length = 0;
} catch (ex) {
this.senderWin.location.replace('about:blank');
var self = this;
setTimeout(function () {
self.flush();
}, 0);
}
}; } // 父页面
var messenger = Messenger.initInParent(document.getElementById('iframe'));
messenger.onmessage = function (data) {
var newline = '\n';
var text = document.createTextNode(data + newline);
document.getElementById('output').appendChild(text);
}; function sendMessage() {
var message = document.getElementById('message');
messenger.send(message.value);
message.value = '';
} // 子页面
var messenger = Messenger.initInIframe();
messenger.onmessage = function (data) {
var newline = '\n';
var text = document.createTextNode(data + newline);
document.getElementById('output').appendChild(text);
}; function sendMessage() {
var message = document.getElementById('message');
messenger.send(message.value);
message.value = '';
}

8、发布订阅模型

var PubSub = {handlers: {}}
PubSub.on = function(eventType, handler) {
if (!(eventType in this.handlers)) {
this.handlers[eventType] = [];
} this.handlers[eventType].push(handler);
return this;
}
PubSub.emit = function(eventType) {
var handlerArgs = Array.prototype.slice.call(arguments, 1);
for (var i = 0; i < this.handlers[eventType].length; i++) {
this.handlers[eventType][i].apply(this, handlerArgs);
}
return this;
}

9、关于this作用域

 //  兼容性更好的 bind
if (!Function.prototype.bind) {
Function.prototype.bind = function() {
var __method = this;
var args = Array.prototype.slice.call(arguments);
var object = args.shift();
return function() {
return __method.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
}
}
}
//  最简单的 bind  (ie9以上,不可取)
Function.prototype.bind = function (scope) {
var fn = this;
return function () {
return fn.apply(scope);
};
}
// 例子
var foo = {
x: 3
}
var bar = function(){
console.log(this.x);
}
bar(); // undefined
var boundFunc = bar.bind(foo);
boundFunc(); //
// 适用场景:事件绑定回调和setTimeout回调
// 1 事件绑定
var logger = {
x: 0,
updateCount: function(){
this.x++;
console.log(this.x);
}
}
// 原始函数
document.querySelector('button').addEventListener('click', function(){
logger.updateCount();
});
// 改造后
document.querySelector('button').addEventListener('click', logger.updateCount.bind(logger)); // 2 setTimeout
// 原始函数
render: function () {
this.$el.html(this.template());
setTimeout(this.afterRender, 0);
}
// 改造后
render: function () {
this.$el.html(this.template());
setTimeout(this.afterRender.bind(this), 0);
}
// Tidier Event Binding With querySelectorAll
Array.prototype.forEach.call(document.querySelectorAll('.klasses'), function(el){
el.addEventListener('click', someFunction);
}); // 改造后
var unboundForEach = Array.prototype.forEach,
forEach = Function.prototype.call.bind(unboundForEach); forEach(document.querySelectorAll('.klasses'), function (el) {
el.addEventListener('click', someFunction);
});

10、jquery多版本

<script type="text/javascript" src="/jquery.1.7.js"></script>
var jQuery_1_7 = jQuery.noConflict(true);
jQuery_1_7('.class').on(callback);

11、常用正则

匹配 UTF- 中文:^[\x{4e00}-\x{9fa5}]+$
匹配包含全角字符的 UTF- 中文:^[\x{4e00}-\x{9fa5}A-Za-z0-9_]+$
匹配 GB2312/GBK 中文:^[".chr(0xa1)."-".chr(0xff)."]+$
匹配包含全角字符的 GB2312/GBK 中文:^[".chr(0xa1)."-".chr(0xff)."A-Za-z0-9_]+$
匹配 HTML 标记:< (\S*?)[^>]*>.*?|< .*? />
匹配邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
匹配网址 URL:[a-zA-z]+://[^\s]*
匹配加区号的国内电话号码:\d{}-\d{}|\d{}-\d{}
匹配 QQ 号:[-][-]{,}
匹配邮政编码:[-]\d{}(?!\d)
匹配身份证号码:\d{}|\d{}
匹配 ip 地址:\d+\.\d+\.\d+\.\d+

12、地址转义

var encodeRFC5987ValueChars = function  (str) {
return encodeURIComponent(str).
// Note that although RFC3986 reserves "!", RFC5987 does not,
// so we do not need to escape it
replace(/['()]/g, escape). // i.e., %27 %28 %29
replace(/\*/g, '%2A').
// The following are not required for percent-encoding per RFC5987,
// so we can allow for a little better readability over the wire: |`^
replace(/%(?:7C|60|5E)/g, unescape);
};
//添加反斜杠

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}

 

13 安装压缩

npm install uglify-js -g
上一篇:codeforces 630C - Lucky Numbers 递推思路


下一篇:构建纯TypeScript应用