jquery - jQuery - 具有多个实例的文件上传器
问题描述
我正在尝试将工作的 codepen 从 Javascript 转换为 jQuery,以便运行图像上传器的多个实例。问题可能是我尝试迭代每一个.item
,但也可能是从addEventListener
到的转换.on()
。
https://codepen.io/moofawsaw/pen/dyPdpGy
我在转换中哪里出错了?
这是我尝试的 jQuery 转换(不工作):
$(document).ready(function() {
function ekUpload() {
var $item = $(".item");
function fileDragHover(e) {
var fileDrag = $item.find(".file-drag");
e.stopPropagation();
e.preventDefault();
fileDrag.className =
e.type === "dragover" ? "hover" : "modal-body file-upload";
}
async function fileSelectHandler(e) {
// Fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// Cancel event and hover styling
fileDragHover(e);
// Process all File objects
for (let i = 0; i < files.length; i++) {
const f = files[i];
if (await hasAlpha(f)) {
console.log("Selected image is transparent");
parseFile(f);
uploadFile(f);
} else {
console.log("Selected image is not transparent");
$item.find(".response").removeClass("hidden");
$item.find(".error-image").removeClass("hidden");
$item.find(".file-image").addClass("hidden");
output(
'<strong class="warning">Image background is not transparent</strong>'
);
}
}
}
// Output
function output(msg) {
// Response
var m = $item.find(".messages");
m.innerHTML = msg;
}
function Init() {
console.log("Upload Initialised");
var fileSelect = $item.find(".file-upload"),
fileDrag = $item.find(".file-drag"),
submitButton = $item.find(".submit-button");
fileSelect.on("change", function(e) {
fileSelectHandler(e);
});
// Is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// File Drop
fileDrag.on("change dragleave", function(e) {
fileDragHover(e);
});
fileDrag.on("drop", function(e) {
fileSelectHandler(e);
});
}
}
function hasAlpha(file) {
return new Promise((resolve, reject) => {
let hasAlpha = false;
const canvas = $item.find("canvas");
const ctx = canvas.getContext("2d");
const img = new Image();
img.crossOrigin = "Anonymous";
img.onerror = reject;
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
.data;
for (let j = 0; j < imgData.length; j += 4) {
if (imgData[j + 3] < 255) {
hasAlpha = true;
break;
}
}
resolve(hasAlpha);
};
img.src = URL.createObjectURL(file);
});
}
function parseFile(file) {
console.log(file.name);
output("<strong>" + encodeURI(file.name) + "</strong>");
// var fileType = file.type;
// console.log(fileType);
var imageName = file.name;
var isGood = /\.(?=svg|jpg|png|jpeg)/gi.test(imageName);
if (isGood) {
$item.find(".start").addClass("hidden");
$item.find(".response").removeClass("hidden");
$item.find(".notimage").addClass("hidden");
// Thumbnail Preview
$item.find(".error-image").addClass("hidden");
$item.find(".file-image").removeClass("hidden");
$item.find(".file-image").src = URL.createObjectURL(file);
} else {
$item.find(".error-image").removeClass("hidden");
$item.find(".file-image").addClass("hidden");
$item.find(".notimage").removeClass("hidden");
$item.find(".start").removeClass("hidden");
$item.find(".response").addClass("hidden");
$item.find(".file-upload-form").reset();
}
}
function uploadFile(file) {
var xhr = new XMLHttpRequest(),
fileInput = $this.find(".class-roster-file"),
fileSizeLimit = 1024; // In MB
if (xhr.upload) {
// Check if file is less than x MB
if (file.size <= fileSizeLimit * 1024 * 1024) {
// File received / failed
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
// Everything is good!
// document.location.reload(true);
}
};
// Start upload
xhr.open(
"POST",
document.getElementById("file-upload-form").action,
true
);
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.send(file);
} else {
output("Please upload a smaller file (< " + fileSizeLimit + " MB).");
}
}
}
// Check for the various File API support.
if (window.File && window.FileList && window.FileReader) {
Init();
} else {
$item.find("file-drag").css("display", "none");
}
}
$(".item").each(function() {
ekUpload();
});
});
@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css);
@import url("https://fonts.googleapis.com/css?family=Roboto");
html,
body,
* {
box-sizing: border-box;
font-size: 16px;
}
html,
body {
height: 100%;
text-align: center;
}
body {
padding: 2rem;
background: #f8f8f8;
}
h2 {
font-family: "Roboto", sans-serif;
font-size: 26px;
line-height: 1;
color: #454cad;
margin-bottom: 0;
}
p {
font-family: "Roboto", sans-serif;
font-size: 18px;
color: #5f6982;
}
.uploader {
display: block;
clear: both;
margin: 0 auto;
width: 100%;
max-width: 600px;
}
.uploader label {
float: left;
clear: both;
width: 100%;
padding: 2rem 1.5rem;
text-align: center;
background: #fff;
border-radius: 7px;
border: 3px solid #eee;
transition: all .2s ease;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.uploader label:hover {
border-color: #454cad;
}
.uploader label.hover {
border: 3px solid #454cad;
box-shadow: inset 0 0 0 6px #eee;
}
.uploader label.hover #start i.fa {
-webkit-transform: scale(0.8);
transform: scale(0.8);
opacity: 0.3;
}
.uploader #start {
float: left;
clear: both;
width: 100%;
}
.uploader #start.hidden {
display: none;
}
.uploader #start i.fa {
font-size: 50px;
margin-bottom: 1rem;
transition: all .2s ease-in-out;
}
.uploader #response {
float: left;
clear: both;
width: 100%;
}
.uploader #response.hidden {
display: none;
}
.uploader #response #messages {
margin-bottom: .5rem;
}
.uploader #file-image {
display: inline;
margin: 0 auto .5rem auto;
width: auto;
height: auto;
max-width: 180px;
}
.uploader #file-image.hidden {
display: none;
}
.uploader #notimage {
display: block;
float: left;
clear: both;
width: 100%;
}
.uploader #notimage.hidden {
display: none;
}
.uploader progress,
.uploader .progress {
display: inline;
clear: both;
margin: 0 auto;
width: 100%;
max-width: 180px;
height: 8px;
border: 0;
border-radius: 4px;
background-color: #eee;
overflow: hidden;
}
.uploader .progress[value]::-webkit-progress-bar {
border-radius: 4px;
background-color: #eee;
}
.uploader .progress[value]::-webkit-progress-value {
background: linear-gradient(to right, #393f90 0%, #454cad 50%);
border-radius: 4px;
}
.uploader .progress[value]::-moz-progress-bar {
background: linear-gradient(to right, #393f90 0%, #454cad 50%);
border-radius: 4px;
}
.uploader input[type="file"] {
display: none;
}
.uploader div {
margin: 0 0 .5rem 0;
color: #5f6982;
}
.uploader .btn {
display: inline-block;
margin: .5rem .5rem 1rem .5rem;
clear: both;
font-family: inherit;
font-weight: 700;
font-size: 14px;
text-decoration: none;
text-transform: initial;
border: none;
border-radius: .2rem;
outline: none;
padding: 0 1rem;
height: 36px;
line-height: 36px;
color: #fff;
transition: all 0.2s ease-in-out;
box-sizing: border-box;
background: #454cad;
border-color: #454cad;
cursor: pointer;
}
.uploader input[type="file"],
.hidden {
display: none;
}
.warning {
color: red;
font-weight: bold;
}
canvas {
position: absolute;
top: -2000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Upload -->
<div class="item">
<form class="uploader file-upload-form">
<input class="file-upload" type="file" name="fileUpload" accept="image/*" />
<label for="file-upload" class="file-drag">
<img src="#" alt="Preview" class="file-image hidden">
<img src="https://cdn3.iconfinder.com/data/icons/online-states/150/Snooze-512.png" class="error-image hidden">
<div class="start">
<i class="fa fa-download" aria-hidden="true"></i>
<div>Select a file or drag here</div>
<div class="notimage hidden">Please select an image</div>
</div>
<div class="response hidden">
<div class="messages"></div>
</div>
</label>
</form>
<div class="filename"></div>
<canvas></canvas>
</div>
<div class="item">
<form class="uploader file-upload-form">
<input class="file-upload" type="file" name="fileUpload" accept="image/*" />
<label for="file-upload" class="file-drag">
<img src="#" alt="Preview" class="file-image hidden">
<img src="https://cdn3.iconfinder.com/data/icons/online-states/150/Snooze-512.png" class="error-image hidden">
<div class="start">
<i class="fa fa-download" aria-hidden="true"></i>
<div>Select a file or drag here</div>
<div class="notimage hidden">Please select an image</div>
</div>
<div class="response hidden">
<div class="messages"></div>
</div>
</label>
</form>
<div class="filename"></div>
<canvas></canvas>
</div>
解决方案
干得好。这可以用来清理一下,但它应该让你朝着正确的方向前进。
很抱歉没有详细解释我所做的更改,但是其中有很多,所以请将您的代码与我的代码进行比较,看看有什么不同。
// File Upload
//
$(function() {
console.log("_________________________");
$(".file-drag").click(function(event) {
$(this)
.siblings(".file-upload")
.click();
});
function ekUpload(item) {
var form = $(this).find('form.uploader'),
fileSelect = $(this).find(".file-upload"),
fileDrag = $(this).find(".file-drag"),
submitButton = $(this).find(".submit-button");
function Init() {
// console.log("Init()");
// fileSelect.addEventListener("change", fileSelectHandler, false);
$(document).on('change', 'form', function(e) {
fileSelectHandler(e);
});
// Is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// File Drop
// fileDrag.addEventListener("dragover", fileDragHover, false);
// fileDrag.addEventListener("dragleave", fileDragHover, false);
// fileDrag.addEventListener("drop", fileSelectHandler, false);
if (isAdvancedUpload) {
$(document).on('drag dragstart dragend dragover dragenter dragleave', 'form', function(e) {
// fileDragHover(e);
e.preventDefault();
e.stopPropagation();
})
.on('dragover dragenter', 'form', function(e) {
e.preventDefault();
e.stopPropagation();
$(e.target).addClass('is-dragover');
})
.on('dragleave dragend drop', 'form', function(e) {
e.preventDefault();
e.stopPropagation();
$(e.target).removeClass('is-dragover');
})
.on('drop dragover', 'body', function(e) {
e.preventDefault();
e.stopPropagation();
})
.on('drop', 'form', function(e) {
e.preventDefault();
e.stopPropagation();
fileSelectHandler(e);
});
}
}
}
function fileDragHover(e) {
// var fileDrag = $(".file-drag");
e.stopPropagation();
e.preventDefault();
e.target.className =
e.type === "dragover" ? "hover" : "modal-body file-upload";
}
async function fileSelectHandler(e) {
var theForm = $(e.target).parent('form.uploader');
// var files = e.target.files || e.dataTransfer.files;
var files = e.target.files || e.originalEvent.dataTransfer.files;
// Process all File objects
for (let i = 0; i < files.length; i++) {
const f = files[i];
if (await hasAlpha(f)) {
console.log("Selected image is transparent");
parseFile(f, theForm);
uploadFile(f, theForm);
} else {
console.log("Selected image is not transparent");
// document.querySelector(".response").classList.remove("hidden");
// document.querySelector(".error-image").classList.remove("hidden");
// document.querySelector(".file-image").classList.add("hidden");
$(theForm)
.find(".response, .error-image, .file-image")
.removeClass("hidden");
output(
'<strong class="warning">Image background is not transparent</strong>'
);
}
}
}
// Output
function output(msg) {
// Response
// var m = document.getElementById("messages");
var m = $(item).find(".messages");
// m.innerHTML = msg;
m.html(msg);
}
function hasAlpha(file) {
return new Promise((resolve, reject) => {
let hasAlpha = false;
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const img = new Image();
img.crossOrigin = "Anonymous";
img.onerror = reject;
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
.data;
for (let j = 0; j < imgData.length; j += 4) {
if (imgData[j + 3] < 255) {
hasAlpha = true;
break;
}
}
resolve(hasAlpha);
};
img.src = URL.createObjectURL(file);
});
}
function parseFile(file, thisForm) {
console.log(file.name);
output("<strong>" + encodeURI(file.name) + "</strong>");
// var fileType = file.type;
// console.log(fileType);
var imageName = file.name;
var isGood = /\.(?=svg|jpg|png|jpeg)/gi.test(imageName);
if (isGood) {
// document.getElementById("start").classList.add("hidden");
// document.getElementById("response").classList.remove("hidden");
// document.getElementById("notimage").classList.add("hidden");
$(thisForm)
.find(".start", ".notimage")
.addClass("hidden");
$(thisForm)
.find(".response")
.removeClass("hidden");
// Thumbnail Preview
// document.querySelector("#error-image").classList.add("hidden");
// document.getElementById("file-image").classList.remove("hidden");
// document.getElementById("file-image").src = URL.createObjectURL(file);
$(thisForm)
.find(".error-image")
.addClass("hidden");
$(thisForm).find('label.has-advanced-upload').removeClass('has-advanced-upload');
$(thisForm)
.find(".file-image")
.removeClass("hidden")
.attr("src", URL.createObjectURL(file));
} else {
// document.querySelector("#error-image").classList.remove("hidden");
// document.getElementById("file-image").classList.add("hidden");
// document.getElementById("notimage").classList.remove("hidden");
// document.getElementById("start").classList.remove("hidden");
// document.getElementById("response").classList.add("hidden");
// document.getElementById("file-upload-form").reset();
$(thisForm)
.find(".error-image, .notimage, .start")
.removeClass("hidden");
$(thisForm)
.find(".file-image, .response")
.addClass("hidden");
$(thisForm)
.find(".file-upload-form")
.trigger("reset");
$(thisForm).find('label[for="file-upload"]').addClass('has-advanced-upload');
}
}
function uploadFile(file, thisForm) {
// var xhr = new XMLHttpRequest(),
// fileInput = document.getElementById("class-roster-file"),
// fileSizeLimit = 1024; // In MB
var xhr = new XMLHttpRequest(),
// fileInput = $(item).find('.class-roster-file'),
fileSizeLimit = 1024; // in MB
if (xhr.upload) {
// Check if file is less than x MB
if (file.size <= fileSizeLimit * 1024 * 1024) {
// File received / failed
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
// Everything is good!
// document.location.reload(true);
console.log("everything is good");
}
};
// Start upload
xhr.open(
"POST",
// document.getElementById("file-upload-form").action,
$(thisForm)
.find(".file-upload-form")
.attr("action"),
true
);
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.send(file);
} else {
output("Please upload a smaller file (< " + fileSizeLimit + " MB).");
}
}
}
// Check for the various File API support.
if (window.File && window.FileList && window.FileReader) {
Init();
} else {
document.getElementById("file-drag").style.display = "none";
}
}
var isAdvancedUpload = (function() {
var div = document.createElement("div");
return (
("draggable" in div || ("ondragstart" in div && "ondrop" in div)) &&
"FormData" in window &&
"FileReader" in window
);
})();
if (isAdvancedUpload) {
$('.file-drag').addClass('has-advanced-upload');
}
$(".item").each(function() {
ekUpload(this);
});
});
@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css);
@import url("https://fonts.googleapis.com/css?family=Roboto");
html, body, * {
box-sizing: border-box;
font-size: 16px;
}
html, body {
height: 100%;
text-align: center;
}
body {
padding: 2rem;
background: #f8f8f8;
}
h2 {
font-family: "Roboto", sans-serif;
font-size: 26px;
line-height: 1;
color: #454cad;
margin-bottom: 0;
}
p {
font-family: "Roboto", sans-serif;
font-size: 18px;
color: #5f6982;
}
.uploader {
display: block;
clear: both;
margin: 0 auto;
width: 100%;
max-width: 600px;
}
.uploader label {
float: left;
clear: both;
width: 100%;
padding: 2rem 1.5rem;
text-align: center;
background: #fff;
border-radius: 7px;
border: 3px solid #eee;
transition: all .2s ease;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: pointer;
}
.uploader label.has-advanced-upload {
background-color: white;
outline: 2px dashed lightgrey;
outline-offset: -10px;
}
.uploader label:hover {
border: 3px solid #454cad;
box-shadow: inset 0 0 0 6px #eee;
}
.uploader label.is-dragover,
.uploader label.is-dragover:hover {
background-color: #eef;
}
.uploader label:hover {
border: 3px solid #454cad;
box-shadow: inset 0 0 0 6px #eee;
}
.uploader label:hover .start i.fa {
-webkit-transform: scale(0.8);
transform: scale(0.8);
opacity: 0.3;
}
.uploader .start {
float: left;
clear: both;
width: 100%;
pointer-events: none;
}
.uploader .start.hidden {
display: none;
}
.uploader .start i.fa {
font-size: 50px;
margin-bottom: 1rem;
transition: all .2s ease-in-out;
}
.uploader .response {
float: left;
clear: both;
width: 100%;
}
.uploader .response.hidden {
display: none;
}
.uploader .response .messages {
margin-bottom: .5rem;
}
.uploader .file-image {
display: inline;
margin: 0 auto .5rem auto;
width: auto;
height: auto;
max-width: 180px;
}
.uploader .file-image.hidden {
display: none;
}
.uploader .notimage {
display: block;
float: left;
clear: both;
width: 100%;
}
.uploader .notimage.hidden {
display: none;
}
.uploader progress,
.uploader .progress {
display: inline;
clear: both;
margin: 0 auto;
width: 100%;
max-width: 180px;
height: 8px;
border: 0;
border-radius: 4px;
background-color: #eee;
overflow: hidden;
}
.uploader .progress[value]::-webkit-progress-bar {
border-radius: 4px;
background-color: #eee;
}
.uploader .progress[value]::-webkit-progress-value {
background: linear-gradient(to right, #393f90 0%, #454cad 50%);
border-radius: 4px;
}
.uploader .progress[value]::-moz-progress-bar {
background: linear-gradient(to right, #393f90 0%, #454cad 50%);
border-radius: 4px;
}
.uploader input[type="file"] {
display: none;
}
.uploader div {
margin: 0 0 .5rem 0;
color: #5f6982;
}
.uploader .btn {
display: inline-block;
margin: .5rem .5rem 1rem .5rem;
clear: both;
font-family: inherit;
font-weight: 700;
font-size: 14px;
text-decoration: none;
text-transform: initial;
border: none;
border-radius: .2rem;
outline: none;
padding: 0 1rem;
height: 36px;
line-height: 36px;
color: #fff;
transition: all 0.2s ease-in-out;
box-sizing: border-box;
background: #454cad;
border-color: #454cad;
cursor: pointer;
}
.uploader input[type="file"],
.hidden {
display: none;
}
input[type="file"].hidden {
display: block;
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.warning {
color: red;
font-weight: bold;
}
canvas {
position: absolute;
top: -2000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Upload -->
<div class="item">
<form class="file-upload-form uploader">
<input class="file-upload" type="file" name="fileUpload" accept="image/*" />
<label for="file-upload" class="file-drag">
<img class="file-image hidden" src="#" alt="Preview">
<img class="error-image hidden" src="https://cdn3.iconfinder.com/data/icons/online-states/150/Snooze-512.png">
<div class="start">
<i class="fa fa-download" aria-hidden="true"></i>
<div>Select a file or drag here</div>
<div class="notimage hidden">Please select an image</div>
</div>
<div class="response hidden">
<div class="messages"></div>
</div>
</label>
</form>
<div class="filename"></div>
<canvas></canvas>
</div>
<div class="item">
<form class="file-upload-form uploader">
<input class="file-upload" type="file" name="fileUpload" accept="image/*" />
<label for="file-upload" class="file-drag">
<img class="file-image hidden" src="#" alt="Preview">
<img class="error-image hidden" src="https://cdn3.iconfinder.com/data/icons/online-states/150/Snooze-512.png">
<div class="start">
<i class="fa fa-download" aria-hidden="true"></i>
<div>Select a file or drag here</div>
<div class="notimage hidden">Please select an image</div>
</div>
<div class="response hidden">
<div class="messages"></div>
</div>
</label>
</form>
<div class="filename"></div>
<canvas></canvas>
</div>
推荐阅读
- service-worker - 在下面的代码中为服务工作者获取侦听器的目的是什么
- simulation - 用热量需求计算质量流量的缓慢计算
- typescript - 如何在 Aurelia 中使用授权自定义属性禁用自定义组件
- angular - angular5的地图框
- c# - 允许用户将多个项目添加到 ObservableCollection c#
- java - 如何使用单个用于具有相同 dtasnapshot 对象的每个循环获取 2 个节点的组合数据
- kentico - Kentico 11 - 托管环境中的电子邮件营销 CMS 显示问题
- javascript - 在 node.js 中重复 cryptojs aes 加密的替代方法
- javascript - 在 Javascript 中获取属性、名称和值
- templates - Visual Studio 2017 ASP NET Core 2 脚手架模板