zoukankan      html  css  js  c++  java
  • Omi框架学习之旅

    以前那篇我写的alloyfinger源码解读那篇帖子,就说过这是一个很好用的手势库,hammer能做的,他都能做到,

    而且源码只有350来行代码,很容易看懂。

    那么怎么把这么好的库作为omi库的一个插件呢,使dom,用起来更爽,更方便呢?

    omi自己有个叫插件体系的功能,主要是赋予dom元素一些能力,并且可以和组件的实例产生关联。

    这当然棒极了。那怎么实现的呢?

    还是先看个demo,看看用起来爽不,爽的话,再看原理也不迟啊。

            OmiFinger.init();    // 初始化OmiFinger插件
    
            class App extends Omi.Component {
                constructor(data) {
                    super(data);
                }
    
                style() {
                    return  `
                        .touchArea{
                            background-color: green;
                             200px;
                            min-height: 200px;
                            text-align: center;
                            color:white;
                            height:auto;
                        }
                     `;
                }
    
                tap(evt) {
                    console.log(this.refs.div1);
                    this.refs.ptext.innerHTML = 'tap';
                }
    
                longTap(evt) {
                    console.log(evt);
                    this.refs.ptext.innerHTML = 'longTap';
                }
    
                swipe(evt) {
                    this.refs.ptext.innerHTML = evt.direction;
                }
    
                render() {
                    return  `
                    <div>
                        <div omi-finger class="touchArea" tap="tap" longTap="longTap" swipe="swipe" ref="div1">    <!--在这里写事件名即可-->
                            Tap or Swipe Me!
                            <p ref="ptext"></p>
                        </div>
                    </div>
                    `;
                }
    
            }
    
            var app = new App();
            Omi.render(app, 'body');

    看下结果:

    我热,就是这么简单,就把rotate  touchStart  multipointStart  multipointEnd  pinch  swipe  tap  doubleTap  longTap  singleTap  pressMove  touchMove  touchEnd  touchCancel这14个事件都能赋给dom去监听相应的实例函数。

    的确很方便,很omi,一个类(哦,不,一个组件(大家都喜欢叫组件,我内心是拒绝的))管理一切啊。

    demo的疑问和疑问的说明:

    疑问一:

    那omi是怎么做到的啊?

    答: 其实omi的插件机制代码很少,少的可怜,只是作为Component原型上_execPlugins方法,当然少不了和omi挂钩了,Omi上有个plugins对象属性,里面专门放插件名及插件函数的。

          那就一步一步来吧。

          demo上的OmiFinger.init();其实就是把初始化了一个插件,放到omi.plugins上去了,仅此而已,没帮我们做别的。来看源码

         

        Omi.plugins = {};    // omi插件集合
    
        // 扩展插件的方法(其实是给了plugins这个对象)
        Omi.extendPlugin = function(name, handler) {
            Omi.plugins[name] = handler;
        };

    再来看一下OmiFinger.init();方法是不是调用了Omi.extendPlugin方法

    var OmiFinger = {};
        var noop = function(){ };
    
        var getHandler = function(name, dom, instance) {
            var value = dom.getAttribute(name);    // 从属性上获取对应的函数名
            if (value === null) {
                return noop;
            }else{
                return instance[value].bind(instance);    // 从类上找到对应的方法
            };
        };
    
        OmiFinger.init = function(){
            Omi.extendPlugin('omi-finger',function(dom, instance){
                if (!instance.alloyFingerInstances) instance.alloyFingerInstances = [];    // finger的实例都存到这里面
                var len = instance.alloyFingerInstances.length;
                var i = 0;
                for( ; i<len; i++){
                    if(instance.alloyFingerInstances[i].dom === dom){    // 如果以前绑定过得, 就先销毁, 然后重新來过
                        instance.alloyFingerInstances[i].fg.destroy();
                        instance.alloyFingerInstances.splice(i,1);    // 并且剔除
                        break;
                    };
                };
                var alloyFinger = new AlloyFinger(dom,{
                    touchStart: getHandler('touchStart', dom, instance),
                    touchMove: getHandler('touchMove', dom, instance),
                    touchEnd: getHandler('touchEnd', dom, instance),
                    touchCancel: getHandler('touchCancel', dom, instance),
                    multipointStart: getHandler('multipointStart', dom, instance),
                    multipointEnd: getHandler('multipointEnd', dom, instance),
                    tap: getHandler('tap', dom, instance),
                    doubleTap: getHandler('doubleTap', dom, instance),
                    longTap: getHandler('longTap', dom, instance),
                    singleTap: getHandler('singleTap', dom, instance),
                    rotate: getHandler('rotate', dom, instance),
                    pinch: getHandler('pinch', dom, instance),
                    pressMove: getHandler('pressMove', dom, instance),
                    swipe: getHandler('swipe', dom, instance)
                });
                instance.alloyFingerInstances.push({fg:alloyFinger,dom:dom});
            });
        }
    
        OmiFinger.destroy = function(){
            delete Omi.plugins['omi-finger'];
        };
        
        window.OmiFinger = OmiFinger;

    这里我把代码都贴出来,因为比较简单。

    Omi.plugins有了对象插件名和函数,那是怎么循环遍历的呢?

    其实就在Component类的_render方法最后面,遍历的,也就是当html插入到指定容器后,再调用的。

    那是怎么调用的呢?

        // 插件机制
        _execPlugins(){
            Object.keys(Omi.plugins).forEach(item => {    // 遍历omi的插件
                let nodes = Omi.$$('*['+item+']',this.node);    // 具有插件名属性的dom
                nodes.forEach(node => {
                    if(node.hasAttribute(this._omi_scoped_attr) ) {    // 节点是否含有_omi_scoped_id属性
                        Omi.plugins[item](node, this);    // 调用插件init方法中第二个函数
                    };
                });
                if(this.node.hasAttribute(item)) {    // 看一下根节点是否含有插件名属性,有的话也执行
                    Omi.plugins[item](this.node, this);
                };
            });
        }

    可以看到,会传2个参数,一个dom,一个实例.正是验证了官网的这句话。 Omi插件体系可以赋予dom元素一些能力,并且可以和组件的实例产生关联。

    至此就这么说完了。

    ps: 

         当然还有transform.js, touch.js也可以让dom玩的飞起,后续再写帖子吧。

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
    Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
    Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
    Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
    Java实现 蓝桥杯VIP 算法提高 士兵排队问题
    Java实现 蓝桥杯VIP 算法提高 士兵排队问题
    Java实现 蓝桥杯VIP 算法提高 士兵排队问题
    Java实现 蓝桥杯VIP 算法提高 士兵排队问题
    Java实现 蓝桥杯VIP 算法提高 数字黑洞
    Minifilter微过滤框架:框架介绍以及驱动层和应用层的通讯
  • 原文地址:https://www.cnblogs.com/sorrowx/p/6645079.html
Copyright © 2011-2022 走看看