使Bootstrap Twitter对话框模态框可拖动。

58

我试图使用这个jQuery插件使Bootstrap Twitter对话框模态可拖动:

http://threedubmedia.com/code/event/drag#demos

但是它不起作用。

var $div = $('html');
console.debug($('.drag'));
$('#modalTest')
    .drag("start", function(ev, dd) {
        dd.limit = $div.offset();
        dd.limit.bottom = dd.limit.top + $div.outerHeight() - $(this).outerHeight();
        dd.limit.right = dd.limit.left + $div.outerWidth() - $(this).outerWidth();
    })
    .drag(function(ev, dd) {
        $(this).css({
            top: Math.min(dd.limit.bottom, Math.max(dd.limit.top, dd.offsetY))
            , left: Math.min(dd.limit.right, Math.max(dd.limit.left, dd.offsetX))
        });
    }); 

你有任何想法如何完成它吗?


使用JQuery UI实现Twitter Bootstrap模态表单的拖放功能 - mccannf
2
以下回答都不是很好,因为Bootstrap与jQuery UI存在冲突 - Andrew Mao
@AndrewMao,请查看https://dev59.com/VGcs5IYBdhLWcg3ww2xP#24562349。 - Bryan Larsen
@AndrewMao 我的答案只使用了jQuery,没有插件。请参考:https://dev59.com/M2cs5IYBdhLWcg3wynDD#51824269 - Below the Radar
10个回答

101
$("#myModal").draggable({
    handle: ".modal-header"
}); 

这对我很有用,我从这里得到了它。如果你要感谢我,请将70%的感谢给Andres Ilich


12
你必须确保已经引入了jquery.ui,因为draggable功能就在那里。 :) - Mizbah Ahsan
2
这种实现拖动的方式虽然可行,但存在很多漏洞。 - Mangirdas Skripka
1
我遇到的一个错误体验是由于溢出所致。当我在模态框周围拖动时,滚动条会显示出来。我在模态框上将溢出设置为隐藏。 - Jeremy Ray Brown
2
@IdahoB的答案对我来说效果更好,没有奇怪的拖动伪影 https://dev59.com/M2cs5IYBdhLWcg3wynDD#39126290 - nwself
对于你:Th 对于安德烈斯:谢谢 - Stachu
显示剩余5条评论

60

如果您不想使用jQuery UI或任何第三方插件,可以使用以下代码。它只是普通的jQuery。

此答案适用于Bootstrap v3.x。有关版本4.x,请参见@User下面的评论

$(".modal").modal("show");

