autobind.js
3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* TODO:
* 1. 移除getMecJson, 插件内部操作直接更新data
* 2. data -> view
* 3. 细粒度数据更新
*/
define(['autobind/utils'], function (_u) {
function _AutoBind(cfg) {
this.$container = $(cfg.container);
this.$el = _u.getEles(cfg.container);
this.handler = cfg.handler;
this.defaultPropKey = cfg.defaultPropKey;
this.render = cfg.render;
}
_AutoBind.prototype = {
bindEvent: function () {
var handler = this.handler;
var defaultPropKey = this.defaultPropKey;
var t = this;
_u.event(this.$container, function (e) {
var eventType = _u.getEvtType(this);
var keyCode = e.keyCode || window.event.keyCode;
// 当前事件类型是否与元素类型匹配
if (eventType.indexOf(e.type)<0) return;
if(e.type === 'keydown' && keyCode !== 13) return;
var propName = _u.getPropName(this) || defaultPropKey;
var _handler = handler[propName];
var value = _handler ? _handler.get() : this.value;
t.render(propName, value);
});
}
};
return function AutoBind(settings) {
var defaultConfig = {
container: document.body,
target: {}, // eg. { name: 'x' }
handler: {}, // eg. { name: {get: Function}}
defaultPropKey: '', // 针对只有一个key的情况 data-prop
render: function () { }
};
var cfg = $.extend(defaultConfig, settings);
var _autobind = new _AutoBind(cfg);
_autobind.bindEvent();
// 手动更新
this.update = function (propKey, value) {
var len = arguments.length;
if (len === 0) {
propKey = cfg.defaultPropKey;
value = cfg.handler[propKey].get();
}
cfg.target[propKey] = value;
cfg.render(propKey, value);
};
};
});
define('autobind/utils', function () {
var sign_key = '[data-autobind]';
var prop_key = 'data-autobind';
var namespace = '__autobind__';
return {
getEles: function (el) {
var $el = $(el);
return $el.find(sign_key);
},
hasPropKey: function (el) {
return el.hasAttribute(prop_key);
},
getPropName: function (el) {
return $(el).attr(prop_key);
},
event: function ($el, callback) {
var evts = ['focusout', 'change', 'click', 'keydown'].map(function (evt) {
return evt + "." + namespace;
}).join(' ');
$el.off(evts, sign_key)
.on(evts, sign_key, callback);
},
getEvtType: function (el) {
var tagName = el.tagName.toLowerCase();
var inputType = el.type;
switch (tagName) {
case 'input':
if (inputType !== 'text' && inputType !== 'number') {
return 'click';
}
case 'textarea':
return 'focusout keydown';
case 'select':
return 'change';
default:
return 'click';
}
}
};
});