【问题标题】:Use a child element to drag a parent element使用子元素拖动父元素
【发布时间】:2012-05-28 07:25:41
【问题描述】:

我想制作类似导航栏的东西,它可以移动整个元素,而不允许拖动父整个元素上的任何位置来控制拖动。例如:

<div class="undraggable">
    <div class="draggable"></div>
    content
</div>

拖动标题栏会拖动它所在的整个窗口,但拖动窗口容器上的其他位置不会拖动窗口。

我尝试使用dragresize,但我不能用他的代码只制作可拖动(不想调整大小)的对象。

【问题讨论】:

    标签: javascript draggable


    【解决方案1】:

    我一直在寻找类似的东西,但在 jquery ui 中,因为我已经在我的项目中使用它,所以如果你已经在使用 JQUERY UI,你可以识别你想要拖动的句柄。 这是一个工作示例:http://jsfiddle.net/VPMFs/

    <style>
    .undraggable{height:500px;width:500px;background:blue;}
    .draggable{height:100px;width:100px;background:white;}
    </style>
    <div class="undraggable">
    <div class="draggable">drag me!</div>
    </div>
    
    <script>
    $('.undraggable').draggable({handle: '.draggable'});
    </script>
    

    【讨论】:

      【解决方案2】:
      1. 在拖动控制器上注册 mousedown 处理程序(例如窗口的标题栏)。
      2. 拖动时,更新不同元素的位置(例如窗口包装)。

      我在这里有一个例子:
      http://phrogz.net/js/PhrogzWerkz/WerkWin.html

      如果您需要它与特定库(如 jQuery UI 库)一起使用,请编辑您的问题并说出来。

      更简单的演示:http://jsfiddle.net/VCQuN/1/

      <div class="window">
        <div class="titlebar">Hello, World!</div>
        <div class="content">
          <p>Window <b>Content!</b></p>
        </div>
      </div>​
      
      // For each item with a `window` class…
      var windows = document.querySelectorAll('.window');
      [].forEach.call(windows,function(win){
      
        // …find the title bar inside it and do something onmousedown
        var title = win.querySelector('.titlebar');
        title.addEventListener('mousedown',function(evt){
      
          // Record where the window started
          var real = window.getComputedStyle(win),
              winX = parseFloat(real.left),
              winY = parseFloat(real.top);
      
          // Record where the mouse started
          var mX = evt.clientX,
              mY = evt.clientY;
      
          // When moving anywhere on the page, drag the window
          // …until the mouse button comes up
          document.body.addEventListener('mousemove',drag,false);
          document.body.addEventListener('mouseup',function(){
            document.body.removeEventListener('mousemove',drag,false);
          },false);
      
          // Every time the mouse moves, we do the following 
          function drag(evt){
            // Add difference between where the mouse is now
            // versus where it was last to the original positions
            win.style.left = winX + evt.clientX-mX + 'px';
            win.style.top  = winY + evt.clientY-mY + 'px';
          };
        },false);
      });
      ​
      

      【讨论】:

      • 非常感谢您的示例非常完美,但对于像我这样的业余爱好者来说有点难以理解。
      • @hsgu 那么你不应该接受我的回答,直到你得到解决问题的答案。然而!请参阅我的编辑以获取更简单的示例。
      • 对不起,我是新手,很胆小。但现在我想我可以得到它了,非常感谢。
      • 非常感谢先生! removeEventListener onmouseup 否则你在每次 mousedown 时添加重复的 mouseup 事件侦听器我还结合了以下脚本来保存/恢复窗口位置jsfiddle.net/v685v9t6/862
      • 这不是拖放,而是使用自定义解决方案移动某些东西。拖放是在操作系统级别实现的,它允许不同软件之间的交互。
      【解决方案3】:

      在父元素中有一个属性 draggable="true",在所有子元素中有一个属性 draggable="false"。现在,如果您拖动任何子元素或父元素,您的拖动将正常工作。 如果您不在图像标签中添加 draggable="false",您的拖放功能将无法正常工作。

      <span className="dragelement cp"  draggable={true} 
      onDragStart={(event)=>drag(event)} onDragEnd={(event)=>dragEnd(event)} 
      id= {'drag'+el.type+index+idx}>
          <div>{m.a}</div>  
          {m.img && <img draggable={false} src={m.img} height="70px" width="100px" />  } 
      </span>
      

      【讨论】:

        【解决方案4】:

        使用 jQuery UI 可拖动功能:

        http://jqueryui.com/demos/draggable/

        您可以在此处构建 jQuery UI 的自定义下载以仅获取您需要的组件(可拖动及其依赖项):http://jqueryui.com/download

        它有很多配置选项 - 你的措辞有点模棱两可,但我认为你可能想要句柄选项:http://jqueryui.com/demos/draggable/#handle

        【讨论】: