冲突的@Dragenter @Dragleave / v-show 事件持续快速触发
Conflicting @Dragenter @Dragleave / v-show Events keep firing rapidly
指针事件:none;已经实现,在调试中,布尔值在 "dragging" 和 draggingOL
的 true 和 false 之间快速切换
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 ONLY,同样的问题。也许问题出在 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 );
}
}
})
我会继续测试和调试并更新此线程。
解决方法是不使用@dragleave
我在手动触发 post 图像请求时将 draggol 的布尔值更改为 false,而不是使用 @dragleave。
我有类似的问题。已经解决,需要防止Vue事件的事件冒泡:
<div v-on:dragleave.self="dragLeave($event)">
...
</div>
我在接下来的代码中解决了同样的问题:
- 删除了“v-on:dragleave”
- 运行 'this.draggingOL=false' 当文件已上传(或刚刚选择)时
- 添加了'v-on:mouseleave="draggingOL=false"'
它对我有用!
希望对某人有所帮助:)
我通过在叠加层上添加透明叠加层解决了这个问题:
<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>
指针事件:none;已经实现,在调试中,布尔值在 "dragging" 和 draggingOL
的 true 和 false 之间快速切换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 ONLY,同样的问题。也许问题出在 v-show 上,我不确定。
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 );
}
}
})
我会继续测试和调试并更新此线程。
解决方法是不使用@dragleave
我在手动触发 post 图像请求时将 draggol 的布尔值更改为 false,而不是使用 @dragleave。
我有类似的问题。已经解决,需要防止Vue事件的事件冒泡:
<div v-on:dragleave.self="dragLeave($event)">
...
</div>
我在接下来的代码中解决了同样的问题:
- 删除了“v-on:dragleave”
- 运行 'this.draggingOL=false' 当文件已上传(或刚刚选择)时
- 添加了'v-on:mouseleave="draggingOL=false"'
它对我有用! 希望对某人有所帮助:)
我通过在叠加层上添加透明叠加层解决了这个问题:
<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>