位置: 编程技术 - 正文

jQuery技巧之让任何组件都支持类似DOM的事件管理(jquery设置important)

编辑:rootadmin

推荐整理分享jQuery技巧之让任何组件都支持类似DOM的事件管理(jquery设置important),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:jquery 设置,如何使用jquery设置一个属性值,jquery设置innerhtml,jquery render,如何使用jquery设置一个属性值,jquery 设置,jquery怎么设置属性,jquery 设置,内容如对您有帮助,希望把文章链接给更多的朋友!

本文介绍一个jquery的小技巧,能让任意组件对象都能支持类似DOM的事件管理,也就是说除了派发事件,添加或删除事件监听器,还能支持事件冒泡,阻止事件默认行为等等。在jquery的帮助下,使用这个方法来管理普通对象的事件就跟管理DOM对象的事件一模一样,虽然在最后当你看到这个小技巧的具体内容时,你可能会觉得原来如此或者不过如此,但是我觉得如果能把普通的发布-订阅模式的实现改成DOM类似的事件机制,那开发出来的组件一定会有更大的灵活性和扩展性,而且我也是第一次使用这种方法(见识太浅的原因),觉得它的使用价值还蛮大的,所以就把它分享出来了。

在正式介绍这个技巧之前,得先说一下我之前考虑的一种方法,也就是发布-订阅模式,看看它能解决什么问题以及它存在的问题。

1. 发布-订阅模式

很多博客包括书本上都说javascript要实现组件的自定义事件的话,可以采用发布-订阅模式,起初我也是坚定不移地这么认为的,于是用jquery的$.Callbacks写了一个:

(基于seajs以及《详解Javascript的继承实现》介绍的继承库class.js)

只要任何组件继承这个EventBase,就能继承它提供的on off trigger方法来完成消息的订阅,发布和取消订阅功能,比如我下面想要实现的这个FileUploadBaseView:

实际调用测试如下:

测试中,实例化了一个FileUploadBaseView对象f,并设置了它的name属性,通过on方法添加一个跟hello相关的监听器,最后通过trigger方法触发了hello的监听器,并传递了额外的两个参数,在监听器内部除了可以通过监听器的函数参数访问到trigger传递过来的数据,还能通过this访问f对象。

从目前的结果来说,这个方式看起来还不错,但是在我想要继续实现FileUploadBaseView的时候碰到了问题。你看我在设计这个组件的时候那几个订阅相关的option:

我原本的设计是:这些订阅都是成对定义,一对订阅跟某个实例方法对应,比如带before的那个订阅会在相应的实例方法(render)调用前触发,不带before的那个订阅会在相应的实例方法(render)调用后触发,而且还要求带before的那个订阅如果返回false,就不执行相应的实例方法以及后面的订阅。最后这个设计要求是考虑到在调用组件的实例方法之前,有可能因为一些特殊的原因,必须得取消当前实例方法的调用,比如调用remove方法时有的数据不能remove,那么就可以在before订阅里面做一些校验,能删除的返回true,不能删除的返回false,然后在实例方法中触发before的订阅后加一个判断就可以了,类似下面的这种做法:

但是这个做法只能在单纯的回调函数模式里实现,在发布-订阅模式下是行不通的,因为回调函数只会跟一个函数引用相关,而发布-订阅模式里,同一个消息可能有多个订阅,如果把这种做法应用到发布-订阅里面,当调用this.trigger('beforeRender')的时候,会把跟beforeRender关联的所有订阅全部调用一次,那么以哪个订阅的返回值为准呢?也许你会说可以用队列中的最后一个订阅的返回值为准,在大多数情况下也许这么干没问题,但是当我们把“以队列最后的一个订阅返回值作为判断标准”这个逻辑加入到EventBase中的时候,会出现一个很大的风险,就是外部在使用的时候,一定得清楚地管理好订阅的顺序,一定要把那个跟校验等一些特殊逻辑相关的订阅放在最后面才行,而这种跟语法、编译没有关系,对编码顺序有要求的开发方式会给软件带来比较大的安全隐患,谁能保证任何时候任何场景都能控制好订阅的顺序呢,更何况公司里面可能还有些后来的新人,压根不知道你写的东西还有这样的限制。

解决这个问题的完美方式,就是像DOM对象的事件那样,在消息发布的时候,不是简简单单的发布一个消息字符串,而是把这个消息封装成一个对象,这个对象会传递给它所有的订阅,哪个订阅里觉得应该阻止这个消息发布之后的逻辑,只要调用这个消息的preventDefault()方法,然后在外部发布完消息后,调用消息的isDefaultPrevented()方法判断一下即可:

