如何在mousedown或dragstart上禁用悬停状态?

时间:2014-08-03 22:04:37

标签: javascript css hover drag

我有一个节点(div)列表,可以通过拖放重新排列。示例代码如下所示。通常情况下,我想用一个类突出显示悬停节点(为简单起见,让我们说蓝色背景,":hover"伪类),但是当拖动一个节点时我想突出显示不同的班级(红色,"拖动"班级)。

我有两个问题:

  1. dragstart()我申请"拖动"类到节点,但它没有立即生效。我可以通过直接修改style.backgroundColor来改变背景颜色,但我希望在添加一个类之后重新绘制一个节点是一个更简单的css解决方案。

  2. 一旦我改变了节点的顺序,悬停状态就会搞乱。正如您所看到的,如果您将节点从上到下拖动,则悬停状态跟随该节点(屏蔽"拖动"类),但如果您从下往上拖动悬停状态跳转到原始索引(索引)接收到mousedown的节点)现在"拖动"课程出现了。

  3. 我尝试过各种各样的东西,但无济于事。据我所知,没有办法删除或暂停:悬停伪类,我无法弄清楚是否有强制悬停在某个节点上的方法(我试过简单的事情)比如设置焦点以使节点处于活动状态。)

    第二个问题是真正的问题,但如果有人能评论如何解决这两个问题,我将不胜感激。提前谢谢。

    <html>
    
    <head>
    <style>
    .node {
        border: 1px solid gray;
        height: 26px;
        width:300px;"
    }
    .node:hover {
        background-color: #4444ff;
    }
    .dragged {
        background-color: #ff4444;
    }
    </style>
    </head>
    
    <body>
    <div id='cont' style="width: 300px;"></div>
    </body>
    
    <script>
    
    (function(){
        var html = '';
        for (var i = 1; i < 11; i++) {
            html += '<div id="' + i + '"draggable="true" ondragstart="dragstart(event)" ondragenter="dragenter(event)" ondragend="dragend(event)" class="node">item' + i + '</div>';
        }
        document.getElementById('cont').innerHTML = html;
    })();
    
    function dragstart(event) {
        event.target.className += ' dragged';
        event.dataTransfer.setData('text/html', event.target.id);
    }
    
    function dragenter(event) {
        var sourceId = event.dataTransfer.getData('text/html');
        var targetId = event.target.id;
    
        if (targetId === sourceId) {
            return true;
        }
    
        var sourceNode = document.getElementById(sourceId);
        var targetNode = document.getElementById(targetId);
        var sourceIndex = Array.prototype.indexOf.call(sourceNode.parentNode.childNodes, sourceNode);
        var targetIndex = Array.prototype.indexOf.call(targetNode.parentNode.childNodes, targetNode);
        if (targetIndex > sourceIndex) {
            targetNode.parentNode.insertBefore(targetNode, sourceNode);
        } else {
            targetNode.parentNode.insertBefore(sourceNode, targetNode);
        }
    }
    
    function dragend(event) {
        event.target.className = event.target.className.replace(' dragged', '');
    }
    
    </script>
    
    </html>
    

2 个答案:

答案 0 :(得分:1)

第一期:

在CSS中,在!important .dragged的末尾添加background-color

第二期:

显然,Chrome有odd behaviour event.dataTransfer.setData()

我刚刚通过setData('text/html'...替换setData('Text'...进行了测试 它实际上在我的Chrome(36 osx)中有效。

当然,您还必须将getData()参数更改为"Text"

从评论中编辑

由于Chrome对dataTransfer.setData()的限制,我无法为最后一段代码制作工作小提琴。 但它在独立页面中对我有用。

最简单的解决方案是使用一个存储元素的全局变量。

var draggedItem;
function dragstart(event) {
    event.target.className += ' dragged';
    draggedItem = event.target;   
}

function dragenter(event) {
    var sourceId = draggedItem.id;
    var targetId = event.target.id;
...

这是一个工作小提琴:http://jsfiddle.net/2Kgvh/

答案 1 :(得分:0)

这变成了一个css和跨浏览器的噩梦,所以我使用了jQuery及其Sortable Widget实现。