11

ドラッグ可能なヘッダー列を実装する必要があるテーブルがあります。Chromeをブラウザとして使用して実装しましたが、すべて正常に機能しました。Firefox(17.0.1)でテストしたところ、dragイベントが発生しないことに気づきました。dragstartしかし、そうします。以下のマークアップで問題を単純化しました。Chromeに読み込まれると、ドラッグ中にマウスが移動するたびにトップラベルが更新されます。Firefoxでは0のままです。

<!DOCTYPE html>
<html>
<head>
<title>TH Drag Test</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<style>
table,td,th {
    border: solid thin black;
}
</style>
<script>
    $(document).ready(function() {
        $("th").bind("drag", function(event) {
            $("#lbl").html(event.originalEvent.offsetX);
        });
    });
</script>
</head>
<body>
    <span id="lbl">0</span>
    <table>
        <thead>
            <tr>
                <th draggable="true">Column A</th>
                <th draggable="true">Column B</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>One</td>
                <td>Two</td>
            </tr>
            <tr>
                <td>Three</td>
                <td>Four</td>
            </tr>
        </tbody>
    </table>
</body>
</html>
4

3 に答える 3

6

Firefox のこの問題を修正する悪夢を見ました。div をダイアリーにドラッグし、ドロップの座標を検出して、ユーザーが選択した日時を知る必要がありました。

ドラッグ イベントを発生させるために、次の行を dragstart イベント ハンドラに追加しました。

event.dataTransfer.setData('Text', this.id);

ただし、Firefox の dragend イベント ハンドラーではこれらが返されないため、ドラッグが終了したときに x 座標と y 座標を取得する方法が最も困難でした。上記のようにマウスイベントを使用してみましたが、ドラッグの進行中はこれらが機能せず、dragend イベントハンドラーが呼び出された後にのみ呼び出されることがわかりました。そのため、ユーザーがいつ div を離したかを検出するために dragend イベントのみを使用し、次にマウス移動イベントを使用して座標を取得し、必要なその他の作業を行いました。これは IE、Firefox、および Chrome で動作することがわかりました。デモの html / javascript は次のとおりです。

 <div>
<div id = "todrag" class = "testdiv" draggable="true"><p>Please drag me</p></div>

<div id = "destination" class = "testdiv"><p>To here</p></div>
<p id = "coords"></p>
<p id = "compareords"></p>
</div>

<script>
    var down = true;
    var m_xcoordDrag = 0;
    var m_ycoordDrag = 0;
    var m_xcoordMove = 0;
    var m_ycoordMove = 0;
    var m_dragReleased = false;
    var m_coordselement = document.getElementById("coords");
    var m_compareordselement = document.getElementById("compareords");

    function OnMouseMove(e) {
        m_xcoordMove = e.x;
        m_ycoordMove = e.y;
        m_coordselement.innerHTML = e.x + "," + e.y;

        if (m_dragReleased) {
            m_compareordselement.innerHTML = "X:" + m_xcoordDrag + ", " + m_xcoordMove + " Y:" + m_ycoordDrag + ", " + m_ycoordMove;

            m_dragReleased = false;
        }
    }

    dragstart = function (event) {

        event.dataTransfer.setData('Text', this.id);
        stop = false;
    }

    dragend = function (event) {
        m_dragReleased = true;

        m_xcoordDrag = event.x;
        m_ycoordDrag = event.y;
    }

    document.onmousemove = OnMouseMove;

    var toDrag = document.getElementById("todrag");

    toDrag.addEventListener('dragstart', dragstart);
    toDrag.addEventListener('dragend', dragend);

</script>

これが役立つことを願っています!

于 2014-01-03T16:21:44.163 に答える
5

切り取ったビットhttp://pastebin.com/bD2g3SqL

編集:

これは機能しますが、offsetX および offsetY プロパティにアクセスする方法をまだ見つけていません。何らかの理由で、イベントの FF バージョンにはそれらが含まれていません。

<!DOCTYPE html>
<html>
<head>
<title>TH Drag Test</title>
<style>
table,td,th {
    border: solid thin black;
}
</style>
<script>
    function Init(){
        var n= document.getElementsByTagName("th");
        var j=0;

        for (var i=0; i<n.length; i++){
            n[i].addEventListener('drag', function (e){
                document.getElementById("lbl").textContent= j++;
            }, false);
        }

        for (var i=0; i<n.length; i++){
            n[i].addEventListener('dragstart', function (e){
                e.dataTransfer.setData('text/plain', 'node');
            }, false);
        }
    }
</script>
</head>
<body onload="Init();">
    <span id="lbl"></span>
    <table>
        <thead>
            <tr>
                <th draggable="true">Column A</th>
                <th draggable="true">Column B</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>One</td>
                <td>Two</td>
            </tr>
            <tr>
                <td>Three</td>
                <td>Four</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

どうやら、あなたがする必要があるのは、ドラッグを「初期化」することです( source .)

EDIT2:

どうやら、clientX および clientY プロパティ ( source )を更新しないドラッグ イベント (go figure) にバグがあるようです。それらは、dragover イベントなどの他のイベントで更新されますが、そのイベントは、オブジェクトが実行されている間のみ発生します。もっともらしいドロップターゲットにドラッグされました。このようなばかげた状況から抜け出す方法は、次のような大雑把なものです。

<!DOCTYPE html>
<html>
<head>
<title>TH Drag Test</title>
<style>
table,td,th {
    border: solid thin black;
}
</style>
<script>    
    var down= false;

    document.onmousemove= OnMouseMove;

    function Init(){
        var n= document.getElementsByTagName('th');

        for (var i=0; i<n.length; i++){
            n[i].onmousedown= OnMouseDown;
        }

        document.onmouseup= OnMouseUp;
    }

    function OnMouseDown(e){
        down= true;
    }

    function OnMouseUp(e){
        down= false;
    }

    function OnMouseMove(e){
        if (!down) return;

        document.getElementById('lbl').textContent= e.pageX ? ('x: ' + e.pageX + ' y: ' + e.pageY) : ('x: ' + (e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft) + ' y: ' + (e.clientY + document.documentElement.scrollTop + document.body.scrollTop));
    }

</script>
</head>
<body onload="Init();">
    <span id="lbl"></span>
    <table>
        <thead>
            <tr>
                <th draggable="true">Column A</th>
                <th draggable="true">Column B</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>One</td>
                <td>Two</td>
            </tr>
            <tr>
                <td>Three</td>
                <td>Four</td>
            </tr>
        </tbody>
    </table>
</body>
</html>
于 2012-12-17T20:05:26.523 に答える
1

dragstartFirefox では、発生する残りのドラッグ イベントを初期化するために、イベントに「何か」(ここでは「init」と呼びます) を設定する必要があります。

これはおそらく、すべての DOM 要素がdraggable="true"デフォルトで XUL にあるためです。(参考: https://bugzilla.mozilla.org/show_bug.cgi?id=646823#c4 )

例:

<div id="something" draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'node');">Drag me</div>

Chrome では、このような「初期化」は必要ありません。

于 2016-07-20T13:25:34.073 に答える