图片上传
form上传
<form action='' method='post' enctype='multipart/form-data'>
<input type='file' />
</form>
ajax上传
<form>
<input type='file' id='file' v-on:change='uploadPic($event)' />
</form>
<script>
uploadPic : function (event) {
var formData = new FormData();
formData.append('file', event.target.files[0]);
$.ajax({
url : '',
type: 'POST',
data : formData,
processData : false,// 数据不被序列化
contentType : false,// 避免设置Content-Type请求头
success : function(res) {},
error : function(err) {}
});
}
</script>
FileReader
利用
FileReader
对象,将input中的file对象,以base64转码的形式读取出来
<input type="file" class="inp-img-file" name='image' accept='image/*' v-on:change='uploadPic($event)'>
<img :src='result' />
<script>
uploadPic : function (event) {
var file = event.target.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
var result = this.result; // data:base64
self.uploadImg({'fileName':file.name, 'base64' : result});
};
}
</script>
window.URL.createObjectURL + canvas
-
<input type='file'>
,部分手机没有相机功能,必须加上accept='image/*'
才能调用相机,然而accept='image/*'
没法使用fileReader
,因此只能使用window.URL.creatObjectURL
; -
creatObjectURL
是浏览器自带的接口,性能相对来说较好,处理更快; - 低版本浏览器图片预览只能用滤镜了...
- canvas主要做了图片压缩(
drawImage()
)以及图片转base64(toDataURL()
)功能.
遇到的问题
- 相机拍照后上传图片没反应.
原因:<input type='file'>
使用了accept='image/*'
,导致无法使用fileReader
,取不到图片,直接报错.
解决:将fileReader
换成window.URL.creatObjectURL
. - 相机拍照上传图片,报
413 request Entity too Large
错误.
原因:图片过大.
解决:利用canvas
做图片压缩处理,3M的图片压缩完后大概200多KB.
<input type="file" class="inp-img-file" name='image' accept='image/*' v-on:change='uploadPic($event)'>
<script>
uploadPic : function (event) {
var file = event.target.files[0];
var URL = window.URL || window.webkitURL;
var blob = URL.createObjectURL(file);// 获取图片的地址
var img = document.createElement('img');
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
img.src = blob;
img.onload = function() {
var width = img.width;
var height = img.height;
var targetWidth, targetHeight;
if (width >= height) {
targetWidth = Math.min(600, width); // 宽度最大为600,超过600,宽高等比压缩
targetHeight = height * (targetWidth / width);
} else {
targetHeight = Math.min(600, height);
targetWidth = width * (targetHeight / height);
}
canvas.width = targetWidth;
canvas.height = targetHeight;
ctx.drawImage(img, 0, 0, width, height, 0, 0, targetWidth, targetHeight);// 图片压缩
var dataURL = canvas.toDataURL("image/" + file.type);// 转base64
self.uploadImg({'fileName':file.name, 'base64' : dataURL});
}
}
</script>
复制粘贴
Clipboard.js
<li :class="['flex', 'clip-span' + index]" :data-index='index' v-on:touchstart='copyDataToClipboard(item.content)'>复制</li>
<script>
copyDataToClipboard : function(content){
var self = this, contentStr = '';
contentStr = self.unique(content);
if (C.Adapter.isNative) {// app
C.Adapter.copyDataToClipboard({'data' : contentStr});
C.UI.tip('复制成功!');
} else {
var clipboard = new Clipboard('.clip-span' + event.target.dataset.index);
clipboard.on('success', function(e) {
C.UI.tip('复制成功!');
e.clearSelection();
});
clipboard.on('error', function(e) {
C.UI.tip('请长按文本进行复制!');
});
}
}
</script>
js原生简单实现,直接调用
document.execCommand('Copy');
即可.
execCommand API、 Selection API
Passive
Passive Event Listeners,为了解决浏览器页面滑动流畅度而设计的,它通过扩展事件属性passive让Web开发者来告知浏览器监听器是否会阻止事件的默认行为,从而让浏览器可以更智能地决策并优化.
target.addEventListener(type, listener[, useCapture, wantsUntrusted ]);
useCapture 参数用来控制监听器是在捕获阶段执行还是在冒泡阶段执行,true 为捕获阶段,false 为冒泡阶段,默认false
// 由于第三个参数没有传值,那么默认就是 false,事件会在冒泡阶段被处理
document.addEventListener("touchstart", function(e){
// do sth.
});
- 如果我们在事件处理函数中调用了
stopPropagation()
,那么之后的元素就无法接收这个事件,也即是剩余的事件处理函数永远不会得到执行; - 如果我们在事件处理函数中调用了
preventDefault()
,那么元素的默认行为就会被取消。
eg:一个 a 标签绑其 click 事件的默认行为是跳转到 href 指定的链接,但是如果我们在click事件处理函数里面调用了preventDefault
方法后,其默认的的行为就被取消了。 - 那么问题来了:由于浏览器无法预先知道一个事件处理函数中会不会调用
preventDefault()
,它需要等到事件处理函数执行完后,才能去执行默认行为,然而事件处理函数执行是要耗时的,这样一来就会导致页面卡顿.所以passive
就出现了.
document.querySelector('.scroll-wrap').addEventListener('touchstart', listener, {passive: true});
document.querySelector('.scroll-wrap').removeEventListener('touchstart', listener);
通过传递
{passive: true}
来明确告诉浏览器,事件处理程序不会调用preventDefault
来阻止默认滑动行为vue中
passive
修饰符
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
vue(2.3.0) 以 { passive: true } 模式添加侦听器