$(".modal-header").on("mousedown", function(mousedownEvt) {
    var $draggable = $(this);
    var x = mousedownEvt.pageX - $draggable.offset().left,
        y = mousedownEvt.pageY - $draggable.offset().top;
    $("body").on("mousemove.draggable", function(mousemoveEvt) {
        $draggable.closest(".modal-dialog").offset({
            "left": mousemoveEvt.pageX - x,
            "top": mousemoveEvt.pageY - y
        });
    });
    $("body").one("mouseup", function() {
        $("body").off("mousemove.draggable");
    });
    $draggable.closest(".modal").one("bs.modal.hide", function() {
        $("body").off("mousemove.draggable");
    });
});
.modal-header {
    cursor: move;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<div class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title">Modal title</h4>
      </div>
      <div class="modal-body">
        <p>One fine body&hellip;</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div>


9
最佳答案。解决方案不依赖于jQuery-ui。 - Marcus Frenkel
2
这个代码可以运行,但在Bootstrap 4中,当你开始拖动时,对话框会有点跳动。我将$draggable.closest(".modal-dialog").offset...这一行改为$draggable.closest(".modal-content").offset...,现在它可以正常工作了。 - User

34

排名第一的解决方案(由Mizbah Ahsan提供)并不完全正确...但很接近。如果您将draggable()应用于模态对话框元素,则在拖动模态对话框时,浏览器窗口滚动条将围绕屏幕滚动。修复方法是将draggable()应用于modal-dialog类而不是元素本身:

$(".modal-dialog").draggable({
    handle: ".modal-header"
});

谢谢!


你的解决方案完美地运作,是我找到的最佳方案。 - Woody
这是一个非常棒的解决方案,可以避免拖动滚动条。我一直在寻找这样的解决方案。 - bugovicsb

8

像其他人说的那样,最简单的解决方案就是在显示模态框后立即从 jQuery UI 中调用 draggable() 函数:

$('#my-modal').modal('show')
              .draggable({ handle: ".modal-header" });

但是Bootstrap和jQuery UI之间存在兼容性问题,因此我们需要在CSS中进行一些额外的修复:

.modal
{
    overflow: hidden;
}
.modal-dialog{
    margin-right: 0;
    margin-left: 0;
}
.modal-header{      /* not necessary but imo important for user */
    cursor: move;
}

2
这对拖动非常有效,但模态框会打开在屏幕的左边缘。 - Mike Devenney

6

5
我做了这个:
$("#myModal").modal({}).draggable();

它使我的标准/基本模态框可拖动。

不确定为什么它能起作用,但它确实能够实现。


你可以为单个jQuery选择器添加许多选项和事件。在可拖动后使用.hide(),它会隐藏。我认为您不需要模态框选项内的括号。 - Havihavi

3

针对鼠标光标(使用jQuery UI):

$('#my-modal').draggable({
    handle: ".modal-header"
});

对于触摸光标(使用jQuery):
var box = null;
var touchobj = null;
var position = {'x':0, 'y':0};
var positionbox = {'x':0, 'y':0};

// init touch
$('.modal-header').on('touchstart', function(e){
    box = $(this).closest('.modal-dialog');
    touchobj = e.changedTouches[0];

    // take position touch cursor
    position['x'] = touchobj.pageX;
    position['y'] = touchobj.pageY;

    //take original position box to move with touch
    positionbox['x'] = parseInt(box.css('left'));
    positionbox['y'] = parseInt(box.css('top'));

    e.preventDefault();
});

// on move touch
$('.modal-header').on('touchmove', function(e){
    var dist = {'x':0, 'y':0};
    touchobj = e.changedTouches[0];

    // we calculate the distance of move
    dist['x'] = parseInt(touchobj.clientX) - position['x'];
    dist['y'] = parseInt(touchobj.clientY) - position['y'];

    // we apply the movement distance on the box
    box.css('left', positionbox['x']+dist['x'] +"px");
    box.css('top', positionbox['y']+dist['y'] +"px");

    e.preventDefault();
});

这两种溶液的混合是兼容的。


2

在我的情况下,我必须设置backdrop并在应用draggable函数到模态对话框之前设置topleft属性。也许这会帮助某些人 ;)

if (!($('.modal.in').length)) {       
$('.modal-dialog').css({
     top: 0,
     left: 0
   });
}
$('#myModal').modal({
  backdrop: false,
   show: true
});

$('.modal-dialog').draggable({
  handle: ".modal-header"
});

0

您可以使用jQuery UI。只需将jQuery UI链接到您的项目中即可。需要一些CSS来删除Bootstrap在“modal-content”元素上提供的过渡效果。

<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css"/>
<style>
    .modal.fade.ui-draggable-dragging {
        -moz-transition: none;
        -o-transition: none;
        -webkit-transition: none;
        transition: none;
    }
</style>
<script>
    $('.modal-content').resizable({
        minHeight: 300,
        minWidth: 300
    });
    $('.modal-dialog').draggable();
</script>

0
在我的情况下,我启用了可拖动功能。它有效地工作。
var bootstrapDialog = new BootstrapDialog({
    title: 'Message',
    draggable: true,
    closable: false,
    size: BootstrapDialog.SIZE_WIDE,
    message: 'Hello World',
    buttons: [{
         label: 'close',
         action: function (dialogRef) {
             dialogRef.close();
         }
     }],
});
bootstrapDialog.open();

也许这会对你有所帮助。


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