我试图使用拖放技术在div中渲染多个图像。
但我没有得到预期的结果,无论我怎样尝试,我都是
重复播放图片,并覆盖name
,size
和type
个属性。
修改
好的,我意识到为什么我得到一个空的data
数组。这是因为那个
时间onload
事件尚未完成,因此仍无法获得数据。
但现在我不知道如何解决下面定义的问题 注释,关于如何在加载所有文件时仅渲染模板。
有人可以提供一些关于如何准备这些数据以便稍后调用Handlebars的线索吗?
JS / filedrop.js
(function(){
"use strict";
// define the drop zone
var dropZone = document.getElementById("drop-zone");
// add a drag over event to the zone
dropZone.addEventListener("dragover", function(e){
e.preventDefault();
// add a hover class so we can see it's working
dropZone.setAttribute("class", "over");
}, false);
// on file drop grab all available image information
dropZone.addEventListener("drop", function(e){
"use strict";
e.preventDefault();
var
reader,
files = e.dataTransfer.files,
fileCount = files.length,
i;
// get the Handlebars template
var handlebarTemplate = document.getElementById("handlebar-template");
var template = Handlebars.compile(handlebarTemplate.innerHTML);
if(fileCount > 0){
var data = [], currObj = {};
for(i = 0; i < fileCount; i = i + 1){
var file = files[i];
reader = new FileReader();
// remove the hover class
dropZone.removeAttribute("class");
reader.onload = function(e){
currObj = {
name : file.name,
size : file.size,
type : file.type,
source: e.target.result
};
data.push(currObj);
// PROBLEM, how to load template once all files are loaded
// because leaving it like this will load some files multiple times
// also name, size and type attributes will be overwritten so I will get
// same attributes for all loaded images.
dropZone.innerHTML += ( template(data) );
};
// render the image as a data url
reader.readAsDataURL(file);
} //end for loop
//console.log(data); I got this! See above EDIT
} //end if
}, false); //end listener
})();
的index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Chapter 12</title>
<style type="text/css" media="screen">
#drop-zone {
min-height: 300px;
max-width: 300px;
padding: 15px;
border: 4px dashed #999;
}
#drop-zone img {
max-width: 100%;
display: block;
}
.over {
border-color: #333;
background: #ddd;
}
ul {
padding: 0;
list-style: none;
color: #333;
}
</style>
</head>
<body>
<div id="drop-zone">
<script id="handlebar-template" type="text/x-handlebars-temlate">
<div class="img-slot">
{{#each this}}
<img src="{{source}}" alt="{{name}}">
<ul>
<li>{{name}}</li>
<li>{{type}}</li>
<li>{{size}}</li>
</ul>
{{/each}}
</div>
</script>
</div><!-- /#drop-zone -->
<script src="bower_components/handlebars/handlebars.min.js"></script>
<script src="js/filedrop.js"></script>
</body>
</html>
答案 0 :(得分:0)
经过一番调整和思考后,我终于成功了。 有关我如何解决问题的解释,请参阅文件内注释。
(function(){
"use strict";
// define the drop zone
var dropZone = document.getElementById("drop-zone");
...
...
// on file drop grab all available image information
dropZone.addEventListener("drop", function(e){
"use strict";
e.stopPropagation();
e.preventDefault();
// get the Handlebars template instance
var handlebarTemplate = document.getElementById("handlebar-template"),
template = Handlebars.compile(handlebarTemplate.innerHTML);
// declare some variables
var reader,
files = e.dataTransfer.files,
i;
if(files.length > 0){
var data = [], f;
for(i = 0, f; f = files[i]; i++){
reader = new FileReader();
// have control over which file is being processed by
// wrapping it all into another anonymous function and
// passing `theFile` argument from loop iteration
reader.onload = (function(theFile){
return function(e){
var imgObj = {
name: theFile.name,
type: theFile.type,
size: theFile.size,
source: e.target.result
};
data.push(imgObj);
// check if all files loaded, so we can then handover to Handlebars.js
if (data.length == files.length){
renderTemplate();
}
}
})(f);
// render the image as a data url
reader.readAsDataURL(f);
} //end for loop
} //end if
// Handover data to Handlebars.js
function renderTemplate(){
dropZone.innerHTML += ( template(data) );
}
}, false); //end listener
})();