前回あったカードがどこかへ行ってしまう不具合を修正しました。 具体的には onload 時にスクロールのイベントリスナーを追加し、テーブル(div 要素) の左上のクライアント座標を、スクロール後に取得し直すように変更しました。
<script type="text/javascript" src="js/dragondrop02/dragndrop02.js"></script>
この HTML で使う style を指定します。前回から変更はありません。
<style> #table { width: 97%; height: 300px; padding: 10px; background-color: tan; position: relative; } #card1, #card2 { position: absolute; } #card1 { z-index: 1; left: 10px; top: 10px; } #card2 { z-index: 2; left: 20px; top: 20px; } </style>カード2枚(img 要素)とテーブル(div 要素)。前回から変更ありません。
<h2>実行結果</h2> <div id="table"> <img src="img/card1.png" id="card1"> <img src="img/card2.png" id="card2"> </div>
前回のドラッグアンドドロップの処理に、スクロール後、テーブルの左上のクライアント座標 tableX, tableY を取得し直す処理を加えました。スクロール直後はまださらにスクロール する可能性があるので、500ms 待ってから取得します。
window.onload = function() { var offsetX = 0; var offsetY = 0; var table = document.getElementById('table'); var tableX = table.getBoundingClientRect().left; var tableY = table.getBoundingClientRect().top; var timeoutID; window.addEventListener('scroll', function () { // wait 500ms after scroll stop clearTimeout(timeoutID); timeoutID = setTimeout(function() { // update tableX and tableY table = document.getElementById('table'); tableX = table.getBoundingClientRect().left; tableY = table.getBoundingClientRect().top; }, 500); }); var cards = document.querySelectorAll('[id^="card"]'); for (var i = 0; i < cards.length; i++) { var card = cards[i]; card.addEventListener('dragstart', function(e) { e.dataTransfer.setData('text', e.target.id); x = e.clientX; y = e.clientY; var card = document.getElementById(e.target.id); offsetX = x - card.getBoundingClientRect().left; offsetY = y - card.getBoundingClientRect().top; }, false); } // drop var dzone = document.getElementById('table'); var zTop = 2; dzone.addEventListener('dragenter', function(e) { e.preventDefault(); }, false); dzone.addEventListener('dragover', function(e) { e.preventDefault(); }, false); dzone.addEventListener('drop', function(e) { e.preventDefault(); rx = e.clientX - tableX; ry = e.clientY - tableY; var id = e.dataTransfer.getData('text'); var card = document.getElementById(id); card.style.left = String(rx - offsetX) + 'px'; card.style.top = String(ry - offsetY) + 'px'; card.style.zIndex = ++zTop; }, false); }
マウスポインタがテーブルの中であればドロップが実行されます。 テーブルの端でドロップするとカードがはみ出すことがあります。 この問題はあまり支障がないので今のところ直す予定はありません。