私のソリューションはjQueryを使用しており、コンパクトなコード(コメントなしの52行、1.8 kb)があり、垂直軸に沿って親コンテナー内で要素を相対的に配置する必要があります。
思考の流れ全体がJavaScriptでコメント化されています。
jsFiddleの実際の動作 (コメントなしのコード)。
HTMLマークアップ
<!DOCTYPE html> <html><head> <meta charset='utf-8'> <link type='text/css' rel='stylesheet' href='style.css'> <script type='text/javascript' src='http://code.jquery.com/jquery-2.0.3.min.js'></script> <script type='text/javascript' src='actions.js'></script> </head><body> <div id="container"> <div class="drag">1</div> <div class="drag">2</div> <div class="drag">3</div> <div class="drag">4</div> <div class="drag">5</div> </div> </body></html>
style.css
#container {position:absolute; width:500px; top:100px;} .drag {position:relative; cursor:default; z-index:1;}
actions.js
$(document).ready(function(){ $.fn.draggable = function(){ // function disableSelection(){ return false; } // $(this).mousedown(function(e){ var drag = $(this); // var posParentTop = drag.parent().offset().top; // var posParentBottom = posParentTop + drag.parent().height(); // var posOld = drag.offset().top; // var posOldCorrection = e.pageY - posOld; // z- drag.css({'z-index':2, 'background-color':'#eeeeee'}); // var mouseMove = function(e){ // var posNew = e.pageY - posOldCorrection; // if (posNew < posParentTop){ // , drag.offset({'top': posParentTop}); // DOM, ( ) // , if (drag.prev().length > 0 ) { drag.insertBefore(drag.prev().css({'top':-drag.height()}).animate({'top':0}, 100)); } // } else if ((posNew + drag.height()) > posParentBottom){ // , + - drag.offset({'top': posParentBottom - drag.height()}); // DOM, ( ) // , if (drag.next().length > 0 ) { drag.insertAfter(drag.next().css({'top':drag.height()}).animate({'top':0}, 100)); } // } else { // ( ) drag.offset({'top': posNew}); // if (posOld - posNew > drag.height() - 1){ // DOM drag.insertBefore(drag.prev().css({'top':-drag.height()}).animate({'top':0}, 100)); // drag.css({'top':0}); // posOld = drag.offset().top; posNew = e.pageY - posOldCorrection; posOldCorrection = e.pageY - posOld; // } else if (posNew - posOld > drag.height() - 1){ // DOM drag.insertAfter(drag.next().css({'top':drag.height()}).animate({'top':0}, 100)); drag.css({'top':0}); posOld = drag.offset().top; posNew = e.pageY - posOldCorrection; posOldCorrection = e.pageY - posOld; } } }; // var mouseUp = function(){ // $(document).off('mousemove', mouseMove).off('mouseup', mouseUp); // $(document).off('mousedown', disableSelection); // drag.animate({'top':0}, 100, function(){ // z- drag.css({'z-index':1, 'background-color':'transparent'}); }); // // (cookie post- , ) }; // // , $(document).on('mousemove', mouseMove).on('mouseup', mouseUp).on('contextmenu', mouseUp); // $(document).on('mousedown', disableSelection); // , (, ) $(window).on('blur', mouseUp); }); } $('.drag').draggable(); });
コード(こことjsFiddleで)は、発見された欠陥の修正の結果として更新されます。これはコメントで通知します。
未解決の問題:親コンテナーの境界を超えて要素をすばやくドラッグしながら要素をジャークします。