【发布时间】:2014-01-20 20:05:12
【问题描述】:
我在生成我选择的图像文件的实时预览的脚本时遇到问题。问题是,当我使用文件输入选择文件时,内存会出现峰值,因此我的 on('change') 方法触发得太晚,无法获得有用的用户响应。现在,如果我按 Ctrl+F5,有时浏览器会变得更加灵敏,并且会非常快速地生成预览。延迟不在于图像数据的内联,而在于用户在文件对话框中选择“打开”与触发 onChange 事件之间的时间。我不知道如何跟踪这两个事件之间发生的事情。
我通过 CSS 定位隐藏了 HTML 文件输入标记,并在我单击单独的 span 元素时触发了单击事件。输入标签注册了 on('change') 函数。在更改时,我通知用户正在生成图像预览。生成完成后,我通知“预览完成”。正如我之前所说,由于内存峰值导致 onchange 事件滞后,我最终没有看到中间的“请稍候......”文本。这在 Firefox 和 Chrome 中都会发生。
javascript
var imageSelectClass = '';
var imageSelectDefaultBGSize = 'auto';
var imageSelectWorkingBGSize = '100%';
var imageSelectDefaultUrl = '';
var imageSelectNoPreviewUrl = '';
function resetImageSelection(resetImage, toOriginalImage) {
$('.image-select-text').text("");
$('.image-select-text').css("opacity", 1);
$('.' + imageSelectClass).css('backgroundSize', imageSelectDefaultBGSize);
if (resetImage) {
if (toOriginalImage) $('.' + imageSelectClass).css('backgroundSize', imageSelectWorkingBGSize);
if (imageSelectDefaultUrl != imageSelectNoPreviewUrl) {
$('.' + imageSelectClass).css('backgroundImage', "url('" + (toOriginalImage ? imageSelectDefaultUrl : imageSelectNoPreviewUrl) + "')");
}
}
}
function handleImageSelection(evt) {
// Clear the photo box
resetImageSelection(true, true);
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
evt.preventDefault();
resetImageSelection(true, true);
$('#' + imageSelectClass).replaceWith($('#' + imageSelectClass).clone());
makeIntoImageSelection(imageSelectClass, imageSelectDefaultUrl, imageSelectNoPreviewUrl, imageSelectDefaultBGSize, imageSelectWorkingBGSize);
newTextMessage("Not an image file!", 2000, 400);
continue;
}
var isValidPreview = f.type.match('image\/(jp(e?)g|png|gif|bmp)');
//var reader = new FileReader();
var theType = /\/(.*)/.exec(f.type)[1].toUpperCase();
// Limit preview to 20MB file sizes
var limit = 20971520;
if (f.size < limit) {
if (isValidPreview) {
resetImageSelection(false, false);
var URL = window.URL || window.webkitURL;
if (URL.createObjectURL) {
newTextMessage("Preview generated.", 3000, 400);
$('.' + imageSelectClass).css('backgroundSize', imageSelectWorkingBGSize);
$('.' + imageSelectClass).css('backgroundImage', "url('" + URL.createObjectURL(f) + "')");
} else {
resetImageSelection(true, false);
newTextMessage("Sorry, but your browser doesn't support image previews.", 0, 0);
}
} else {
resetImageSelection(true, false);
newTextMessage(theType + " images can't be previewed 'on-the-fly'. However it will be converted when you save.", 0, 0);
}
} else {
resetImageSelection(true, false);
newTextMessage("On-the-fly previews only available for files <= " + (limit/1024/1024) + "MB", 0, 0);
}
}
}
function makeIntoImageSelection(id, defaultUrl, noPreviewUrl, defaultBGSize, workingBGSize) {
imageSelectClass = id;
originalCanvasWidth = $('.' + id).width();
originalCanvasHeight = $('.' + id).height();
imageSelectDefaultBGSize = defaultBGSize;
imageSelectWorkingBGSize = workingBGSize;
imageSelectDefaultUrl = defaultUrl;
imageSelectNoPreviewUrl = noPreviewUrl;
// When span is clicked, trigger the file input
$('span.' + id).on('click', function(evt) {
evt.preventDefault();
$('#' + id).click();
newTextMessage("Select an image.", 3000, 400);
});
$('#' + id).on('change', function (evt) {
newTextMessage("Generating preview...", 2000, 400);
handleImageSelection(evt);
});
$('.image-select-text').css('maxWidth', $('.image-select.' + id + ' span').css('width'));
}
function newTextMessage(msg, display_time, fadeDelay) {
$('.image-select-text').text(msg);
$('.image-select-text').css("opacity", 1);
if (display_time > 0) {
$('.image-select-text').delay(display_time).fadeTo(fadeDelay, 0, function() {
$('.image-select-text').text("");
$('.image-select-text').css("opacity", 1);
});
}
}
HTML
<form accept-charset="UTF-8" action="/albums/4/photographs" class="new_photograph" enctype="multipart/form-data" id="new_photograph" method="post">
<div style="margin:0;padding:0;display:inline"></div>
<input class="image-select" id="photograph_photo" name="photograph[photo]" type="file">
<table>
<tbody>
<tr>
<td>
<span class="image-select photograph_photo" style="background-size: 100%;"></span><br>
<span class="image-select-text" style="opacity: 1;"></span>
</td>
</tr>
<tr>
<td><label for="photograph_title">Title</label><br><input id="photograph_title" name="photograph[title]" size="50" type="text" data-cip-id="photograph_title"></td>
</tr>
<tr>
<td><label for="photograph_description">Description</label><br><textarea id="photograph_description" name="photograph[description]"></textarea></td>
</tr>
</tbody>
</table>
<br>
<div class="actions">
<input name="commit" type="submit" value="Create Photograph">
</div>
</form>
文档末尾的内嵌 Javascript
makeIntoImageSelection('photograph_photo', '[url of original image file if any]', '[url of global default image file]', '100%', '100%');
【问题讨论】:
标签: javascript jquery html performance file-upload