MUI

mui简介

  • MUI不依赖任何第三方JS库,原生UI(MUI以iOS平台UI为基础,补充部分Android平台特有的UI控件),结合H5 plus可实现更解决原生的APP应用
  • APP开发类型:原生开发、H5开发、混合开发(Hybrid App:一部分功能用native构建,一部分功能用html5构建,比如AppCan、PhoneGap(Cordova)等)
  • 官网:http://dev.dcloud.net.cn/mui/

事件

  • js的addEventListener()方法只能监听某个特定元素上的事件(只能通过id获取元素,或者window对象等)
  • 可以使用.on()方法实现批量元素的事件绑定

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    mui(".mui-table-view").on('tap', '.mui-table-view-cell', function(){
    //获取id
    var id = this.getAttribute("id");
    //传值给详情页面,通知加载新数据
    mui.fire(detail,'getDetail',{id:id});
    //打开新闻详情
    mui.openWindow({
    id:'detail',
    url:'detail.html'
    });
    })
    • tap为mui定义的点击时间
    • mui(".mui-table-view")根据class获取对象,只能获取非动态加入的DOM
    • 此处实际是监听.mui-table-view下的.mui-table-view-cell的点击事件
  • <a>标签点击无法跳转到href指定的连接,解决办法见下文

mui零散知识

  • H5底部导航跳转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<nav class="mui-bar mui-bar-tab">
<a data-href="index.html" class="mui-tab-item sm-href" href="javascript:;">
<span class="mui-icon mui-icon-home"></span>
<span class="mui-tab-label">首页</span>
</a>
<a data-href="#" class="mui-tab-item sm-href" href="javascript:;">
<span class="mui-icon mui-icon-contact"></span>
<span class="mui-tab-label">活动</span>
</a>
<a data-href="home.html" class="mui-tab-item sm-href mui-active" href="javascript:;">
<span class="mui-icon mui-icon-contact"></span>
<span class="mui-tab-label">我的</span>
</a>
</nav>
1
2
3
4
5
6
7
8
9
10
11
12
// a标签点击跳转:解决mui的a标签href无法跳转
bindSmHref(document.getElementsByClassName("sm-href"));
function bindSmHref(pageTabs) {
for(var i=0; i < pageTabs.length; i++) {
pageTabs[i].addEventListener('tap', function(event) {
var href = this.getAttribute("data-href");
if(href != null && href != "") {
window.location.href = href;
}
}, false);
}
}
  • popover弹框、scroll滚动
    • popover参数二为锚点元素(anchorElement),标识弹框是基于某个元素的。如果
1
2
3
4
5
6
7
8
9
<div id="popover" class="mui-popover"><!--默认隐藏, dom在body下即可-->
<div class="mui-scroll-wrapper">
<div class="mui-scroll">
<div style="padding: 10px;"><!--mui-scroll下是真实dom,需要里面元素有padding则需要调解此div-->
这里是内容
</div>
</div>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
(function(mui, window, document, undefined) {
mui.init();

// 初始化滚动条
mui('.mui-scroll-wrapper').scroll({});

// 当mybtn按钮被点击时,弹框显示隐藏切换
document.getElementById("mybtn").addEventListener('tap', function(event) {
mui("#popover").popover("toggle", document.getElementById("popoverRef")); // 如果弹框居中,则只需要参考popoverRef元素为居中
});
})(mui, window, document, undefined);
1
2
3
4
5
6
7
8
9
10
#popover {
height: 500px;
width: 85%;
/*
display: block;
top: 0px;
left: 5%;
overflow: auto;
*/
}
  • 图片上传,下列方法可解决mui示例中h5页面拍照无法上传问题(缺点:上传到后台无法记录文件类型,无文件后缀)
    • 利用canvas将图片转成base64并压缩 -> 将base64的dataUrl转成Blob -> 将Blob放入到FormData -> xhr
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// =======
// 图片上传: 利用canvas将图片转成base64并压缩 -> 将base64的dataUrl转成Blob -> 将Blob放入到FormData -> xhr
// =======
/*
var smImg = new SmUploadImg();
smImg.init({
inputs: document.getElementById(".sm-input__img"),
callback: function(base64, target) {
// formData.append(target.id, this.dataUrltoBlob(base64));
}
});
*/
SmUploadImg = function() {
this.sw = 0;
this.sh = 0;
this.tw = 0;
this.th = 0;
this.scale = 0;
this.maxWidth = 0;
this.maxHeight = 0;
this.maxSize = 0;
this.fileSize = 0;
this.fileDate = null;
this.fileType = '';
this.fileName = '';
this.inputs = null;
this.canvas = null;
this.mime = {};
this.type = '';
this.target = null;
this.toastr = null;
this.callback = function () {};
this.loading = function () {};
};

