这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
JavaScript 事件代理(委托)一般用于以下情况:1. 事件注册在祖先级元素上,代理其子级元素。可以减少事件注册数量,节约内存开销,提高性能。2. 对 js 动态添加的子元素可自动绑定事件。本文主要介绍用原生 js 实现该功能。下面跟着小编一起来看下吧
JavaScript 事件代理(委托)一般用于以下情况:
1. 事件注册在祖先级元素上,代理其子级元素。可以减少事件注册数量,节约内存开销,提高性能。
2. 对 js 动态添加的子元素可自动绑定事件。
之前一直用各种 js 库的事件代理,如 jQuery,非常方便实用。今天尝试用原生 js 实现该功能。
- var addEvent = (function () {
- if (document.addEventListener) {
- return function (element, type, handler) {
- element.addEventListener(type, handler, false);
- };
- } else if (document.attachEvent) {
- return function (element, type, handler) {
- element.attachEvent('on' + type, function () {
- handler.apply(element, arguments);
- });
- };
- } else {
- return function (element, type, handler) {
- element['on' + type] = function () {
- return handler.apply(element, arguments);
- };
- };
- }
- })(),
- getClassElements = function (parentElement, classname) {
- var all, element, classArr = [], classElements = [];
- if (parentElement.getElementsByClassName) {
- return parentElement.getElementsByClassName(classname);
- } else {
- all = parentElement.getElementsByTagName('*');
- for (var i = 0, len = all.length; i < len; i++) {
- element = all[i];
- classArr = element && element.className && element.className.split(' ');
- if (classArr) {
- for (var j = 0; j < classArr.length; j++) {
- if (classArr[j] === classname) {
- classElements.push(element);
- }
- }
- }
- }
- return classElements;
- }
- },
- delegate = function () { // 参数:element, type, [selector,] handler
- var args = arguments,
- element = args[0],
- type = args[1],
- handler;
- if (args.length === 3) {
- handler = args[2];
- return addEvent(element, type, handler);
- }
- if (args.length === 4) {
- selector = args[2];
- handler = args[3];
- return addEvent(element, type, function (event) {
- var event = event || window.event,
- target = event.target || event.srcElement,
- quickExpr = /^(?:[a-zA-Z]*#([\w-]+)|(\w+)|[a-zA-Z]*\.([\w-]+))$/,
- match,
- idElement,
- elements,
- tagName,
- count = 0,
- len;
- if (typeof selector === 'string') {
- match = quickExpr.exec(selector);
- if (match) {
- // #ID selector
- if (match[1]) {
- idElement = document.getElementById(match[1]);
- tagName = match[0].slice(0, match[0].indexOf('#'));
- // tag selector
- } else if (match[2]) {
- elements = element.getElementsByTagName(selector);
- // .class selector
- } else if (match[3]) {
- elements = getClassElements(element, match[3]);
- tagName = match[0].slice(0, match[0].indexOf('.'));
- }
- }
- if (idElement) {
- if ( tagName ? tagName === idElement.nodeName.toLowerCase() && target === idElement : target === idElement ) {
- return handler.apply(idElement, arguments);
- }
- } else if (elements) {
- for (len = elements.length; count < len; count++) {
- if ( tagName ? tagName === elements[count].nodeName.toLowerCase() && target === elements[count] : target === elements[count] ) {
- return handler.apply(elements[count], arguments);
- }
- }
- }
- }
- });
- }
- };
主要是用 apply 改变 this 的指向
- handler.apply(idElement, arguments);
- handler.apply(elements[count], arguments);
测试一下:
- <style>
- #outer {padding: 50px; background-color: lightpink;}
- #inner {padding: 30px; background-color: aliceblue;}
- #paragraph1, #paragraph3 {background-color: cadetblue}
- </style>
- <div id="outer">
- outer
- <div id="inner">
- inner
- <p id="paragraph1" class="parag1">
- paragraph1
- </p>
- <p id="paragraph2" class="parag">
- paragraph2
- </p>
- <span>
- span
- </span>
- <p id="paragraph3" class="parag">
- paragraph3
- </p>
- </div>
- </div>
- var outer = document.getElementById('outer');
- delegate(outer, 'click', function () {
- console.log(this.id); // outer
- });
- delegate(outer, 'click', 'p',
- function() {
- console.log(this.id); //点击 paragraph1 元素,输出其id为 "paragraph1"
- });
模仿 jQuery 的风格,优化代码:
- (function () {
- var $ = function (element) {
- return new _$(element);
- };
- var _$ = function (element) {
- this.element = element && element.nodeType === 1 ? element : document;
- };
- _$.prototype = {
- constructor: _$,
- addEvent: function (type, handler, useCapture) {
- var element = this.element;
- if (document.addEventListener) {
- element.addEventListener(type, handler, (useCapture ? useCapture : false));
- } else if (document.attachEvent) {
- element.attachEvent('on' + type, function () {
- handler.apply(element, arguments);
- });
- } else {
- element['on' + type] = function () {
- return handler.apply(element, arguments);
- };
- }
- return this;
- },
- getClassElements: function (classname) {
- var element = this.element, all, ele, classArr = [], classElements = [];
- if (element.getElementsByClassName) {
- return element.getElementsByClassName(classname);
- } else {
- all = element.getElementsByTagName('*');
- for (var i = 0, len = all.length; i < len; i++) {
- ele = all[i];
- classArr = ele && ele.className && ele.className.split(' ');
- if (classArr) {
- for (var j = 0; j < classArr.length; j++) {
- if (classArr[j] === classname) {
- classElements.push(ele);
- }
- }
- }
- }
- return classElements;
- }
- },
- delegate: function () { //参数:type, [selector,] handler
- var self = this,
- element = this.element,
- type = arguments[0],
- handler;
- if (arguments.length === 2) {
- handler = arguments[1];
- return self.addEvent(type, handler);
- } else if (arguments.length === 3) {
- selector = arguments[1];
- handler = arguments[2];
- return self.addEvent(type, function (event) {
- var event = event || window.event,
- target = event.target || event.srcElement,
- quickExpr = /^(?:[a-zA-Z]*#([\w-]+)|(\w+)|[a-zA-Z]*\.([\w-]+))$/,
- match,
- idElement,
- elements,
- tagName,
- count = 0,
- len;
- if (typeof selector === 'string') {
- match = quickExpr.exec(selector);
- if (match) {
- // #ID selector
- if (match[1]) {
- idElement = document.getElementById(match[1]);
- tagName = match[0].slice(0, match[0].indexOf('#'));
- // tag selector
- } else if (match[2]) {
- elements = element.getElementsByTagName(selector);
- // .class selector
- } else if (match[3]) {
- elements = self.getClassElements(match[3]);
- tagName = match[0].slice(0, match[0].indexOf('.'));
- }
- }
- if (idElement) {
- if ( tagName ? tagName === idElement.nodeName.toLowerCase() && target === idElement ? target === idElement ) {
- return handler.apply(idElement, arguments);
- }
- } else if (elements) {
- for (len = elements.length; count < len; count++) {
- if ( tagName ? tagName === elements[count].nodeName.toLowerCase() && target === elements[count] : target === elements[count] ) {
- return handler.apply(elements[count], arguments);
- }
- }
- }
- }
- });
- }
- }
- };
- window.$ = $;
- return $;
- }());
使用如下:
- var outer = document.getElementById('outer');
- $(outer).delegate('click', '.parag',
- function(event) {
- console.log(this.id);
- });
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持 phperz!
来源: http://www.phperz.com/article/17/0524/329298.html