使用javascript和把手在拖放时渲染图像

时间:2014-12-26 21:51:49

标签: javascript drag-and-drop handlebars.js

我试图使用拖放技术在div中渲染多个图像。

但我没有得到预期的结果,无论我怎样尝试,我都是 重复播放图片,并覆盖namesizetype个属性。

修改 好的,我意识到为什么我得到一个空的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>

1 个答案:

答案 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
})();