手写事件侦听器,并要求兼容浏览器
var eventUtil = {
getEvent: function(event) {
return event || window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
},
addListener: function(element, type, hander) {
if (element.addEventListener) {
element.addEventListener(type, hander, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, hander);
} else {
element['on' + type] = hander;
}
},
removeListener: function(element, type, hander) {
if (element.removeEventListener) {
element.removeEventListener(type, hander, false);
} else if (element.deattachEvent) {
element.detachEvent(type, hander);
} else {
element['on' + type] = null;
}
},
preventDefault: function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
stopPropagation: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
// 调用
(function() {
var btn = document.getElementById("btn");
var link = document.getElementsByTagName("a")[0];
eventUtil.addListener(btn, "click", function(event) {
var event = eventUtil.getEvent(event);
var target = eventUtil.getTarget(event);
alert(event.type);
alert(target);
eventUtil.stopPropagation(event);
});
eventUtil.addListener(link, "click", function(event) {
alert("prevent default event");
var event = eventUtil.getEvent(event);
eventUtil.preventDefault(event);
});
eventUtil.addListener(document.body, "click", function() {
alert("click body");
});
})();
手写事件模型
var Event = (function () {
var list = {}, bind, trigger, remove;
bind = function (key, fn) {
if (!list[key]) {
list[key] = [];
}
list[key].push(fn);
};
trigger = function () {
var key = Array.prototype.shift.call(arguments);
var fns = list[key];
if (!fns || fns.length === 0) {
return false;
}
for (var i = 0, fn; fn = fns[i++];) {
fn.apply(this, arguments);
}
};
remove = function (key, fn) {
var fns = list[key];
if (!fns) {
return false;
}
if (!fn) {
fns & (fns.length = 0);
} else {
for (var i = fns.length - 1; i >= 0; i--) {
var _fn = fns[i];
if (_fn === fn) {
fns.splice(i, 1);
}
}
}
};
return {
bind: bind,
trigger: trigger,
remove: remove
}
})();
// 调用
Event.bind('Hit', function(){ console.log('bind event'); }); // 绑定事件
Event.trigger("Hit", function(){ console.log('trigger event'); }); // 触发事件
手写事件代理,并要求兼容浏览器
function delegateEvent(parentEl, selector, type, fn) {
var handler = function(e){
var e = e || window.event;
var target = e.target || e.srcElement;
if (matchSelector(target, selector)) {
if(fn) {
fn.call(target, e);
}
}
};
if(parentEl.addEventListener){
parentEl.addEventListener(type, handler);
}else{
parentEl.attachEvent("on" + type, handler);
}
}
/**
* support #id, tagName, .className
*/
function matchSelector(ele, selector) {
// if use id
if (selector.charAt(0) === "#") {
return ele.id === selector.slice(1);
}
// if use class
if (selector.charAt(0) === ".") {
return (" " + ele.className + " ").indexOf(" " + selector.slice(1) + " ") != -1;
}
// if use tagName
return ele.tagName.toLowerCase() === selector.toLowerCase();
}
// 调用
var box = document.getElementById("box");
delegateEvent(box, "a", "click", function(){
console.log(this.href);
})
手写事件触发器,并要求兼容浏览器
var fireEvent = function(element, event){
if (document.createEventObject){
var mockEvent = document.createEventObject();
return element.fireEvent('on' + event, mockEvent)
}else{
var mockEvent = document.createEvent('HTMLEvents');
mockEvent.initEvent(event, true, true);
return element.dispatchEvent(mockEvent);
}
}
手写 Function.bind 函数
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
throw new TypeError("'this' is not function");
}
// bind's default arguments, array without first element
// first part arguments for the function
var aBindArgs = Array.prototype.slice.call(arguments, 1);
var fToBind = this; // the function will be binding
var fNOP = function () {};
var fBound = function () {
// target this will be binding
var oThis = this instanceof fNOP ? this : oThis || this;
// last part arguments for the function
var aCallArgs = Array.prototype.slice.call(arguments);
// complete arguments for the function
var aFuncArgs = aBindArgs.concat(aCallArgs);
return fToBind.apply(oThis, aFuncArgs);
};
// fBound extends fToBind
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
// 调用
var add = function(a, b, c){ return a + b + c;};
var newAdd = add.bind(null, 1, 2);
var result = newAdd(3);
手写数组快速排序
var quickSort = function(arr) {
if (arr.length <= 1) { return arr; }
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0, len = arr.length; i < len; i++){
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat([pivot], quickSort(right));
};
// 调用
quickSort([9, 4, 2, 8, 1, 5, 3, 7]);
手写数组冒泡排序
var bubble = function(arr){
var maxIndex = arr.length - 1, temp, flag;
for (var i = maxIndex; i > 0; i--) {
flag = true
for (var j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
}
}
if(! flag){
break;
}
}
return arr;
}
// 调用
var arr = bubble([13, 69, 28, 93, 55, 75, 34]);
手写数组去重
Array.prototype.unique = function() { return [...new Set(this)];};
// 调用
[1, 2, 3, 3, 2, 1].unique();
function unique1(arr){
var hash = {}, result = [];
for(var i=0, len=arr.length; i<len; i++){
if(! hash[arr[i]]){
result.push(arr[i]);
hash[arr[i]] = true;
}
}
return result;
}
// 调用
unique1([1, 2, 3, 3, 2, 1]);
Array.prototype.unique2 = function(){
this.sort();
var result = [this[0]];
var len = this.length;
for(var i = 0; i < len; i++){
if(this[i] !== result[result.length - 1]){
result.push(this[i]);
}
}
return result;
}
// 调用
[1, 2, 3, 3, 2, 1].unique2();
function unique3(arr){
var result = [];
for(var i=0; i<arr.length; i++){
if(result.indexOf(arr[i]) == -1){
result.push(arr[i]);
}
}
return result;
}
// 调用
unique3([1, 2, 3, 3, 2, 1]);
将url的查询参数解析成字典对象
function parseQuery(url) {
url = url == null ? window.location.href : url;
var search = url.substring(url.lastIndexOf("?") + 1);
var hash = {};
var reg = /([^?&=]+)=([^?&=]*)/g;
search.replace(reg, function (match, $1, $2) {
var name = decodeURIComponent($1);
var val = decodeURIComponent($2);
hash[name] = String(val);
return match;
});
return hash;
}
封装函数节流函数
var throttle = function(fn, delay, mustRunDelay){
var timer = null;
var t_start;
return function(){
var context = this, args = arguments, t_curr = +new Date();
clearTimeout(timer);
if(!t_start){
t_start = t_curr;
}
if(t_curr - t_start >= mustRunDelay){
fn.apply(context, args);
t_start = t_curr;
} else {
timer = setTimeout(function(){
fn.apply(context, args);
}, delay);
}
};
};
// 调用(两次间隔50ms内连续触发不执行,但每累计100ms至少执行一次
window.onresize = throttle(myFunc, 50, 100);
用JS实现千位分隔符
function test1(num){
var str = (+ num) + '';
var len = str.length;
if(len <= 3) return str;
num = '';
while(len > 3){
len -= 3;
num = ',' + str.substr(len, 3) + num;
}
return str.substr(0, len) + num;
}
function test2(num){
// ?= 正向匹配:匹配位置
// ?! 正向不匹配:排除位置
var str = (+num).toString();
var reg = /(?=(?!\b)(\d{3})+$)/g;
return str.replace(reg, ',');
}