21

I would like to use html5's file api, in combination with the external drag n drop functionality (drag an external file onto a designated spot and capture its contents) and jquery. I found a working non-jquery example: (html5 demo: file api)

 var drop = document.getElementById('drop');  
 drop.ondragover = function () {this.className = 'focus'; return false;};  
 drop.ondragend = function () { this.className = ''; return false; };  
 drop.ondrop=function(e) {  
          this.className = '';  
          e.preventDefault();  
          var file = e.dataTransfer.files[0];  
          var reader = new FileReader();  
          reader.onload = function (evt) {  
                console.log(evt.target.result);  
          }  
          reader.readAsText(file);  
      }; 

This works fine. Now I would like to make this more a jquery-ish and I tried:

 $("#drop").bind('ondragover',function() {this.addClass('focus'); return false;})
.bind("ondragend",function () { this.removeClass('focus'); return false;})  
.bind("ondrop",function(e) {  
         this.removeClass("focus");  
         e.preventDefault();  
         var file = e.dataTransfer.files[0];  
         var reader = new FileReader();  
         reader.onload = function (evt) {  
               console.log(evt.target.result);  
         }  
         reader.readAsText(file);  
     });   

But that doesn't work, none of the binded events seems to get triggered. I also tried to loose the "on" part for the eventnames but that also doesn't work. Hopefully somebody here can shine a light?

regards, jeroen.

2 Answers 2

34

Gidon's description solves the problem. Here is a fully coded example in case someone else is looking to solve this problem and wants more detail.

// Bindings to HTML; replace these with your components.
var $dropArea = $('#dropArea');
var $picsHolder = $('#picsHolder');

// Attach our drag and drop handlers.
$dropArea.bind({
  dragover: function() {
    $(this).addClass('hover');
    return false;
  },
  dragend: function() {
    $(this).removeClass('hover');
    return false;
  },
  drop: function(e) {
    e = e || window.event;
    e.preventDefault();

    // jQuery wraps the originalEvent, so we try to detect that here...
    e = e.originalEvent || e;
    // Using e.files with fallback because e.dataTransfer is immutable and can't be overridden in Polyfills (http://sandbox.knarly.com/js/dropfiles/).            
    var files = (e.files || e.dataTransfer.files);

    var $img = $('<img src="" class="uploadPic" title="" alt="" />');
    for (var i = 0; i < files.length; i++) {
      (function(i) {
        // Loop through our files with a closure so each of our FileReader's are isolated.
        var reader = new FileReader();
        reader.onload = function(event) {
          var newImg = $img.clone().attr({
            src: event.target.result,
            title: (files[i].name),
            alt: (files[i].name)
          });

          // Resize large images...
          if (newImg.size() > 480) {
            newImg.width(480);
          }

          $picsHolder.append(newImg);
        };
        reader.readAsDataURL(files[i]);
      })(i);
    }

    return false;
  }
});
#dropArea {
  border: 10px dashed;
  border-radius: 10px;
  border-color: gray;
  width: 200px;
  height: 200px;
}
#dropArea:hover {
  border-color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="picsHolder"></div>
<div id="dropArea"></div>

Sign up to request clarification or add additional context in comments.

2 Comments

had to change dragend to dragleave in chrome and then duplicate removeclass in drop
@Benjamin, I was banging my head on my desk for a while before I saw this - usually don't have to add "fixes" for Chrome, but oh well. Thanks for this!
21

The solution is simple.

  1. Lose the on prefix (that's why no events were thrown)
  2. this. => $(this). (that's why when events were thrown nothing happened, it gave an error).

With me it worked.

1 Comment

yep that was stupid (the $(this)). Anyway for going jquery I also must unpack the original event by doing e.originalEvent.dataTransfer. Thanks for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.