2012-01-26 9 views
7

通常このような質問/回答はしませんが、私はこの質問を20回以上聞いたので、実際に動作します。つまり、ドラッグ可能なjQueryアイテム内にスクロール可能なコンテンツ(overflow: auto;がある場合は、スクロールバーの親ドラッグ可能なコンテナをクリックしてドラッグすると解決します)ドラッグ可能なアイテムの内容をスクロールするときにjQueryのドラッグを無効にする

ここでは、この問題を提示する一部のHTMLの例です:

<div class="draggable" style="width:100px;height:100px;"> 
    <div id="content" style="width:80px;height:80px;overflow:auto;"> 
    Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit. 
    </div> 
</div> 

あなたがドラッグ可能にする要素を初期化する典型的な方法は、このようなものです:

$(".draggable").draggable() 

答えて

4

ソリューションをバインドすることです〜にスクロールイベントを初期化する要素、およびそれらの要素をスクロールします。次に、子のいずれかがscrollコマンドを呼び出すと、その要素のドラッグ可能な親をすべて見つけ、その要素にスクロールしたデータ要素を設定します。

jQuery UIの現在のバージョン(1.8.16)では、スクロールバーでマウスを動かすとstartイベントが発生し、ツリーをプロジェクトするので、このソリューションはテストではうまく機能します。あなたの閲覧/手を染めの快楽のために

$(".draggable").draggable({ 
    start: function() { 
     // if we're scrolling, don't start and cancel drag 
     if ($(this).data("scrolled")) { 
      $(this).data("scrolled", false).trigger("mouseup"); 
      return false; 
     } 
    } 
}).find("*").andSelf().scroll(function() {    
    // bind to the scroll event on current elements, and all children. 
    // we have to bind to all of them, because scroll doesn't propagate. 

    //set a scrolled data variable for any parents that are draggable, so they don't drag on scroll. 
    $(this).parents(".ui-draggable").data("scrolled", true); 

}); 

、私は同様の問題のjsfiddleを含めました。

+0

残念なことに、この回答は、実際にスクロールバーをクリックした結果としてスクロールが発生した場合にのみ機能します。スクロールせずにスクロールバーを押すと、jQuery UI/Draggableコードは引き続きドラッグを開始します。(Chrome 23 Betaで掲示されたjsfiddleでこれを試してみてください;スクロールせずにスクロールバーをクリックするだけです) – eleotlecram

+0

"*"(すべて)のスクロールイベントをリッスンし、そのスクロールがデータに当てはまることを追加する必要があります。もう1つの答えは自己完結型であり、後で読みやすくするためです。 – mgwidmann

6

[1]とPriorityMarkが提供するソリューションを組み合わせたソリューションを提案します。このソリューションはより確実に機能し、より効率的であると私は思っています。このため

$(".draggable").draggable({ 
    start: function(event) { 
     var content = $(this).children('.content'); 

     // if we're scrolling, don't start and cancel drag 
     if (event.originalEvent.pageX-content.offset().left > content.innerWidth()) 
     { 
      console.log('should-cancel'); 
      $(this).trigger("mouseup"); 
      return false; 
     } 
    } 
}); 

仕事に、I少しDOM(これはその大きな問題になることはありません)例調整:

<div class="draggable" style="width:100px;height:100px;overflow:auto;"> 
    <div class="content" style="width:80px;height:80px;"> 
    Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit. 
    </div> 
</div>​ 

がここドラッグ可能のdivがを持っていることに注意してくださいをオーバーフローで、のコンテンツではありません。 div。解決策はそれほど重要ではありませんが、ポイントを作ることは厳密には必要ではないので、余分なdivレベルを追加する必要はありません。

ここにはjsfiddleです。

[1] - listen for mouse events … except a div's overflow:scroll scrollbar?

+0

感謝した素晴らしい!あなたは揺れる! – msqar

+1

オハイオ州垂直スクロールのために働くが、水平にスクロールしようとすると、それは盗まれる!どうすればこの問題を解決できますか? :( – msqar

+1

この解決策はスクロール機能を有効にしますが、ドラッグ可能な項目を取り消し可能にします。 Mac OSXでFF21.0で試してみました – PowerAktar

1

私はこの問題を検索し、私のために完璧に動作し、私はそれを共有したい小さな解決策を見つけました。 私の解決策は、子/コンテンツの "mousedown"イベントの伝播を止めることです。 ないマウスダウンは何のドラッグを意味しません。)

$(".draggable").draggable(); 
$("#content").mousedown(function(event) { 
    event.stopPropagation(); 
}); 
0

これはかなりのソリューションですが、それは1つのバグがあります。 スクロールするように設定すると、要素を実際にドラッグするには2番目のドラッグが必要です。

関連する問題