Bug

События указателя: нет; уже реализован, в отладке логическое значение быстро переключалось между истиной и ложью как для "перетаскивания", так и для перетаскиванияOL

HTML структура

     <ol id="product-images" @dragenter="draggingOL=true" @dragleave="draggingOL=false">

        <li v-for="(file, key) in files" style="pointer-events: none;"></li>

      </ol>


      <div v-show="files.length < 1 || draggingOL == true">
         <div ref="fileform" :class="['next-upload-dropzone', dragging ? 'css1' : '', draggingOL ? 'css1 css2' : '']" @dragenter="dragging=true" @dragleave="dragging=false">

         </div>
      </div>

После перетаскивания изображения в тег DIV появится тег OL.

У тега OL нет перетаскиваемого элемента, поэтому я добавил Dragenter и ушел в OL

Когда я добавляю второй перетаскивающий элемент в тег OL, когда вы перетаскиваете изображение в область, логическое значение перетаскивания и перетаскиванияOL быстро переключается между истиной и ложью с интервалом 0,5 с. То же самое для css, показать и показать очень быстро.

Я пробовал несколько способов, включая только один Драгентер, ту же проблему. Возможно, проблема с V-шоу, я не уверен.

Изображение <div> Выше изображение тега DIV Изображение OL Выше изображение тега OL

Javascript

var dropFileApp = new Vue({
    el: '#dropfile',
    data: {
        dragAndDropCapable: false,
        dragging : false,
        draggingOL : false,
        files: [],
        uploadPercentage: 0
    },
    // define methods under the `methods` object
    mounted(){
  /*
    Determine if drag and drop functionality is capable in the browser
  */
  this.dragAndDropCapable = this.determineDragAndDropCapable();

  /*
    If drag and drop capable, then we continue to bind events to our elements.
  */
  if( this.dragAndDropCapable ){
    /*
      Listen to all of the drag events and bind an event listener to each
      for the fileform.
    */
    ['drag', 'dragstart', 'dragend', 'dragover', 'dragenter', 'dragleave', 'drop'].forEach( function( evt ) {
      /*
        For each event add an event listener that prevents the default action
        (opening the file in the browser) and stop the propagation of the event (so
        no other elements open the file in the browser)
      */
      this.$refs.fileform.addEventListener(evt, function(e){
        e.preventDefault();
        e.stopPropagation();
      }.bind(this), false);
    }.bind(this));

    /*
      Add an event listener for drop to the form
    */

    this.$refs.fileform.addEventListener('drop', function(e){
      /*
        Capture the files from the drop event and add them to our local files
        array.
      */
      for( let i = 0; i < e.dataTransfer.files.length; i++ ){
        this.files.push( e.dataTransfer.files[i] );
        this.getImagePreviews();
      }
      console.log((this.files.length))
      /*
        Instantly upload files
      */
      this.submitFiles();
    }.bind(this));
  }
},

methods: {
  /*
    Determines if the drag and drop functionality is in the
    window
  */
  determineDragAndDropCapable(){
    /*
      Create a test element to see if certain events
      are present that let us do drag and drop.
    */
    var div = document.createElement('div');

    /*
      Check to see if the `draggable` event is in the element
      or the `ondragstart` and `ondrop` events are in the element. If
      they are, then we have what we need for dragging and dropping files.

      We also check to see if the window has `FormData` and `FileReader` objects
      present so we can do our AJAX uploading
    */
    return ( ( 'draggable' in div )
            || ( 'ondragstart' in div && 'ondrop' in div ) )
            && 'FormData' in window
            && 'FileReader' in window;
  },

  /*
    Gets the image preview for the file.
  */
  getImagePreviews(){
    /*
      Iterate over all of the files and generate an image preview for each one.
    */
    for( let i = 0; i < this.files.length; i++ ){
      /*
        Ensure the file is an image file
      */
      if ( /\.(jpe?g|png|gif)$/i.test( this.files[i].name ) ) {
        /*
          Create a new FileReader object
        */
        let reader = new FileReader();

        /*
          Add an event listener for when the file has been loaded
          to update the src on the file preview.
        */
        reader.addEventListener("load", function(){
          this.$refs['preview'+parseInt( i )][0].src = reader.result;
        }.bind(this), false);

        /*
          Read the data for the file in through the reader. When it has
          been loaded, we listen to the event propagated and set the image
          src to what was loaded from the reader.
        */
        reader.readAsDataURL( this.files[i] );
      }else{
        /*
          We do the next tick so the reference is bound and we can access it.
        */
        this.$nextTick(function(){
          this.$refs['preview'+parseInt( i )][0].src = '/images/file.png';
        });
      }
    }
  },

  /*
    Submits the files to the server
  */
  submitFiles(){
    /*
      Initialize the form data
    */
    let formData = new FormData();

    /*
      Iteate over any file sent over appending the files
      to the form data.
    */
    for( var i = 0; i < this.files.length; i++ ){
      let file = this.files[i];

      formData.append('files[' + i + ']', file);
    }

    /*
      Make the request to the POST /file-drag-drop URL
    */
    axios.post( '/file-drag-drop',
      formData,
      {
        headers: {
            'Content-Type': 'multipart/form-data'
        },
        onUploadProgress: function( progressEvent ) {
        //Showing Loading   
        }.bind(this)
      }
    ).then(function(){
      console.log('SUCCESS!!');
    })
    .catch(function(){
      console.log('FAILURE!!');
    });
  },

  /*
    Removes a select file the user has uploaded
  */
  removeFile( key ){
    this.files.splice( key, 1 );
  }
}
})

Я буду продолжать тестировать, отлаживать и обновлять эту ветку.

1
CodeGuru 3 Янв 2019 в 03:07

3 ответа

Лучший ответ

Решение состоит в том, чтобы не использовать @dragleave

Я изменил логическое значение для draggingOL на false после запуска запроса на публикацию изображения вручную вместо использования @dragleave.

0
CodeGuru 4 Янв 2019 в 01:19

Я решил это, добавив прозрачный оверлей к моему оверлею:

<div style="position: relative"
   @dragenter.prevent.stop="dropzone = true"
   @dragover.prevent.stop="dropzone = true"
  >
    <!-- Bunch of other stuff here -->

    <div v-if="dropzone" class="dropzone" >
      <i class="material-icons">cloud_upload</i>
      <div class="dropzone_text">Drop files here</div>

      <!-- transparent, catches drop & dragleave events -->

      <div style="width: 100%; height: 100%; position: absolute"
        @drop.prevent.stop="dropzone = false"
        @dragleave.prevent.stop="dropzone = false"
      ></div>
</div>
1
luff 28 Ноя 2019 в 13:10

У меня была похожая проблема. Это было решено, вам нужно предотвратить всплывание событий для событий Vue: Предотвращение появления событий в Vue

<div v-on:dragleave.self="dragLeave($event)">
    ...
</div>
3
Павел Швецов 5 Апр 2019 в 13:18