jQueryでシンプルなドラッグドロップがまずい

このQ&Aのポイント
  • jQueryでシンプルなドラッグドロップ自作をやってみましたが、うまくいきません。
  • ドラッグドロップした後は、離している状態のupにならず、押さずに動かしても要素がついてきます。
  • 短くてシンプルなjQueryのドラッグドロップのサンプルが見つからず、どうやって回避する方法が知りたいです。
回答を見る
  • ベストアンサー

jQueryでシンプルドラッグドロップがまずい

Javascript,jQuery初心者です。主にWINDOWS7、GoogleChrome使用です。 jQueryでシンプルなドラッグドロップ自作をやってみました。 <!DOCTYPE html> <html> <head> <meta carset="utf-8"> <script src="js/jquery-1.11.0.min.js"></script> <style> #chr{ position:absolute; left:100px; top:100px; } </style> <body> <div id="msg"></div> <div id="chr"> <img src="parts/usl470.jpg"> </div> <script> dragflg=false; $("#chr").mousedown(function(){ dragflg=true; $("#msg").html("on")}) .mouseup(function(){ dragflg=false; $("#msg").html("up")}); $(window).mousemove(function(e){ if(dragflg) { $("#chr").css("left",e.clientX-20+"px") .css("top",e.clientY-20+"px"); } }); </script> </body> </head> </html> mousedown、mouseupの検出を確認するために、隅にon、upと表示するようにしてあります。 思惑通り、押すとon、離すとupが表示されますが、ドラッグドロップした後は、離している状態のupになってくれず、押さずに動かしても#chrはついてきてしまいます。まともなドラッグドロップと違い、もう1回クリックでやっと離してくれる、という具合です。  #chr上でボタンを離している時はそれを検出するんじゃないのか?と思ってしまうのですが、ついでに、ドラッグ動作自体も、移動禁止マークが出てちょっとおかしいし、詳しい人はどうやってこういう症状を回避してドラッグドロップの動作を実現しているのでしょうか?  ネットで見て回って参考にしようにも、短くてシンプルなjQueryのドラッグドロップのサンプルが見つからず、ここで何が間違いなのか意見を仰ごうと思ったものです。手っ取り早くjQueryUIを導入すれば、やりたいこと自体は出来るんでしょうけど、ボタン離していても検出できないのが何なのかは、すっきりしておきたいと思いました。どうかよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.1

この手のことをやったことはありませんが、興味があったので試してみました。 スクリプトとは関係なしに、ブラウザ側の機能として表示中の要素をドラッグしようとすると移動禁止マークが出るように、ドラッグに対しての反応が組み込まれているようです。 >ドラッグ動作自体も、移動禁止マークが出てちょっとおかしいし、~ 上記のブラウザ側の処理が働いていると想像します。 これをキャンセルしておかないとドラッグ&ドロップの制御はうまくいかないようですね。キャンセルするには、イベントの伝搬を止めておけばよさそうです。 というわけで、こんな感じ? (クリックした位置が変わらないように、少しロジックを変えています) (全角空白は半角に) <!DOCTYPE html> <html lang="ja"> <head>Sample</head> <style> #chr{ position:absolute; left:100px; top:100px; } </style> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script type="text/javascript"> (function(){  var drag = { flag:false };  $(document).mousedown(function(e){   if($(e.target).parent().attr("id")!="chr") return;   var o = $("#chr").offset();   drag.deff = { x:o.left - e.pageX, y:o.top - e.pageY };   drag.flag = true;   e.preventDefault();  }).mousemove(function(e){   if(!drag.flag) return;   $("#chr").css({top: e.pageY + drag.deff.y, left: e.pageX + drag.deff.x});   e.preventDefault();  }).mouseup(function(){   drag.flag = false;  }); })(); </script> </head> <body> <div id="msg"></div> <div id="chr"> <img src="parts/usl470.jpg"> </div> </body> </html>

参考URL:
http://api.jquery.com/event.preventDefault/
zchess
質問者

お礼

犯人は、ブラウザのデフォルト動作だったんですか。 それにしても、すごい!! クリックした位置まで変わらないようにしてるのに、こんなに短く実現できるんですね。 デフォルトの動作を抑止するevent.preventDefaultの使い方といい、 恥ずかしながら、知らない技法がいっぱいです。 シンプルなのに学ぶことの多いお手本です。ありがとうございました。

