在Firefox中不会触发HTML拖动事件

时间:2012-12-17 18:57:08

标签: javascript css html5 firefox

我有一个表,我需要在其上实现可拖动的标题列。我使用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>

3 个答案:

答案 0 :(得分: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>

我希望这有帮助!

答案 1 :(得分: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:

显然,拖动事件(go figure)中存在一个错误,它不会更新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>

答案 2 :(得分:1)

Firefox需要&#39;某些东西&#39; (我们称之为&#39; init&#39; here)在dragstart事件中设置,以初始化要发生的其余拖动事件。

这可能是因为XUL中默认情况下所有DOM元素都是draggable="true"。 (参考: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不需要进行初始化&#39;。