【发布时间】:2016-02-01 06:33:20
【问题描述】:
我有一个带有可拖动行的 HTML 表格。根据this answer,我正在“取消”dragover 事件。
dest.addEventListener( 'dragover', function(evt){
evt.dataTransfer.dropEffect = 'copy';
if (evt.preventDefault) evt.preventDefault();
return false;
}, false );
根据MDN,我在(我认为)所有正确的地方打电话给preventDefault()。
dest.addEventListener( 'drop', function(evt) {
this.classList.remove('over');
...
if (evt.stopPropagation) evt.stopPropagation();
return false;
}, false );
拖放在 Chrome 和 Safari 中完美运行。在 Firefox 中,拖放可以工作,然后 Firefox 会重定向到一个新的 URL。
var src = document.querySelector('#src tbody'),
dest = document.querySelector('#dest tbody');
var people = [
{name:'Gavin', age:42},
{name:'Bjørn', age:17},
{name:'Leyla', age:24}
];
people.forEach(function(person,i){
var tr = rowFor(person);
src.appendChild(tr);
tr.draggable = true;
tr.addEventListener( 'dragstart', function(evt){
this.classList.add('drag','selected');
evt.dataTransfer.dropEffect = 'copy';
evt.dataTransfer.setData( 'text', i );
return false;
}, false );
tr.addEventListener( 'dragend', function(evt){
if (evt.preventDefault) evt.preventDefault();
this.classList.remove('drag');
return false;
}, false );
});
dest.addEventListener( 'dragenter', function(evt){
this.classList.add('over');
return false;
}, false );
dest.addEventListener( 'dragover', function(evt){
evt.dataTransfer.dropEffect = 'copy';
this.classList.add('over');
if (evt.preventDefault) evt.preventDefault();
return false;
}, false );
dest.addEventListener( 'dragleave', function(evt){
this.classList.remove('over');
return false;
}, false );
dest.addEventListener( 'drop', function(evt) {
this.classList.remove('over');
var index = evt.dataTransfer.getData('Text');
var dup = rowFor( people[index] );
dest.appendChild( dup );
if (evt.stopPropagation) evt.stopPropagation();
return false;
}, false );
function rowFor(obj){
var tr = document.createElement('tr');
tr.innerHTML = "<td>"+obj.name+"</td><td>"+obj.age+"</td>";
return tr;
}
body { background:#eee }
#wrap {
display:flex;
flex-direction:row;
justify-content:space-between;
align-items:flex-start;
flex-grow:1;
height:400px;
padding:1em
}
table { width:200px; border-collapse:collapse; border:1px solid #ccc }
tbody { background:#fff }
th,td { padding:0 5px }
th { text-align:left; background:#ddd }
caption { background:#ccc }
table.over { border:2px solid yellow }
tr.selected td { background:lightblue }
table { display:flex; flex-flow:column; height:100%; margin-right:4px; overflow:hidden }
table caption { flex:0 0 auto; width:100%; display:block }
table thead { flex:0 0 auto; width:calc(100% + 1px) }
table tbody { flex:1 1 auto; display:block; overflow-y:auto }
table tbody tr { width:100% }
table thead,
table tbody tr { display:table; table-layout:fixed }
tbody tr { cursor:default }
thead th:last-child,
tbody td:last-child { width:33%; }
<div id="wrap">
<table id="src">
<caption>drag from here</caption>
<thead><tr><th>name</th><th>age</th></tr></thead>
<tbody></tbody>
</table>
<table id="dest">
<caption>drag to here</caption>
<thead><tr><th>name</th><th>age</th></tr></thead>
<tbody></tbody>
</table>
</div>
代码片段也可通过jsfiddle.net/8d96vpws/3/获得
如何阻止 Firefox 更改位置?
【问题讨论】:
-
将
evt.preventDefault();放到drop监听器上。 -
天啊。深夜的眼睛。我一直将
stopPropagation视为preventDefault。 @Teemu Post 作为代表的答案。 -
看起来 ashan_SL 已经有了相同的答案。顺便提一句。如果您使用过
addEventListener,则无需检查evt.stopPropagation或evt.preventDefault是否存在,如果addEventListener存在,它们将存在。
标签: javascript firefox html5-draggable