使用子元素拖动父元素

9
我想制作一个类似导航栏的东西,可以移动整个元素,但不允许在父元素上随意拖动以控制拖动。例如:
<div class="undraggable">
    <div class="draggable"></div>
    content
</div>

拖动标题栏会拖动其所在的整个窗口,但在窗口容器的其他位置拖动不会拖动窗口。
我尝试使用dragresize,但无法使用他的代码仅使对象可拖动(不想调整大小)。

请参阅此答案 https://dev59.com/aFoV5IYBdhLWcg3wa-Qo#71743513,该答案限制了父元素的可拖动部分。 - Ken
4个回答

8

我想找一个类似的东西,但使用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>

5
  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
@hsgu 那么在你得到解决问题的答案之前,你不应该接受我的答案。然而!请看我编辑的更简单的例子。 - Phrogz
抱歉,我是个新手,有些缺乏自信。但现在我觉得我可以理解了,非常感谢。 - hsgu
非常感谢你先生! 在mouseup事件上使用removeEventListener,否则您会在每个mousedown事件上添加重复的mouseup事件侦听器。 我还结合了以下脚本来保存/恢复窗口位置 http://jsfiddle.net/v685v9t6/862/ - BIOHAZARD
这不是拖放,而是使用自定义解决方案移动某些东西。 拖放是在操作系统级别实现的,它允许不同软件之间的交互。 - Christophe Quintard
@ChristopheQuintard 这是真的,但我想知道你为什么提到这个。OP没有问拖放,问题也没有标记为拖放,而我的答案也没有提到它。此外,拖放不必在操作系统级别实现。许多JavaScript库都存在于此(我自己编写了一些)。 - Phrogz

2
在父元素中添加属性draggable="true",在所有子元素中添加属性draggable="false"。现在,如果您拖动任何子元素或父元素,则您的拖动将正常工作。 如果您不在图像标签中添加draggable="false",则您的拖放功能将无法正常工作。 Drag and drop with nested elements
<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>

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接