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玩的飞起,后续再写帖子吧。

  • 相关阅读:
    Phaser中很多对象都有一个anchor属性
    prelaod场景,用来显示资源加载进度
    Eclipse rap 富客户端开发总结(11) : rcp/rap与spring ibatis集成
    Eclipse rap 富客户端开发总结(10) : Rap不同系统间的差异和处理方式
    Eclipse rap 富客户端开发总结(9) : rap上传与下载
    Eclipse rap 富客户端开发总结(8) : 发布到tomcat后解决rap编码和字符集的问题
    Eclipse rap 富客户端开发总结(7) : 如何修改rap的样式
    Eclipse rap 富客户端开发总结(6) : 如何发布rap到tomcat
    Eclipse rap 富客户端开发总结(5): RAP国际化之路
    Eclipse rap 富客户端开发总结(4):如何搭建 rap 中文开发环境
  • 原文地址:https://www.cnblogs.com/sorrowx/p/6645079.html
Copyright © 2011-2022 走看看