2014-12-26 3 views
0

Я пытаюсь отобразить несколько изображений в div, используя технику перетаскивания.Рендеринг изображений при перетаскивании с использованием javascript и рулей

Но я не получаю ожидаемые результаты, и что бы я ни старался, я не был получать изображения неоднократных и name, size и type атрибутов быть переопределен.

EDIT Хорошо, я понял, почему я получаю пустой data массив. Это потому, что при этом время onload событие не закончилось, поэтому данных по-прежнему нет.

Но теперь я не знаю, как разрешить ПРОБЛЕМУ, которая определена ниже в комментарии , о том, как визуализировать шаблон только один раз, когда загружаются все файлы.

Может ли кто-нибудь дать представление о том, как эти данные должны быть подготовлены к тому, чтобы быть оказанным позже, вызывая ручные панели?

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

После некоторой настройки и мышления, в конце концов, я сделал его работу. Пожалуйста, просмотрите комментарии в файле, чтобы узнать, как я решил проблему.

(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 
})(); 
Смежные вопросы