Omi框架学习之旅 - 插件机制之omi-finger 及原理说明
以前那篇我寫的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;width: 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); // 具有插件名屬性的domnodes.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玩的飛起,后續再寫帖子吧。
轉載于:https://www.cnblogs.com/sorrowx/p/6645079.html
總結
以上是生活随笔為你收集整理的Omi框架学习之旅 - 插件机制之omi-finger 及原理说明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “535Wp高效单晶双面双玻组件日集电能
- 下一篇: 柴油机排气管出柴油是什么原因?