而这个做法跟使用jquery管理DOM对象的事件是一样的思路,比如bootstrap的大部分组件以及我在前面一些博客中写的组件都是用的这个方法来增加额外的判断逻辑,比如bootstrap的alert组件在close方法执行的时候有一段这样的判断:

按照这个思路去改造EventBase是一个解决问题的方法,但是jquery的一个小技巧,能够让我们把整个普通对象的事件管理变得更加简单,下面就让我们来瞧一瞧它的庐山真面目。

2. jquery小技巧模式

1)技巧一

如果在定义组件的时候,这个组件是跟DOM对象有关联的,比如下面这种形式:

那么我们可以完全给这个组件添加on off trigger one这几个常用事件管理的方法,然后将这些方法代理到$element的相应方法上:

通过代理,当调用组件的on方法时,其实调用的是$element的on方法,这样的话这种类型的组件就能支持完美的事件管理了。

2)技巧二

jQuery技巧之让任何组件都支持类似DOM的事件管理(jquery设置important)

第一个技巧只能适用于跟DOM有关联的组件,对于那些跟DOM完全没有关联的组件该怎么添加像前面这样完美的事件管理机制呢?其实方法也很简单,只是我自己以前真的是没这么用过,所以这一次用起来才会觉得特别新鲜:

看截图中框起来的部分,只要给jquery的构造函数传递一个空对象,它就会返回一个完美支持事件管理的jquery对象。而且除了事件管理的功能外,由于它是一个jquery对象。所以jquery原型上的所有方法它都能调用,将来要是需要借用jquery其它的跟DOM无关的方法,说不定也能参考这个小技巧来实现。

3. 完美的事件管理实现

考虑到第2部分介绍的2种方式里面有重复的逻辑代码,如果把它们结合起来的话,就可以适用所有的开发组件的场景,也就能达到本文标题和开篇提到的让任意对象支持事件管理功能的目标了,所以最后结合前面两个技巧,把EventBase改造如下(是不是够简单):

实际调用测试如下

1)模拟跟DOM关联的组件

测试代码一:

在这个测试里, 我定义了一个跟DOM关联的Demo组件并继承了EventBase这个事件管理的类,给beforeRender事件和render事件都添加了一个监听,render方法中也有打印信息来模拟真实的逻辑,实例化Demo的时候用到了#demo这个DOM元素,最后的测试结果是:

完全与预期一致。

测试代码二:

在这个测试了, 我定义了一个跟DOM相关的Demo组件并继承了EventBase这个事件管理的类,给beforeRender事件添加了3个监听,其中一个有加prevetDefault()的调用,而且该回调还不是最后一个,最后的测试结果是:

从结果可以看到,render方法的主要逻辑代码跟后面的render事件都没有执行,所有beforeRender的监听器都执行了,说明e.preventDefault()生效了,而且它没有对beforeRender的事件队列产生影响。

2)模拟跟DOM无关联的普通对象

测试代码一:

在这个测试里, 我定义了一个跟DOM无关的Demo组件并继承了EventBase这个事件管理的类,给beforeRender事件和render事件都添加了一个监听,render方法中也有打印信息来模拟真实的逻辑,最后的测试结果是:

完全与预期的一致。

测试代码二:

在这个测试了, 我定义了一个跟DOM无关的Demo组件并继承了EventBase这个事件管理的类,给beforeRender事件添加了3个监听,其中一个有加prevetDefault()的调用,而且该回调还不是最后一个,最后的测试结果是:

从结果可以看到,render方法的主要逻辑代码跟后面的render事件都没有执行,所有beforeRender的监听器都执行了,说明e.preventDefault()生效了,而且它没有对beforeRender的事件队列产生影响。

所以从2个测试来看,通过改造后的EventBase,我们得到了一个可以让任意对象支持jquery事件管理机制的方法,将来在考虑用事件机制来解耦的时候,就不用再去考虑前面第一个介绍的发布-订阅模式了,而且相对而言这个方法功能更强更稳定,也更符合你平常使用jquery操作DOM的习惯。

4. 本文小结

有2点需要再说明一下的是:

1)即使不用jquery按照第1部分最后提出的思路,把第一部分常规的发布-订阅模式改造一下也可以的,只不过用jquery更加简洁些;

2)最终用jquery 的事件机制来实现任意对象的事件管理,一方面是用到了代理模式,更重要的还是要用发布-订阅模式,只不过最后的这个实现是由jquery帮我们把第一部分的发布-订阅实现改造好了而已。

