简体   繁体   中英

Stop HTML5 drop from redirecting Firefox

I have an HTML table with draggable rows. Per this answer I am 'cancelling' the dragover event.

dest.addEventListener( 'dragover', function(evt){
  evt.dataTransfer.dropEffect = 'copy';
  if (evt.preventDefault) evt.preventDefault();
  return false;
}, false );

Per MDN I am calling preventDefault() in (I think) all the right places.

dest.addEventListener( 'drop', function(evt) {
  this.classList.remove('over');
  ...
  if (evt.stopPropagation) evt.stopPropagation();
  return false;
}, false );

The drag/drop works perfectly in Chrome and Safari. In Firefox, the drag/drop works, and then Firefox redirects to a new 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> 

Snippet also available at jsfiddle.net/8d96vpws/3/

How do I stop Firefox from changing location?

I think first you need when drop, stop action without checking condition. this happen condition not true at this point. after you can find some issues in this code.

dest.addEventListener( 'drop', function(evt) {
  evt.preventDefault();
  evt.stopPropagation();
  this.classList.remove('over');
  ...
}, false );

see below

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM