Bootstrap Sortable面板内嵌地图:拖拽地图时如何阻止面板排序?
解决Bootstrap Sortable面板与内嵌拖拽地图的冲突问题
我之前也碰到过这种嵌套拖拽组件打架的情况,简直头疼!核心问题就是地图的拖拽事件冒泡到了外层的Sortable面板上,导致你拖地图的时候不小心把整个面板也拽走了。试试下面这两个方案,应该能完美解决你的问题:
方案一:限制Sortable的拖拽触发区域(推荐)
Bootstrap Sortable本身就支持通过handle选项指定只有特定元素才能触发面板排序,咱们把拖拽触发区域限制在面板的标题栏(就是你的.x_title元素),这样只有点击拖拽标题栏时才会触发面板排序,地图区域的操作就完全不会干扰了。
修改你的Sortable初始化代码,加上handle配置:
$("#widget-container").sortable({ containerSelector: "#widget-container", itemSelector: ".widget-holder", placeholder: "col-sm-3 widget-placeholder", // 新增:指定标题栏为唯一拖拽手柄 handle: ".x_title", start: function(e, ui) { ui.placeholder.height(ui.item.height); ui.placeholder.width(ui.item.width); }, stop: function (event, ui) { var data = $("#widget-container").sortable("toArray"); console.log(data); $.ajax({ type: 'POST', url: '/url.php', data: { data: data }, success: function(res) { } }); } }).disableSelection();
这个方案最直接,从根源上把面板的拖拽触发范围缩小到了标题栏,地图区域的拖拽事件根本不会触发Sortable的逻辑,完美隔离两个组件的拖拽行为。
方案二:阻止地图容器的事件冒泡
如果方案一因为某些场景不适用(比如你需要面板的其他区域也能拖拽),可以尝试在地图容器上阻止事件冒泡,让地图的拖拽事件不会传递到父级的Sortable面板。
给你的地图容器绑定mousedown和touchstart事件(兼顾移动端),只阻止事件冒泡即可:
// 阻止地图区域的鼠标/触摸事件冒泡到父元素 $("#map-container").on("mousedown touchstart", function(e) { e.stopPropagation(); // 注意:如果地图本身的拖拽需要默认行为,不要加e.preventDefault(),否则会影响地图拖拽功能 // e.preventDefault(); });
这里只需要调用stopPropagation(),不用随便禁用默认行为,这样既不影响地图自身的拖拽操作,又能避免触发面板的Sortable事件。
验证效果
改完之后测试一下:拖拽地图的时候,面板应该纹丝不动;拖拽面板的标题栏,就能正常排序面板了。两个组件的拖拽功能终于能和平共处啦!
内容的提问来源于stack exchange,提问作者René Beneš
相关产品推荐
相关产品推荐