以上内容是针对jQuery技巧之让任何组件都支持类似DOM的事件管理的相关知识,希望对大家有所帮助!

基于jquery fly插件实现加入购物车抛物线动画效果 先给大家展示下效果图:在购物网站中,加入购物车的功能是必须的功能,有的网站在用户点击加入购物车按钮时,就会出现该商品从点击出以抛物线

jQuery EasyUI中DataGird动态生成列的方法 EasyUI中使用DataGird显示数据列表中,有时需要根据需要显示不同的列,例如,在权限管理中,不同的用户登录后只能查看自己权限范围内的列表字段,这

jquery Deferred 快速解决异步回调的问题 jqueryDeferred快速解决异步回调的问题functionok(name){vardfd=new$.Deferred();callback:func(){returndfd.resolve(response);}returndfd.promise();}$.when(ok(1),ok(2)).then(function(resp1,resp2){

标签: jquery设置important

本文链接地址:https://www.jiuchutong.com/biancheng/384064.html 转载请保留说明!

上一篇:jQuery中的Deferred和promise 的区别(jquery中的选择器有哪些)

下一篇:基于jquery fly插件实现加入购物车抛物线动画效果(jquery.flot)

  • 减税性质代码及名称是什么意思
  • 公司缴税怎么计算的
  • 增值税计算为什么是销项减进项
  • 维保税率和维修税率是多少
  • 公司有食品流通证能卖保健品吗
  • 虚开增值税普通发票罪的立案标准
  • 月末计提账务处理
  • 没通过认证的增值税发票是否能够记入成本抵扣
  • 事业单位职工福利费支出范围
  • 退税税额要做进项税转出吗?
  • 三证合一后没有去税务局登记会怎么样
  • 淘宝开企业店铺需要什么资料
  • 在建工程转固定资产当月提折旧吗?
  • 企业的其他业务是什么
  • 电费的税费计入什么会计科目
  • 房地产土地增值税加计扣除20%
  • 股权转让的分录怎么做
  • 应用程序出现异常怎么办
  • 美元汇户和钞户的区别
  • 右键菜单中没有RAR压缩项怎么办
  • 弥补亏损的会计分录是怎样的
  • 生产经营所得投资者减除费用季度申报填吗
  • 本年利润和利润总额的关系
  • 企业雇佣临时工的工资属于工资薪金支出么
  • 高新企业研发费用占比规定
  • 高新技术产业的税收优惠
  • 增值税有哪些类型的税种
  • Yii2.0小部件GridView(两表联查/搜索/分页)功能的实现代码
  • 废旧物资处理怎么入账
  • 以前年度进项转出分录
  • 工作服计入什么明细科目
  • iozone测试结果分析
  • 报表按季度报是什么意思
  • 出纳记账凭证怎么写
  • 营业收入和营业外收入的区别
  • 接待客人的场合
  • 开票一定要确认发票吗
  • jvm jmm
  • sqlserver还原数据库一直显示正在执行0%
  • 核定征收方式包括哪几种
  • 以前年度未入账固定资产账务处理
  • 无形资产摊销是什么会计科目
  • 按信用风险特征组合
  • 融资租入固定资产的租赁费属于什么费用
  • 国外佣金代扣代缴增值税可以抵扣吗
  • 红字发票账务处理需冲回成本吗?
  • 当月发生业务下月开票如何做账
  • 收到第三方补助怎么做账
  • 按最低标准买社保30年退休后每个月领多少钱
  • 登记现金日记账收入栏的依据有
  • 增值税销项抵扣报税后有效期是多长时间
  • 培训费产生的差额怎么算
  • 弥补上年亏损所需的资金
  • 在mysql中使用什么语句来查询数据
  • sql server自定义类型怎么写入备机
  • 正确使用显微镜的七个步骤
  • window正在检查内存
  • Ubuntu Kylin 14.10默认的屏幕分辨率怎么更改?
  • mac上dns设置
  • windows10mobile官网
  • mac显示器颜色不一致
  • 运行方式包括什么方式
  • win10一年更新一次
  • zmweb.exe是什么进程
  • win10系统怎么配置交换机
  • 在linux系统中
  • win8免密码登录
  • WIN7系统还原
  • 如果打招呼了不理是什么原因
  • iframe内容自适应缩放
  • android遇到的难题
  • shell脚本检查语法
  • javascript面向对象编程
  • 深入理解计算机系统 电子书
  • 有哪些推荐阅读的书
  • 公司开票明细如何查询
  • 个人工资扣税标准计算
  • 徐州第三税务分局
  • 关税是什么
  • 代理记账公司前期准备流程
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设