/**
* @description 初始化对象
*/
SmUploadImg.prototype.init = function(options) {
this.maxWidth = options.maxWidth || 800;
this.maxHeight = options.maxHeight || 600;
this.maxSize = options.maxSize || 5 * 1024 * 1024; // 图最大大小(5M)
this.inputs = options.inputs; // 文件输入框(可多个)
this.mime = {
'png': 'image/png',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'bmp': 'image/bmp'
};
// 提示函数
this.toastr = options.toastr || null;
// 图片加载完后返回base64
this.callback = options.callback || function() {};
// 读取图片时调用
this.loading = options.loading || function() {
// console.log("loading...");
};

this._addEvent();
};

/**
* @description 将base64的dataUrl转换成Blob对象
*/
SmUploadImg.prototype.dataUrltoBlob = function(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
};

/**
* 为新加入Dom的元素绑定事件
* @param {Object} inputs
*/
SmUploadImg.prototype.addInputs = function(inputs) {
this._addEvent(inputs);
};

/**
* @description 绑定事件
* @param {Object} elm 元素
* @param {Function} fn 绑定函数
*/
SmUploadImg.prototype._addEvent = function(inputs) {
var _this = this;

function tmpSelectFile(ev) {
_this._handelSelectFile(ev);
}

if(!inputs)
inputs = _this.inputs;
if(inputs.length || inputs.length == 0) {
for(var i=0; i < inputs.length; i++) {
inputs[i].addEventListener('change', tmpSelectFile, false);
}
} else if(inputs) {
inputs.addEventListener('change', tmpSelectFile, false);
}
};

/**
* @description 绑定事件
* @param {Object} elm 元素
* @param {Function} fn 绑定函数
*/
SmUploadImg.prototype._handelSelectFile = function(ev) {
var file = ev.target.files[0];

this.type = file.type;
this.target = ev.target;

// 如果没有文件类型,则通过后缀名判断(解决微信及360浏览器无法获取图片类型问题)
if(!this.type) {
this.type = this.mime[file.name.match(/\.([^\.]+)$/i)[1]];
}

if(!/image.(png|jpg|jpeg|bmp)/.test(this.type)) {
var msg = '不支持此文件类型';
this.toastr ? this.toastr(msg) : alert(msg);
this.target.value = "";
return;
}

if(file.size > this.maxSize) {
var msg = '选择文件大于' + this.maxSize / 1024 / 1024 + 'M,请重新选择';
this.toastr ? this.toastr(msg) : alert(msg);
this.target.value = "";
return;
}

this.fileName = file.name;
this.fileSize = file.size;
this.fileType = this.type;
this.fileDate = file.lastModifiedDate;

this._readImage(file);
};

/**
* @description 读取图片文件
* @param {Object} image 图片文件
*/
SmUploadImg.prototype._readImage = function(file) {
var _this = this;

function tmpCreateImage(uri) {
_this._createImage(uri);
}

this.loading();

this._getURI(file, tmpCreateImage);
};

/**
* @description 通过文件获得URI
* @param {Object} file 文件
* @param {Function} callback 回调函数,返回文件对应URI
* return {Bool} 返回false
*/
SmUploadImg.prototype._getURI = function(file, callback) {
var reader = new FileReader();
var _this = this;

function tmpLoad() {
// 头不带图片格式,需填写格式
var re = /^data:base64,/;
var ret = this.result + '';

if(re.test(ret))
ret = ret.replace(re, 'data:' + _this.mime[_this.fileType] + ';base64,');

callback && callback(ret, this.target);
}

reader.onload = tmpLoad;

reader.readAsDataURL(file);

return false;
};

/**
* @description 创建图片
* @param {Object} image 图片文件
*/
SmUploadImg.prototype._createImage = function(uri) {
var img = new Image();
var _this = this;

function tmpLoad() {
_this._drawImage(this);
}

img.onload = tmpLoad;

img.src = uri;
};

/**
* @description 创建Canvas将图片画至其中,并获得压缩后的文件
* @param {Object} img 图片文件
* @param {Number} width 图片最大宽度
* @param {Number} height 图片最大高度
* @param {Function} callback 回调函数,参数为图片base64编码
* return {Object} 返回压缩后的图片
*/
SmUploadImg.prototype._drawImage = function(img, callback) {
this.sw = img.width;
this.sh = img.height;
this.tw = img.width;
this.th = img.height;

this.scale = (this.tw / this.th).toFixed(2);

if(this.sw > this.maxWidth) {
this.sw = this.maxWidth;
this.sh = Math.round(this.sw / this.scale);
}

if(this.sh > this.maxHeight) {
this.sh = this.maxHeight;
this.sw = Math.round(this.sh * this.scale);
}

this.canvas = document.createElement('canvas');
var ctx = this.canvas.getContext('2d');

this.canvas.width = this.sw;
this.canvas.height = this.sh;

ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, this.sw, this.sh);

this.callback(this.canvas.toDataURL(this.type), this.target);

ctx.clearRect(0, 0, this.tw, this.th);
this.canvas.width = 0;
this.canvas.height = 0;
this.canvas = null;
};
ChatGPT开源小程序