zoukankan      html  css  js  c++  java
  • Web页面多对象多文档事件冲突的解决方案

    这段时间写了很多基于js和jquery的前端控件,每一个的功能都很复杂,事件也很多。

    因为都是单独封装的,单独使用没有问题,但把他们放到一个页面使用,就经常发生事件冲突的问题。

    这几天一直在考虑用一个什么比较好的方法解决,今天把其中一个解决方案实验了一下,感觉很不错,现在发出来,大家一起探讨下。

        window.UE_EVENT = window.UE_EVENT || {
            Key: 1,
            ClipBoard: null,
            CurrElement: null,
            CurrKey: 0,
            Events: { 'mousemove': [], 'mousedown': [], 'keypress': [], 'dblclick': [], 'mouseup': [], 'keydown': [], 'keyup': [], 'click': [], 'resize': [], 'copy': [], 'paste': [] },
            Delete: function (event, key) {
                if (!event || !key) return false;
                var e = event.toLowerCase(),l = this.Events[e];
                for (var i in l) {
                    if (l[i].KEY == key) {
                        l.splice(i, 1);
                        break;
                    }
                }
            },
            Add: function (dom, event, callback) {
                if (!dom || !event || !callback) return false;
                UE_EVENT.IsRun || UE_EVENT.Run();
                var key = UE_EVENT.SetEventKey(dom), isExists = false, e = event.toLowerCase(), l = this.Events[e];
                for (var i in l) {
                    if (l[i].KEY == key) {
                        l[i].FUN = callback;
                        isExists = true;
                    }
                }
                if (!isExists) {
                    l.push({ 'KEY': key, 'EVENT': e, 'DOM': dom[0] || dom, 'FUN': callback });
                }
            },
            Excute: function (event, e) {
                var l = this.Events[event];
                if (event == 'resize') {
                    for (var i in l) {
                        var t = l[i], d = t.DOM;
                        if (t.width != $(d).width() || t.height != $(d).height()) {
                            t.width = $(d).width();
                            t.height = $(d).height();
                            l[i].FUN(t.width, t.height, null, d);
                        }
                    }
                } else {
                    e = e || window.event;
                    var t = e.srcElement || e.target,
                        k = parseInt($(t).attr('eventkey'), 10);
                    for (var i in l) {
                        if (l[i].KEY == k || l[i].KEY == this.CurrKey) {
                            l[i].FUN(e, t, l[i].KEY, l[i].DOM);
                        }
                    }
                }
            },
            Download: function (url, json) {
                var form = $('<form style="display:none" target="ue_download_iframe" method="post" action="' + url + '"><iframe id="ue_download_iframe" name="ue_download_iframe" onload=""></iframe><input name="JsonData" value="' + JSON.stringify(json).replace(/"/g, "'") + '" /></form>').appendTo('body');
                var iframe = document.getElementById('ue_download_iframe');
                if (document.readyState) {
                    iframe.onreadystatechange = function () {
                        if (this.readyState && this.readyState == 'complete') {
                            form.remove();
                        }
                    }
                } else {
                    iframe.onload = function () {
                        form.remove();
                    }
                }
                form.submit();
            },
            SetEventKey: function (obj) {
                if (!obj) return;
                var dom = obj[0] || obj,
                    isDOM = (typeof HTMLElement === 'object') ? (dom instanceof HTMLElement) : dom && typeof dom === 'object' && dom.nodeType === 1,
                    key = isDOM ? parseInt($(dom).attr('eventkey'), 10) : dom.eventKey;
                key = key || UE_EVENT.Key++;
                if (isDOM) {
                    $(dom).attr('eventkey', key)
                } else {
                    dom.eventKey = key;
                }
                return key;
            },
            Run: function (obj) {
                if (!this.IsRun) {
                    $(document).on('mousemove', function (e) {
                        UE_EVENT.Excute('mousemove', e);
                    }).on('mousedown', function (e) {
                        UE_EVENT.Excute('mousedown', e);
                    }).on('keypress',  function (e) {
                        UE_EVENT.Excute('keypress',  e);
                    }).on('dblclick',  function (e) {
                        UE_EVENT.Excute('dblclick',  e);
                    }).on('mouseup',   function (e) {
                        UE_EVENT.Excute('mouseup',   e);
                    }).on('keydown',   function (e) {
                        UE_EVENT.Excute('keydown',   e);
                    }).on('keyup',     function (e) {
                        UE_EVENT.Excute('keyup',     e);
                    }).on('click',     function (e) {
                        UE_EVENT.CurrKey = 0;
                        UE_EVENT.Excute('click', e);
                    });
                    setInterval(function () { UE_EVENT.Excute('resize', null); }, 200);
                    //$(window).on('resize', function (e) {
                    //    UE_EVENT.Excute('resize', e);
                    //});
                    $('body').on({
                        copy: function (e) {
                            var d = window.clipboardData || e.originalEvent.clipboardData;
                            var txt = "";
                            UE_EVENT.Excute('copy', txt);
                            d.setData('Text', txt);
                            return false;
                        },
                        paste: function (e) {
                            var d = window.clipboardData || e.originalEvent.clipboardData;
                            UE_EVENT.Excute('paste', d.getData('Text'));
                        }
                    });
                }
                UE_EVENT.IsRun = true;
                return true;
            }
        };
        $.fn.SetEvent = function (event, callback) {
            return UE_EVENT.Add(this, event, callback);
        };
        $.fn.ActiveEvent = function () {
            UE_EVENT.CurrKey = UE_EVENT.SetEventKey(this);
        };


    这个方案的思路就是用单例模式,建立一个事件方法列表,就像系统的注册表一样(事实上灵感也是来自注册表),

    然后所有的插件控件的文档事件,都向这个列表集合里注册,这样需要用的时候,就能统一调度,互不冲突。

    今天做了一点调整,就是添加了dom对象的保存,同时注册的事件改为保存事件名称,这样可能比较灵活

    一改:添加了resize事件

    二改:这次改为每添加一个事件,都指定一个key值

    三改:修改resize事件为实时监控标签size变化,取消绑定body的resize事件

                添加copy和poaste事件

  • 相关阅读:
    Ansible 详细用法说明(一)
    Puppet基于Master/Agent模式实现LNMP平台部署
    推荐-zabbix原理篇
    Centos 6.x 安装Nagios及WEB管理nagiosql实现windows及linux监控指南
    CentOS 7下安装Logstash ELK Stack 日志管理系统(下)
    【Python基础学习二】定义变量、判断、循环、函数基本语法
    【Python基础学习一】在OSX系统下搭建Python语言集成开发环境 附激活码
    内联函数
    2016 科大讯飞校招研发一面二面 10.13
    hiho #1151 : 骨牌覆盖问题·二 (递推,数论)
  • 原文地址:https://www.cnblogs.com/foren/p/6009079.html
Copyright © 2011-2022 走看看