【问题标题】:d3 send mouse event to divs child elementd3 将鼠标事件发送到 div 子元素
【发布时间】:2015-01-17 13:59:23
【问题描述】:

尝试拖放包含在 div 中的完整表单, 问题是保留默认行为 的子元素(这里是文本输入 允许例如通过鼠标选择文本)并限制 dragstart 到 div#dragme 边框部分。

这里有说明 https://github.com/mbostock/d3/wiki/Drag-Behavior#on 如何在拖动元素时保留一些不良行为, 但我想在这里相反的情况是可取的, 这意味着(类似于)将事件发送到 div 孩子,并让他们执行他们的默认行为。

这里是代码,请尝试用鼠标选择文本 (或通过双击选择整个文本),它不会工作:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    <html>
    <head>
    <style>
        div#dragme { 
                position:  absolute;
                overflow: hidden;
                left: 20;
                top: 20; 
                width: auto;
                background: silver; 
                border: 15px  solid rgba(0,0,0,0.5); 
                border-radius: 4px; padding: 8px;
        }
    </style>
    </head>
    <script src="d3.js"></script>

    <div id="container"  onclick="mouseclick(event)" > 
    </div>

    <script>
        elem = document.createElement("div");
        elem.id = 'content';
        elem.innerHTML = '<div draggable="true" id="dragme" class="resizeable"><input type="text" value="my text" />    </div>';
        document.body.insertBefore(elem,document.body.childNodes[0]);

        function move(){
            console.log("target: "+  d3.event.target);
            var dragTarget = d3.select(this);
            dragTarget
            .style("left", function(){return d3.event.dx + parseInt(dragTarget.style("left"))})
            .style("top", function(){return d3.event.dy + parseInt(dragTarget.style("top"))});
        }; 

        var node_drag = d3.behavior.drag()
                      .on("drag", move);
        var nodes =  d3.selectAll("#dragme");
        nodes.call(node_drag);
    </script>
    </body>
    </html>

【问题讨论】:

    标签: javascript events d3.js children preserve


    【解决方案1】:

    我最近通过在 textarea 上添加 mouseover/mouseout 处理程序来关闭和打开父 div 的拖动行为来解决类似的问题,例如:

            var e = elem.find('textarea');
            e.on('mouseover', function(){ elem.draggable('destroy') });
            e.on('mouseout', function(){ elem.draggable() });
    

    【讨论】:

    • 这个应该放在哪里?我把它放在 nodes.call(node_drag); 之后它并没有改变行为(输入仍然无法选择)我也尝试使用 find('input') 而不是 find('textarea')。
    【解决方案2】:

    你可以抑制对该元素的拖拽:

    function move() {
      // if dragging on an input
      if (d3.event.sourceEvent.target.nodeName === "INPUT")
        return false;
      var dragTarget = d3.select(this);
      dragTarget
        .style("left", function() {
          return d3.event.dx + parseInt(dragTarget.style("left"))
        })
        .style("top", function() {
          return d3.event.dy + parseInt(dragTarget.style("top"))
        });
    };
    

    编辑

    以上在 IE 中不起作用,所以...

    回到原来的移动功能:

    function move() {
      var dragTarget = d3.select(this);
      dragTarget
        .style("left", function() {
          return d3.event.dx + parseInt(dragTarget.style("left"))
        })
        .style("top", function() {
          return d3.event.dy + parseInt(dragTarget.style("top"))
        });
    };
    

    并抑制输入框上的移动事件:

    var node_drag = d3.behavior.drag()
      .on("drag", move);
    var nodes = d3.selectAll("#dragme");
    nodes.call(node_drag);
    
    d3.select("#dragme > input").on("mousedown", function(){
      d3.event.stopPropagation();
    });
    

    例如here

    【讨论】:

    • 示例中的文本仍然不可选择。
    • @Mike75,呃,该死的 IE,不过在 Chrome 中工作,让我再看看。
    • 还是很奇怪:当我复制行时: d3.select("#dragme > input").on("mousedown", function(){ d3.event.stopPropagation(); });进入我原来的移动程序它仍然没有效果!??我在 ubuntu 14 中使用 firefox。这个:d3.select("#dragme > input").on("mousedown", function(){ d3.event.stopPropagation(); alert("here I am"); }) ;显示消息但不显示文本选择。我不明白。
    • @Mike75,你把它复制到移动函数中了吗?它在nodes.call(node_drag) 之后属于它之外。
    猜你喜欢
    • 2013-07-25
    • 2020-07-17
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    相关资源
    最近更新 更多