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);

然而,最难解决的是如何在拖动结束时获取 x 和 y 坐标,因为这些不会在 Firefox 的 dragend 事件处理程序中返回。我尝试使用上面提到的鼠标事件,但我发现这些在拖动过程中不起作用,并且仅在调用 dragend 事件处理程序后才被调用。所以,我只使用了 dragend 事件来检测用户何时释放了 div,然后使用下一个鼠标移动事件来获取坐标并执行任何其他需要的工作。我发现这适用于 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。)

编辑2:

显然,拖动事件(如图)中有一个错误,它不会更新 clientX 和 clientY 属性(source。)它们会在其他一些事件上更新,例如 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

Firefox 需要在dragstartevent 中设置“something”(我们在这里称为“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 回答