`
fjguodong
  • 浏览: 39386 次
社区版块
存档分类
最新评论

javasript中主动触发事件的方法

阅读更多

对于实现事件触发器,浏览器都有原生的方法来支持,但是在兼容性上又有很大的出入,这种兼容性的问题完全在意料之中,IE有自己的方法,其他标准浏览器也有一套方法,不说谁的方法好与不好,对于WEB开发者来说搞出几套方法就是对开发人员的一种折磨。IE支持fireEvent方法来实现事件触发,标准浏览器支持dispatchEvent来实现事件触发,两面派的IE9是两者都支持。下面是出自prototype.js的源码(其实我是从司徒正美的博客复制过来的):

    var fireEvent = function(element,event){
        if (document.createEventObject){
            // IE浏览器支持fireEvent方法
            var evt = document.createEventObject();
            return element.fireEvent('on'+event,evt)
        }
             else{
            // 其他标准浏览器使用dispatchEvent方法
            var evt = document.createEvent( 'HTMLEvents' );
            // initEvent接受3个参数:
            // 事件类型,是否冒泡,是否阻止浏览器的默认行为
            evt.initEvent(event, true, true); 
            return !element.dispatchEvent(evt);
        }
    };

 上面的方法可以兼容主流的浏览器以实现事件触发器的功能。但是对于一些封装好的事件处理系统,如jQuery的event模块,就没这么简单了,只能通过模拟来实现了。我在之前写过一个很简单的事件处理系统,最近又碰到自定义事件的需求,于是在之前的事件系统的基础上模拟了一个事件触发器,代码如下:

    /**
     * 事件触发器
     * @param { Object } DOM元素
     * @param { String / Object } 事件类型 / event对象
     * @param { Array }  传递给事件处理函数的附加参数
     * @param { Boolean } 是否冒泡
     */
    trigger : function( elem, event, data, isStopPropagation ){
        var type = event.type || event,
            // 冒泡的父元素,一直到document、window
            parent = elem.parentNode ||
                elem.ownerDocument ||
                elem === elem.ownerDocument && win,
            eventHandler = $.data( elem, type + 'Handler' );
 
        isStopPropagation = typeof data === 'boolean' ?
            data : (isStopPropagation || false);
 
        data = data && isArray( data ) ? data : [];
 
        // 创建自定义的event对象       
        event = typeof event === 'object' ?
            event : {
                type : type,
                preventDefault : noop,
                stopPropagation : function(){
                    isStopPropagation = true;
                }
            };
 
        event.target = elem;       
        data.unshift( event );
        if( eventHandler ){
            eventHandler.call( elem, data );
        }
        // 递归调用自身来模拟冒泡
        if( parent && !isStopPropagation ){
            data.shift();
            this.trigger( parent, event, data );
        }
    }

 模拟的原理并不难,给某元素绑定一个事件处理函数,如果有触发事件的实际操作就会执行相应的事件处理函数,所以要达到事件触发器的功能只要获取到相应的事件处理函数然后执行就差不多了,这是最基本的。

在实际的事件发生时浏览器会生成一个event对象,里面包含了一些事件发生时的属性和信息。如果没有实际的事件发生是没有这个event对象的,所以上面的代码也创建了一个event对象满足最基本的功能。

还有事件冒泡,如果没有实际的事件发生,自然也不会有冒泡的行为,那么如果要模拟冒泡的功能,就必须不断的查找父元素并检查是否绑定了相同类型的事件,直至到document和window为止,如果结构复杂,这种递归调用的方法性能估计会不怎么样。

最后是浏览器的默认行为,我觉得这个要去模拟相当麻烦,麻烦到不知如何去实现,比如a标签默认的跳转,我测试了jQuery的trigger,也没有实现,但是一些其他的行为貌似又在API手册中有介绍。毕竟这个功能不是很重要,暂时也没做过多的深究,下面是一些演示。

 

原载于:雨夜带刀’s Blog
本文链接:http://iamxz.com/%E4%B8%BB%E5%8A%A8%E8%A7%A6%E5%8F%91%E4%BA%8B%E4%BB%B6%E7%9A%84%E6%96%B9%E6%B3%95/
如需转载请以链接形式注明原载或原文地址。

尊重文章原作者,转载请注明: 转载自原作者地址

 

分享到:
评论

相关推荐

    javascript 主动派发事件总结

    2,fireEvent() 这是IE旧版本中实现的触发事件方法,它无须创建事件对象,直接使用。如下 代码如下: element.fireEvent(‘onclick’); 注意:与attachEvent一样它需要加上“on” 一个兼容性所有浏览器的版本,如下 ...

    TreeNodeCheckChanged事件触发方法代码实例

    这个事件不会主动postback,需要手动写javascript触发。对网上找到的方法做了些改进,增加UpdatePanel,以免页面不停的刷。这里就不考虑性能神马的了,因为既然项目已经允许选择使用TreeView服务器控件了,也就不要...

    JS打开新窗口防止被浏览器阻止的方法

    第一种、使用原生javascript的window.open()方法(大部分情况下会被浏览自阻止) 第二种、模拟表单(form)提交,原理是指定表单的action为想要打开的URL地址,target设置为”_blank” 代码如下:document.ge

    JavaScript原生实现观察者模式的示例

    观察者模式又叫做发布订阅模式,它...在JavaScript中事件监听机制就可以理解为一种观察者模式。通过onclick进行事件绑定,然后通过交互行为进行触发或者事件主动触发。 下面给出一个JS自定义的PubSub,仔细阅读下面这段

    crawlergo使用chrome headless模式进行URL收集的浏览器爬虫

    它对整个网页的关键位置与DOM渲染阶段进行HOOK,自动进行表单填充并提交,配合智能的JS事件触发,尽可能的收集网站暴露出的入口。内置URL去重模块,过滤掉了大量伪静态URL,对于大型网站仍保持较快的解析与抓取速度...

    java面试宝典

    116、JavaScript中的对象. 25 117、function的用法 26 118、对象的继承 27 119、this的用法 29 120、Array in JavaScript 29 121、jsp有哪些内置对象?作用分别是什么? 31 122、jsp有哪些动作?作用分别是什么? 31 123...

    千方百计笔试题大全

    116、JavaScript中的对象. 25 117、function的用法 26 118、对象的继承 27 119、this的用法 29 120、Array in JavaScript 29 121、jsp有哪些内置对象?作用分别是什么? 31 122、jsp有哪些动作?作用分别是什么? 31 123...

    Silverlight2.0功能展示Demo源码

    MouseLeave - 鼠标离开时触发的事件(显然,此事件不能冒泡) MouseLeftButtonDown - 鼠标左键单击按下时触发的事件 MouseLeftButtonUp - 鼠标左键单击按下并放开时触发的事件 MouseMove - 鼠标移动时触发的事件 ...

    sanity-plugin-vercel-deploy:自定义插件可触发来自Sanity Studio的Webhook

    :sparkles: 实时状态更新 :sparkles: 多个部署 :sparkles: 主动投票 :sparkles: Vercel团队支持 :sparkles:安装使用Sanity CLI在您的studio文件夹中运行以下命令:sanity install vercel-deploy :warning: 注意:...

    dreamweaver的各种组件

    Animate Images 它可以使用JPG的格式也可以用动态的形式表现出来,并且您可以定义触发动作,获得最大的主动! Add Favourite 将网站加入使用者的“收藏夹” AllowDynamicFont 使用动态文字, 就是可以自动载入设定...

    Cnode:仿cnode社区微信小程序

    下拉刷新进行请求后,需要主动触发停止下拉刷新;解决方法:onPullDownRefresh: function() { this.getData()//刷新时请求服务器的方法 wx.stopPullDownRefresh();//为停止当前页面下拉刷新}注意:setData()同react的...

    Active-Auras

    DAE的宏在应用时将触发一次,在删除时将触发一次(正在做一段时间的破坏效果) “不活动时应用”选项允许效果传播到其他令牌,而不应用到Aura令牌。 这对于不影响效果所有者的Debuff样式效果很有用 保护光环的演示...

    layui-soul-table:layui-table 表头筛选、列顺序调整、列快速隐藏、excel导出等

    子表(表中表、无限层级、子表同样支持前3个功能) 5.拖动行 6.右击快捷菜单 7.合计栏支持固定列 8.双击自适应列宽 9.右侧固定列 列宽拖动改到单元格左侧 效果 1.表头筛选效果 2.编辑筛选效果 筛选明代姓张的 或 ...

    测试培训教材

    1、测试流程管理、测试度量方法 按照尽早进行测试的原则,测试人员应该在需求阶段就介入,并贯穿软件开发的全过程。就测试过程本身而言,应该包含以s下几个阶段。  -测试需求的分析和确定。  -测试计划。  -...

Global site tag (gtag.js) - Google Analytics