当前位置: 首页 > 知识库问答 >
问题:

javascript - draggable如何snap到新创建的元素上?

戚阳
2023-10-01

我使用jqui中的draggable小部件。

我希望当我的draggable元素拖拽到某个区域后,能产生一个新元素“#block”,并且这个新元素能够被draggable的"snap"所识别

我的代码如下:

$("#ball").draggable({    refreshPositions:true,    snap:"#block",    statr: function(event,ui) {        //创建#block元素的函数        createBlock()    }})

我发现#block元素能够正确被创建,并且没有任何拼写错误,但是"#ball"元素仍然无法识别#block元素,也无法吸附上去。我尝试使用refreshPoistion:true来更新draggable元素,但这没有效果。

我应该怎么解决这个问题,或者说,我能通过其他方法来完成我的需求吗?谢谢你的建议和回答!

共有2个答案

翟嘉祥
2023-10-01

遗憾的是,我最终也没能实现这个功能,我想,这可能与draggable元素的snap的判定有关,或许修改jquery-ui的源文件能解决这个问题,很可惜,我没有这样的能力。

我换用了另一种方式来实现这个功能,他看起来有着与snap一样的外表,或许能够一定程度上解决和我遭遇了同样问题的人:

这分为两部分,我将draggable元素命名为“#ball”,snap元素命名为“#block”
在#block上,我进行了这样的设置:

$("#block").droppable({    tolerance: "pointer",    accept:"#ball",    //球的圆心在鼠标的位置,所以我使用了pointer,当鼠标进入block时,球的圆心也进入了block    over:function(event,ui){        event.stopPropagation()        //通过修改snapping变量令ball的drag事件停止        snapping = true        //获取block的中心,这里的block是一个圆形        var radius = $(this).width()/2        var x = $(this).offset().left + radius        var y = $(this).offset().top + radius        //将ball的圆心移动到这里来        $(ui.draggable).offset({            left: x - ball的半径,            top: y - ball的半径        })    },    drop:function(event,ui){        console.log("球放进了篮子里")    },    //当鼠标移出block时    out:function(event,ui){        event.stopPropagation()        //令drag事件重启        snapping = false        //将ball移动到鼠标的位置来        $(ui.draggable).offset({            left: event.clientX,            top: event.clientY        })    }})

另一边,我同样对#ball的draggable进行了设置:

    $("#ball").draggable({    //我的block是一个在ball开始移动后才创建的对象,也正是因此snap无法起效,这里需要给ball设置refreshPositions:true,才能检测到新创建的block对象    refreshPositions:true,    //以snapping变量限制drag行动    drag: function(event,ui) {        if(snapping != false){            draggingBall(this)        }        else{            //在此时,ball的拖拽事件将不会发生            return 0;        }    },    stop: function(){        console.log("已经结束了!")    }})

需要提及的是,在我的程序中,ball的移动是借由helper产生,而非ball本身进行的移动,因此,这个代码可能不会在任何情况有效,但我希望它能够作为一种参考

狄赞
2023-10-01

看起来您正在尝试使用 jQuery UI 的 draggable 组件,并希望在拖动一个元素时,让其根据新创建的元素进行吸附。根据您提供的代码,您已经在 draggable 初始化函数中指定了 snap 参数为 "#block",但发现无法正常工作。

首先,snap 参数的工作原理是,它会在元素拖动时,根据设定的其他元素(这里应该是 "#block")进行吸附。所以问题可能出在 "#block" 元素的创建时间和位置上。

这里有几个需要注意的点:

  1. Snap 的元素需要存在:Snap 插件会在页面加载时获取所有指定的元素,因此新创建的元素可能无法立即被识别。您需要在页面加载后,当新元素已经存在时,再去初始化 draggable。
  2. RefreshPositions 参数:这个参数确实可以用来在拖动后更新 snap 元素的坐标,但是如果这些元素是在 draggable 初始化之后才添加到 DOM 中的,那么这个参数可能无法工作。
  3. Snap 的大小:如果新创建的元素 "#block" 太小,或者它不在 draggable 元素的视口范围内,那么 snap 功能可能无法正常工作。

为了解决这个问题,您可以尝试以下方案:

  1. 确保 Snap 元素在 draggable 初始化前已经存在:将新元素的创建逻辑放在 draggable 初始化之前,或者在 draggable 的 stop 事件中触发新元素的创建。
  2. 使用延迟初始化:如果您无法保证元素在 draggable 初始化时已经存在,那么可以尝试在 draggable 初始化后,等待一段时间再去创建新元素。
  3. 手动触发吸附:在创建新元素后,可以尝试手动触发 draggable 的吸附。这可以通过调用 $(".draggable").draggable("option","snap"); 来实现。

这是一个例子代码:

$("#ball").draggable({    refreshPositions: true,    start: function(event, ui) {        // Create #block element after the draggable is initialized        setTimeout(function() {            createBlock();        }, 100); // Delay the creation of #block element for 100ms after the draggable is initialized    },    snap: "#block"});

在这个例子中,我使用了 setTimeout 来延迟创建 "#block" 元素,确保 draggable 在开始拖动前已经存在。

这只是一个可能的解决方案,实际情况可能因为您的页面和代码而有所不同。如果这个建议不能解决您的问题,或者您有其他信息可以提供,我会很高兴再次为您提供帮助。

 类似资料:
  • 编辑2:在仔细阅读了jquery-ui的源代码,并充分理解了其原理后,我制作出了能够符合我的需求的代码:能够在旋转后的父元素中使用jquery-ui的draggable功能以实现拖动子元素的效果。我希望能分享给大家,或许有其他人有着和我类似的需求,可以提供给您作为参考。 需要写在最前面强调的是,这个功能有一定的局限性,例如旋转的父元素和拖拽的子元素必须都是position:absolute,并且一

  • 当然,我已经定义了这一点。等等: 我得到一个等待超时例外 我甚至用了很多类型的By,比如Xpath,css选择器,类...但是仍然没有运气. 解决方案:所以我需要返回到defaut上下文(返回到父上下文),我的代码是这样的: 多谢@naveen提醒我查那个案子:)。

  • 我正在尝试在php中创建以下元素,以创建我们的一个客户所需的xml。 每件事都很好,但我不知道如何创建以下元素 我已经尝试了几种方法,但仍然无法正确生成上述示例 有人能送我上路吗? 这是我的代码

  • 问题内容: 我有一个带有多个选项卡的选项卡页,一旦单击该选项卡,就会调用服务以返回一些数据。其中一些数据返回html表单,并且非常随机。我想收集输入的值,并通过服务将数据发送回服务器。我的问题是无法从正在动态创建的html中的输入元素中获取数据。 我创建了一个Plunker来显示问题所在。请注意,html值可以随时更改,因此对html进行硬编码将无法使用。在这里,代码来自plunker,但是请查看

  • 本文向大家介绍如何使用JavaScript和CSS创建可拖动的HTML元素?,包括了如何使用JavaScript和CSS创建可拖动的HTML元素?的使用技巧和注意事项,需要的朋友参考一下 要使用JavaScript和CSS创建可拖动的HTML元素,代码如下- 示例 输出结果 上面的代码将产生以下输出- 通过拖动来移动div时-

  • 我正在制作一个React应用程序,允许你制作一个列表并保存它,但React一直在警告我,我的元素没有唯一的关键道具(元素列表/列表表单)。如何为用户创建的元素创建唯一的关键道具?下面是我的代码 我的超文本标记语言: