She*_*kel 10 jquery html5 jquery-tools jcrop
我试图找出我的代码是否有问题或当前的HTML5 File API实现.
以下代码有效.在加载图像一次后重复该过程时会出现错误.
第二次选择文件时,图像blob加载,然后闪烁,图像消失.之后的后续选择通常可以正常工作(如果文件很大,有时会出现不稳定的行为).重复相同文件选择的过程通常有效(作为修复).
任何帮助将不胜感激.
使用的JavaScript库
JQuery 1.7.1
JQuery Tools 1.2.6
JCrop 0.9.9
步骤 - 摘要
用户通过传统<input type="file" />
对话框选择文件.
onchange处理程序为输入执行并检查是否选择了文件,如果是,则验证MIME类型是image/jpeg还是image/png,以及所选文件大小是否小于250KB.如果此验证失败,则重置选择.
此时,要上载的文件(图像)有效.接下来,它检查浏览器是否支持File API CreateObjectURL via if
(typeof window.URL == 'undefined') return;
(如果没有,则跳过后续步骤)
它将图像blob加载到当前图片预览中(一个用于显示当前图像),也加载到动态生成的图像元素中,该图像元素通过jcrop裁剪功能添加到jquery工具的叠加层中.
然后,用户通过jcrop裁剪图像并关闭叠加层,查看要上载的图像的裁剪预览(仅当浏览器支持CreateObjectURL且用户裁剪图像时)
代码
HTML
<div style="height: 100px; overflow: hidden; width: 100px; margin-bottom: 5px;">
<img id="PhotoPreview" alt="Photo" src="/Content/no-photo.png" />
</div>
<input type="file" id="Photo" name="Photo" onchange="photoChanged(this.files)" />
<input type="hidden" id="PhotoCrop" name="PhotoCrop" value="" />
Run Code Online (Sandbox Code Playgroud)
JavaScript window.URL = window.URL || window.webkitURL;
function photoChanged(files) {
if (!files.length) return;
var file = files[0];
if (file.type != 'image/jpeg' && file.type != 'image/png') {
alert('The photo must be in PNG or JPEG format');
$("#Photo").val('');
return;
}
var fileSizeLimit = 250;
var fileSize = file.size / 1024;
if (fileSize > fileSizeLimit) {
var fileSizeString = fileSize > 1024 ? (fileSize / 1024).toFixed(2) + "MB" : (fileSize).toFixed(2) + "KB";
alert("The photo file size is too large, maximum size is " + fileSizeLimit
+ "KB. This photos' file size is: " + fileSizeString);
$("#Photo").val('');
return;
}
if (typeof window.URL == 'undefined') return;
var preview = document.getElementById('PhotoPreview');
$(preview).removeClass('profile-photo');
preview.src = window.URL.createObjectURL(file);
preview.onload = function () {
var img = new Image();
$("#PhotoOverlay div").empty().append(img);
window.URL.revokeObjectURL(this.src);
img.src = window.URL.createObjectURL(file);
img.onload = function () {
window.URL.revokeObjectURL(this.src);
$(this).Jcrop({
onSelect: onImageCropSelect,
aspectRatio:
310 / 240,
minSize: [100, 100],
setSelect: [0, 0, 100, 100]
});
$("#PhotoOverlay")
.css({ width: this.width + 'px', : 'auto'})
.overlay()
.load();
};
};
}
function onImageCropSelect(e) {
$("#PhotoCrop").val(e.x + ',' + e.y + ',' + .x2 + ',' + e.y2);
var rx = 100 / e.w;
var ry = 100 / e.h;
var height = $("#PhotoOverlay div img").height();
var width = $("#PhotoOverlay div img").width();
jQuery('#PhotoPreview').css({
width: Math.round(rx * width) + 'px',
height: Math.round(ry * height) + 'px',
marginLeft: '-' + Math.round(rx * e.x) + 'px',
marginTop: '-' + Math.round(ry * e.y) + 'px'
});
}
$(function () {
$("#PhotoOverlay").overlay({
mask: {
color: '#ebecff',
loadSpeed: 200,
opacity: 0.9
}
});
});
Run Code Online (Sandbox Code Playgroud)
随意使用代码(我对此处收到的任何帮助的贡献).
更新
关于使用JCrop,我遇到了关于stackoverflow的另一个关于类似问题(图像加载然后消失)的问题.我目前打赌JCrop是罪魁祸首.
我还读到,当img.onload执行时,图像并不总是"准备好",因此奇怪的行为和对.TimeualWidth/.actualHeight的附加检查可能会解决问题.我会调查一下.
更新
我有一个使用FileReader和readAsDataUrl的概念工作证明,而不是使用CreateObjectURL并使用CANVAS绘制预览而不是基于边距的溢出:隐藏解决方案.需要一些改进然后我会在这里发布代码.
img.src
当您在声明之前设置时,通常会出现不稳定的行为img.onload
function imageLoadHandler() { ... }
var img = new Image();
img.onload = function() { imageLoadHandler() }
img.src = window.URL.createObjectURL(file);
if(img.complete) { imageLoadHandler() } //fix for browsers that don't trigger .load() event with image in cache
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助