2012-05-25 13 views
11

私のウェブアプリケーションでは、ドラッグアンドドロップ機能をいくつか実装しようとしています。私は、基本的なことを行うグローバルJavaScriptコンポーネントを持っています。このオブジェクトは、現在のドラッグ操作(移動、コピー、リンク)に応じて、マウスカーソルの変更も行います。私のWebページには、インラインでもCSSファイルでも、独自のカーソルスタイルを定義するさまざまなHTML要素があります。JavaScriptを使用したマウスカーソルのグローバルオーバーライド

私の中心的なドラッグ&ドロップコンポーネントは、マウスカーソルが上にある要素のスタイルから独立して、マウスカーソルをグローバルに変更する方法はありますか?

私が試した:

document.body.style.cursor = "move" 

document.body.style.cursor = "move !important" 

をしかし、それは動作しません。カーソルスタイルを定義する要素の上をドラッグするたびに、カーソルがそのスタイルに変更されます。

確かに、私は現在ドラッグしている要素のスタイルを変更することができましたが、要素が重いときにリセットする必要があります。これは少し複雑に思えます。私はグローバルなソリューションを探しています。

答えて

10

あなたのCSSを大虐殺しないでください! element.setCapture()

操作ドラッグを実装し、削除するには、非常に重要なAPIを使用する必要があります。かかわらず、彼らはのターゲット要素のカーソルになります

  • カーソル(でも、ブラウザウィンドウの外に)発生した場所の、
    • すべてのマウスイベント

      は、キャプチャのターゲット要素にリダイレクトされます。これは、この結果をもたらしますマウスポインタがどこにあるかにかかわらず、キャプチャ。

    あなたはelement.releaseCapture()をコールする必要がありまたはdocument.releaseCapture()操作の終わりに、通常モードに切り替えます。あなたは(とりわけ)例えばのように、痛みを伴う問題の多くを持つことができ:

    は、ドラッグ&ドロップのナイーブimplemnntationに注意マウスは、ブラウザのウィンドウの外にrealeasedされた場合に何が起こるか、またはオーバー伝播を停止するハンドラを持つ要素。 setCapture()を使用すると、このすべての問題とカーソルスタイルも解決されます。

    自分でドラッグアンドドロップを実装する場合は、これを詳しく説明しているthis excellent tutorialを読むことができます。

    可能であれば、ご自分の文脈でjQuery UI draggableを使用することもできます。ドラッグ&ドロップの期間全体のページの上に透明のdivを開く -

  • +4

    setCaptureはIEとFF/Mozで動作しますが、Chromeはこの素晴らしい機能をサポートしていません:( – eselk

    +0

    setCaptureは今日のFirefox(Internet Explorer 11ではなく)でのみ動作しますが、それが存在するときに使用できます – ygoe

    4
    document.body.style.cursor = "move" 
    

    はうまくいきます。

    しかし、私はCSSを使ってグローバルスタイリングをすることをお勧めします。

    は、次の定義:

    body{ 
        cursor:move; 
    } 
    

    問題は、他の要素で定義されたカーソルが、ボディスタイルをオーバーライドすること、です。

    次のようないろいろ書い行うことができます:*は通常悪いセレクタと考えていること、しかし

    body *{ 
        cursor:inherit; 
    } 
    

    注:

    your-element.style.cursor = "inherit"; // (or "default") 
    

    体からまたはCSSで継承されたスタイルにそれをリセットすることを-選択。

    2

    あなたは、CSSの宣言を行う場合は、次の

    * {cursor:move;}

    をそれが動作するはずです。

    3

    残念ながらelement.setCapture()は、私はブルートフォースアプローチを使用してIE

    では動作しません。

    .tbFiller { 
        position:absolute; 
        z-index:5000; 
        left:0; 
        top:0; 
        width:100%; 
        height:100%; 
        background-color:transparent; 
        cursor:move; 
    } 
    
    ... 
    
    function dragStart(event) { 
        // other code... 
        document.tbFiller=document.createElement("div"); 
        document.tbFiller.className="tbFiller" 
    } 
    
    function dragStop(event) { 
        // other code... 
        document.tbFiller.parentNode.removeChild(document.tbFiller); 
    } 
    
    +1

    setCapture works IEでは、Chromeはそれと同じものはないとは思わない – eselk

    +0

    setCaptureはIE 11では動作しません.FirefoxはMicrosoft APIだと言いますが、再度落としたかもしれませんが、オーバーレイdiv、CSSルール、クラスを設定するだけで十分です。 – ygoe

    0

    これは私が何をすべきかであり、それはあなたのページにこのCSSルールを追加2017年

    のようFirefoxの、クロム、エッジとIEで動作します:

    html.reset-all-cursors * 
    { 
        cursor: inherit !important; 
    } 
    

    とき<html>要素"reset-all-cursors"クラスを持っていれば、実際に要素自体を操作することなく、要素の個別に設定されたすべてのカーソルをstyle属性でオーバーライドします。場所を一掃する必要はありません。

    次に、ページ全体のカーソルを任意のelementの値で上書きする場合は、e。 g。ドラッグされている要素は、JavaScriptで次の操作を行います。

    element.setCapture && element.setCapture(); 
    $("html").addClass("reset-all-cursors"); 
    document.documentElement.style.setProperty("cursor", $(element).css("cursor"), "important"); 
    

    それが利用可能であるsetCapture機能を使用しています。これは現時点ではFirefoxにすぎませんが、Microsoft APIだと言われています。その後、特殊クラスがドキュメント全体に追加され、すべてのカスタムカーソルが無効になります。最後に、ドキュメント上のカーソルをどこにでも表示するように設定します。

    キャプチャイベントと組み合わせて、ドラッグカーソルをページおよびブラウザウィンドウの外側に拡張することさえできます。 setCaptureはこれをFirefoxで確実に行います。しかし、ブラウザ、UIのレイアウト、およびマウスカーソルがウィンドウを離れる経路に依存して、毎回動作しません。 ;-)

    完了したら、クリーンアップ:

    element.releaseCapture && element.releaseCapture(); 
    $("html").removeClass("reset-all-cursors"); 
    document.documentElement.style.setProperty("cursor", ""); 
    

    これはaddClassremoveClassのためのjQueryを含んでいます。単純なシナリオでは、classの属性をdocument.documentElementと単純に比較して設定できます。これは、Modernizrのような他のライブラリを破るでしょう。要素の希望のカーソルが既にわかっている場合はcss関数を取り除くか、element.style.cursorのようなものを試してみてください。

    関連する問題