関連するQ&A

  • jQuery。セレクタに変数を使えないケース?

    Javascript勉強駆け出しの者です。WIN7、Chromeを主に使っています。 <!DOCTYPE html> <html> <head> <meta carset="utf-8"> <script src="js/jquery-1.11.0.min.js"></script> <style> .chr{ position:absolute; } </style> </head> <body> <div id="gyoku" class="chr" style="top:60px;left:0;"> <img src="parts/gyoku.png"> </div> <div id="hisya" class="chr" style="top:120px;left:0;"> <img src="parts/hisya.png"> </div> <div id="kaku" class="chr" style="top:180px;left:0;"> <img src="parts/kaku.png"> </div> <script> var chrid; dragflg=false; $(".chr").css("position","absolute") .mousedown(function() { dragflg=true; chrid=$(this).attr('id'); }) .mouseup(function(){ dragflg=false; }); // $("#gyoku").mousemove(function(e){ $("#"+chrid).mousemove(function(e){ if(dragflg) {  e.preventDefault(); $(this).css("left",e.clientX-20+"px") .css("top",e.clientY-20+"px"); } }); </script> </body> </html> 一応、シンプルにドラッグドロッププログラムを書くというのを目指したものです。 対象のキャラ(約35×50px)を3つほど用意し、mousedown時に変数chridにid名を読み込み、切り替えてドラッグドロップするという狙いですが、うまくmousemoveがいきません。mousemove行を1行上のコメント行に差し替えて個別にidを直接書けば意図通り動くのに、変数を使用するとダメなようです。jQuery解説サイトでも、セレクタに"文字列"+変数という書き方は使える、という説明で、"#gyoku"と chridに"gyoku"を読み込んでいる時の"#"+chrid は同じ意味と認識しているのですが、違うのでしょうか? どうすればうまく動くのか、どなたかご教示お願いします。 jQueryUIを使った方が手っ取り早いというご指摘もあるかと思いますが、この際、jQueryのセレクタで変数が無効なケースとは何かを知りたくなってしまったので、これはこれとして教えていただければ幸いです。

  • jQueryで質問です。

    jQueryで質問です。 オブジェクトA、Bがあるとします。 Aをドラッグすると、mousedownかdragstartの段階で要素がBに置き換わってドラッグさせるような動きは可能でしょうか。 作成中のソースを記載します。 <html> <head> <title>test</title> <script type="text/javascript" src="./jquery.min.js"></script> <script type="text/javascript" src="./ui/jquery.ui.core.js"></script> <script type="text/javascript" src="./ui/jquery.ui.widget.js"></script> <script type="text/javascript" src="./ui/jquery.ui.mouse.js"></script> <script type="text/javascript" src="./ui/jquery.ui.draggable.js"></script> <script type="text/javascript" src="./ui/jquery.ui.droppable.js"></script> <script type="text/javascript"> $(function(){ obj1 = $("#box"); obj2 = $('<div style="width:200px;height:200px;background:red;">B</div>'); obj1 .mousedown( function(){ obj1.replaceWith(obj2); obj2.draggable(); } ); }); </script> </head> <body> <div style="width:200px; height:100px; background: #cccccc;" id="box">A</div> </body> </html> これだと、Aのドラッグを一度解除して、Bをドラッグすると上手くいきますが、1回のモーションでBをドラッグさせたいのです。 宜しくお願いします。

  • JQueryを使用して、画像をドラッグで拡大・縮小できるボタンを画像右

    JQueryを使用して、画像をドラッグで拡大・縮小できるボタンを画像右下に配置しようと考えています。 以下のようなコードを作成したのですが、firefox(3.6.3)だとmouseupによるmousemoveのunbindがうまくいかず、mousemoveが維持されます。 IE8、chrom、operaでは考えたとおりの動きをしますが、ときたまchromでfirefoxと同様の不具合がおきます。 どのようにコードを修正すればよいでしょうか? ------------------------ <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style type="text/css"> <!-- div#frame1{ position : absolute; height : 360px; width : 240px; top : 0; left : 0; border : 5px solid #000FFF; } div#frame1 img#handle{ position : absolute; bottom : 0; right : 0; border : 5px solid #FFF000; } //--> </style> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript"> <!-- $(function(){ $("img#handle").mousedown(function(e){ $("#frame1") .data("mdownX" , e.clientX) .data("mdownY" , e.clientY); $(document).mousemove(function(e){ var width = parseInt($("div#frame1").css("width"),10); var height = parseInt($("div#frame1").css("height"),10); $("div#frame1").css({ width : width + (e.pageX - $("#frame1").data("mdownX")) + "px", height : height + (e.pageY - $("#frame1").data("mdownY")) + "px" }); $("#frame1") .data("mdownX" , e.pageX) .data("mdownY" , e.pageY); }); }); $(document).mouseup(function(){ $(document).unbind("mousemove"); }); }); //--> </script> <title>zoom</title> </head> <body> <div id="frame1"> <img id="handle" src="image.bmp" alt="画像"/> </div> </body> </html>

  • jquery bindがとまらない

    jquery の bindを使い、以下のサイトを参考にしながら、実装を試みているのですが、unbindしてもとまらなくなってしまいました。 mousedown、mousemove、mouseup を使い、mousedownした時点のx座標と、mousemoveしている間のx座標の差を取り、mouseup時に移動距離を表示するというものをとりあえず作りたいのですが、mousemoveが永遠続いてしまい、mouseupしてもとまりません。 $('#main_body').mousedown(function(e){ now_x = e.pageX; alert(now_x); $(document).mousemove(function(e){ now_x2 = e.pageX; alert(now_x2); }) }).mouseup(function(){ alert("bbbb"); $(document).unbind("mousemove"); }); これですと、now_x2がずっと出続けてしまいます。。。 どうか、お力をお貸しください。 よろしくお願い致します。 参考サイト: http://weble.org/2011/03/08/jquery-floatingbox

  • jQuery UIのdraggableについて

    こちらでは初めて質問させていただきます。 よろしくお願いします。 現在、jQuery UI の draggable を使用してWebブラウザ上での ドラッグ&ドロップを実装中なのですが、 期待通りに動作させることが出来ません。 <script></script> …… (1) <html> <head> <script type="text/javascript" src="jQuery/jquery-1.3.2.js"></script> <script type="text/javascript" src="jQuery/jquery-ui-1.7.2/development-bundle/ui/ui.core.js"></script> <script type="text/javascript" src="jQuery/jquery-ui-1.7.2/development-bundle/ui/ui.draggable.js"></script> <style> #a { height:100px; width:300px; overflow:scroll; border:solid 1px Black; } #b { width:60px; height:40px; background:lime; position:absolute; top:10px; left:50px } #c { width:60px; height:40px; background:lime; position:absolute; top:60px; left:50px } </style> <script type="text/javascript"> $j = jQuery.noConflict(); $j(function($) { $('#b').draggable(); }); $j(function($) { $('#c').draggable(); }); </script> </head> <body> <div id="a"> <span id="b">Drag Element1</span> <span id="c">Drag Element2</span> </div> </body> </html> ドラッグ対象は複数存在するため、ドラッグ対象を<div>エリア内で スクロール(必須です)させています。 ドラッグ対象を<div>エリア外にドラッグしたいのですが、 <div>エリア内しかドラッグできません。 ((1)の記述がないと、ドラッグ対象が<div>エリア内でスクロール しませんでした。???) どなたか、よきアドバイスをお願いします。

  • ドラッグをさせない方法は?

    現在、JavaScriptでドラッグを不可にさせるような方法を 探しております。  ドラッグといっても、画像等のドラッグ&ドロップでは なく、画面内の文字をドラッグ(mousedownさせたまま、 mousemoveみたいな感じ。うまく表現できなくて申し訳 ありません)  なにか良い方法をご存知の方はいらっしゃいませんで しょうか?    mousedownイベント発生時に強制的にmouseupや mousemoveを不可にするような方法があれば良いとは 思っているのですが・・・。  よろしくお願いいたします。

  • jqueryで、後から追加した画像もドラッグ&ドロップできるようにした

    jqueryで、後から追加した画像もドラッグ&ドロップできるようにしたい 以下のようにして、画像をドラッグ&ドロップできるようにしています そこに、新たに画像をアップロードして、その画像もドラッグできるようにするところで詰まってしまいました アップロードする時に画面遷移を起こしたくなかったので、インラインフレームを使っています upload.phpでアップロードされた画像を取得して、divタグのクラス名を指定したりしてappendChildで親フレームに挿入 しかし、画像が表示されはするのですがドラッグしようとしても何も起こらない状態です Firebugでも見てみると、元の画像は <div class="dragArea ui-draggable"><img src="./img0.jpg" width="100" height="100"></div> となっていますが、アップロードした画像(新規追加した要素)は、 <div id="adddragfile"><div class="dragArea"><img src="././tmp/newimg.jpg" width="100" height="100"></div></div> となっていて、ドラッグ属性が付いていないように思えます よろしくお願いします /* include.php */ //ドラッグ可能な画像 <div class='dragArea'><img src='./img0.jpg' width='100' height='100'></div> //ここにタグを追加していく <div id='adddragfile'></div> //ドロップ先となる画像 <div class='dropArea'><img src='./img1.jpg' width='300' height='300'></div> <div class='dropArea'><img src='./img2.jpg' width='300' height='300'></div> //ファイルのアップロード <iframe title='upload_frame' name="upload_frame" style="display:none"></iframe> <form action="./upload.php" method="post" enctype="multipart/form-data" target="upload_frame"> <input type="hidden" name="max_file_size" value="1000000"> <input type="file" name="upload_image"> <input type="submit" value="画像アップロード"> </form> /* jqueryファイル */ $(function(){ $(".dragArea").draggable({ cursor:'move', helper:'clone' }); $(".dropArea").droppable({ drop:function(e,ui){ alert("ドロップされました"); } }); }); /* upload.php */ <?php $upload_dir = './tmp/'; $filename = $_FILES['upload_image']['name']; move_uploaded_file($_FILES['upload_image']['tmp_name'], $upload_dir.$filename); ?> <script type="text/javasscript"> //親フレームのオブジェクトを取得 var container = parent.document.getElementById('adddragfile'); //要素を作成していく div = parent.document.createElement('div'); div.className = "dragArea"; image = parent.document.createElement('img'); image.src = './<?php print($upload_dir.$filename);?>'; image.width = "100"; image.height = "100"; container.appendChild(div); div.appendChild(image); </script>

  • jQueryのdraggable縦書き出来ますか?

    プログラム自体初めてなのですが、仕事の関係で作らないといけない事になりました。 目的は、「文字が書かれた札をドラッグで色々と動かして操作したいです。」 jQueryのdraggableを使用して札のようなものをマウスのドラッグで色々と動かしたいと考え 作ってみましたが、札の中がどうしても横書きになってしまいます。 「札の中を縦書きにする方法を教えて頂けないでしょうか?」 基本的な考え方が間違っているかもしれませんが出来るのであればどうか教えてほしいです。 とりあえずここまでは書いています。 質問が分かりづらく申し訳ありません。 <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet"href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" /> <script src="http://code.jquery.com/jquery- 1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script> <link rel="stylesheet" href="/resources/demos/style.css" /> <style> #draggable01 { width: 25px; height: 500px; padding: 0.5em; } #draggable02 { width: 25px; height: 350px; padding: 0.5em; } </style> <script> $(function() { $( "#draggable01" ).draggable(); }); </script> <script> $(function() { $( "#draggable02" ).draggable(); }); </script> </head> <body> <div> <div id="draggable01" class="ui-widget-content"> <p>あいうえお</p></div> <div id="draggable02" class="ui-widget-content"> <p>かきくけこ</p></div> </div> </body></html>

  • borderの箇所をマウスでクリック

    cssでborderを指定し ajaxで枠内、枠外では何も動作しないが borderの箇所をマウスでクリックした場合のみ 動ささせるにはどのようにすればいいでしょうか。 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { $("div.button").mousedown(function () { $("div#message").text("マウスのボタンが押されました。"); }) $("div.button").mouseup(function () { $("div#message").text("マウスのボタンがはなされました。"); }) }) </script> <style> .button { border: solid 1px #0094ff; background-color: #e1e1e1; width: 200px; height: 32px; } </style> </head> <body> <div class="button">枠</div> <div id="message"></div> </body> </html>

    • ベストアンサー
    • AJAX
  • 【as3】クリックでインスタンスを増やしたい

    Actionscript初心者です。 勉強のため、以下のURLにあるActionscript2.0のFlashをActionscript3.0に書き換えたいと思っています。 http://allabout.co.jp/gm/gc/66814/ 左側にリースのパーツ、右に素のままのリースが配置されています。パーツはそれぞれ、リボン付きベル(インスタンス名「bellBig」)、松ぼっくり (インスタンス名「matu」)、小さいベル(インスタンス名「bellSmall」)と指定してあります。この3つのアイテムをドラッグドロップすることでリースを飾り付けていきます。 インスタンスをドラッグ&ドロップする所まではできたのですが、 松ぼっくりと小さいベルをドラッグした際にインスタンスを複製するところでつまずいています。 あまりにも初歩的な質問で恐縮ですが、ご教授お願いいたします。 /*////////////////////大きいベル/////////////////////*/ // ドラッグ開始 bellBig.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown1); function mouseDown1(event:MouseEvent):void{ bellBig.startDrag(); } // ドラッグ終了 bellBig.addEventListener(MouseEvent.MOUSE_UP,mouseUp1); function mouseUp1(event:MouseEvent):void{ bellBig.stopDrag(); } /*////////////////////まつぼっくり/////////////////////*/ // ドラッグ開始 matu.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown); function mouseDown(event:MouseEvent):void{ matu.startDrag(); } //ドラッグ終了 matu.addEventListener(MouseEvent.MOUSE_UP,mouseUp); function mouseUp(event:MouseEvent):void{ matu.stopDrag(); } /*////////////////////小さいベル/////////////////////*/ // ドラッグ開始 bellSmall.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown2); function mouseDown2(event:MouseEvent):void{ bellSmall.startDrag(); } // ドラッグ終了 bellSmall.addEventListener(MouseEvent.MOUSE_UP,mouseUp2); function mouseUp2(event:MouseEvent):void{ bellSmall.stopDrag(); }