【问题标题】:Conflicting @Dragenter @Dragleave / v-show Events keep firing rapidly冲突的@Dragenter @Dragleave / v-show 事件不断快速触发
【发布时间】:2019-01-03 00:07:45
【问题描述】:

指针事件:无;已经实现,在调试中,布尔值在“拖动”和“拖动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

当我将第二个 dragenter 添加到 OL 标签时,当您将图像拖入该区域时,dragging 和 draggingOL 的布尔值将以 0.5s 的间隔在 true 和 false 之间快速切换。 css 也一样,显示和取消显示非常迅速。

我尝试了几种方法,包括只有一个 Dragenter,同样的问题。也许问题出在v-show,我不确定。

上面是DIV标签的图片 以上是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 );
  }
}
})

我将继续测试和调试和更新这个线程。

【问题讨论】:

  • 您的 v-show 似乎正在切换可见性。当可见性改变时drag-leave。您可以制作一个 jsfiddle 或提供可隔离问题的可运行代码吗?这可能会使提供解决方案变得更容易。
  • @Daniel 无法让 CSS 工作,我觉得我的 CSS 现在太乱了,嗯,好的,谢谢您对 v-show 的建议

标签: javascript vue.js vuejs2 drag-and-drop draggable


【解决方案1】:

我有类似的问题。已经解决,需要防止Vue事件的事件冒泡: Prevent event bubbling in Vue

<div v-on:dragleave.self="dragLeave($event)">
    ...
</div>

【讨论】:

    【解决方案2】:

    我在接下来的代码中修复了同样的问题:

    1. 删除了“v-on:dragleave”
    2. 上传(或刚刚选择)文件时运行“this.draggingOL=false”
    3. 添加了“v-on:mouseleave="draggingOL=false"'

    它对我有用! 希望它可以帮助某人:)

    【讨论】:

      【解决方案3】:

      我通过在我的叠加层中添加一个透明叠加层来解决它:

      <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>

      【讨论】:

      • 不错的建议。
      【解决方案4】:

      解决办法是不要使用@dragleave

      在手动触发图像的发布请求时,我将 draggingOL 的布尔值更改为 false,而不是使用 @dragleave。

      【讨论】:

        猜你喜欢
        • 2011-02-07
        • 1970-01-01
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        • 2016-09-03
        • 2012-12-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多