最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Drag and drop a file on label - Stack Overflow

programmeradmin5浏览0评论

I need your help, again

I can drag and drop a file or click on a basic input file on HTML5 and it'll work. What I want is to be able to make that with a label, I can click on the label to add a file with a label for but I can't drag and drop a file on the label. I've tried to make it possible with that JavaScript over here but it didn't work, I've read some tutorials and I'm not sure of the code below.

$(document).on('dragenter', '#image-event-label', function() {
        $(this).css('border', '1px solid #B8A1F5');
        return false;
    });
     
    $(document).on('dragover', '#image-event-label', function(e){
        e.preventDefault();
        e.stopPropagation();
        $(this).css('border', '1px solid #B8A1F5');
        return false;
    });
     
    $(document).on('dragleave', '#image-event-label', function(e) {
        e.preventDefault();
        e.stopPropagation();
        $(this).css('border', '1px solid #422B7E');
        return false;
    });

    $(document).on('drop', '#image-event-label', function(e) {
        if(e.originalEvent.dataTransfer){
           if(e.originalEvent.dataTransfer.files.length) {
               e.preventDefault();
               e.stopPropagation();
               $(this).css('border', '1px solid #0F0');
               upload(e.originalEvent.dataTransfer.files);
           }  
        }
        else {
           $(this).css('border', '1px solid #422B7E');
        }
        return false;
    });

    function upload(files) {
        var f = files[0] ;
        var reader = new FileReader();
        reader.onload = function (event) {
            $('#image-event').val(event.target.result);
        }
        reader.readAsDataURL(f);      
    }
<script src=".1.1/jquery.min.js"></script>
<label for="image-event" id="image-event-label">Import an image</label>
				<input type="file" name="image-event" style="display:none" id="image-event">

I need your help, again

I can drag and drop a file or click on a basic input file on HTML5 and it'll work. What I want is to be able to make that with a label, I can click on the label to add a file with a label for but I can't drag and drop a file on the label. I've tried to make it possible with that JavaScript over here but it didn't work, I've read some tutorials and I'm not sure of the code below.

$(document).on('dragenter', '#image-event-label', function() {
        $(this).css('border', '1px solid #B8A1F5');
        return false;
    });
     
    $(document).on('dragover', '#image-event-label', function(e){
        e.preventDefault();
        e.stopPropagation();
        $(this).css('border', '1px solid #B8A1F5');
        return false;
    });
     
    $(document).on('dragleave', '#image-event-label', function(e) {
        e.preventDefault();
        e.stopPropagation();
        $(this).css('border', '1px solid #422B7E');
        return false;
    });

    $(document).on('drop', '#image-event-label', function(e) {
        if(e.originalEvent.dataTransfer){
           if(e.originalEvent.dataTransfer.files.length) {
               e.preventDefault();
               e.stopPropagation();
               $(this).css('border', '1px solid #0F0');
               upload(e.originalEvent.dataTransfer.files);
           }  
        }
        else {
           $(this).css('border', '1px solid #422B7E');
        }
        return false;
    });

    function upload(files) {
        var f = files[0] ;
        var reader = new FileReader();
        reader.onload = function (event) {
            $('#image-event').val(event.target.result);
        }
        reader.readAsDataURL(f);      
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="image-event" id="image-event-label">Import an image</label>
				<input type="file" name="image-event" style="display:none" id="image-event">

Thanks everybody in advance !

Share Improve this question asked Apr 22, 2018 at 22:14 BambouBambou 1,0771 gold badge12 silver badges26 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 17

The easiest way, is to append your input[type=file] directly in your <label>, and to style this input in a way it covers all the label.

Doing so, you'll be able to drop files directly on the label, and the input's default behavior will take care of it, ultimately, no js is needed in this part:

// only to show it did change
$('#image-event').on('change', function upload(evt) {
  console.log(this.files[0]);
});

// only to show where is the drop-zone:
$('#image-event-label').on('dragenter', function() {
  this.classList.add('dragged-over');
})
 .on('dragend drop dragexit dragleave', function() {
  this.classList.remove('dragged-over');
});
#image-event {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  width: 100%;
  height: 100%;
  display: block;
}
#image-event-label {
  position: relative;
}

#image-event-label.dragged-over {
  border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="image-event" id="image-event-label">
        Import an image
        <input type="file" name="image-event" id="image-event">
</label>


Now, note that it is actually now* possible to set the .files FileList of an input[type=file], but you need to set it to an other FileList object, and fortunately, there is one available in the DataTransfer object that comes along the DropEvent:

function handleDroppedFile(evt) {
  evt.preventDefault();
  // since we use jQuery we need to grab the originalEvent
  var dT = evt.originalEvent.dataTransfer;
  var files = dT.files;
  if (files && files.length) {
    // we set our input's 'files' property
    $('#image-event')[0].files = files;
  }
}
$('#image-event-label').on({
    'drop': handleDroppedFile,
    'dragenter': function(e) { e.preventDefault(); },
    'dragover': function(e) {
      e.preventDefault();
      this.classList.add('dragged-over');
    }
  })
  .on('dragleave dragexit', function() {
    this.classList.remove('dragged-over')
  });
.dragged-over {
  border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="image-event" id="image-event-label">
        Drop a file here
</label> <br><br>
<input type="file" name="image-event" id="image-event">

*IIRC, this is now supported in Chrome, Safari, latests Edge and latests Firefox. I don't think IE does support it though, so beware when using this.

Adding to Naseh Badalov's response, if you "overlay" the label on top of the file element, I recommend adding pointer-events: none; to your label class. This makes it so that the label won't respond to any drag-and-drop events. The label is removed from the "functionality flow" of the page but not the visual flow, so you can still see it but can't drag anything on top of it. So the underlying file element responds to all the functionality instead.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PDF Preview</title>
</head>
<body>

<form>
    <input type="file" id="pdfUpload" accept="application/pdf">
    <br><br>
    <iframe id="pdfPreview" width="600" height="500"></iframe>
</form>

<script>
    document.getElementById('pdfUpload').addEventListener('change', function(event) {
        const file = event.target.files[0];
        if (file.type === "application/pdf") {
            const fileURL = URL.createObjectURL(file);
            document.getElementById('pdfPreview').src = fileURL;
        } else {
            alert("Please upload a valid PDF file.");
        }
    });
</script>

</body>
</html>

发布评论

评论列表(0)

  1. 暂无评论