手写事件侦听器,并要求兼容浏览器
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, ',');
}