Javascript 将指针事件重新触发到下层(用于使用interact.js进行不规则形状的拖动)
我需要手动构造/触发mousedown事件,就像自然的mousedown事件一样,任何相关的事件处理程序(在straight JS、jQuery或interact.JS中)都可以处理它。然而,这一事件似乎并没有像我预期的那样触发任何事情 我试图使用interact.js库制作一些形状不规则的图像。这些图像只是带有透明部分的矩形img元素。在每个元素上,我定义了2个interact.js事件侦听器:Javascript 将指针事件重新触发到下层(用于使用interact.js进行不规则形状的拖动),javascript,jquery,interact.js,Javascript,Jquery,Interact.js,我需要手动构造/触发mousedown事件,就像自然的mousedown事件一样,任何相关的事件处理程序(在straight JS、jQuery或interact.JS中)都可以处理它。然而,这一事件似乎并没有像我预期的那样触发任何事情 我试图使用interact.js库制作一些形状不规则的图像。这些图像只是带有透明部分的矩形img元素。在每个元素上,我定义了2个interact.js事件侦听器: 检查单击是否在图像区域内,如果不在,则禁用拖动(在“向下”事件时触发) 处理拖动(在“拖动”事件时
// code to re-assign "zIndex"s
function demote(element, interactible, event){
// block dragging on element
interactible.draggable(false);
// get all images lower than the target
var z = element.css("zIndex");
var images = $("img").filter(function() {
return Number($(this).css("zIndex")) < z;
});
// push the target to the back
element.css("zIndex",1);
// re-process all lower events
$(images).each( function () {
// move element up
$(this).css("zIndex",Number($(this).css("zIndex"))+1);
// re-fire event if element began below current target
elem = document.getElementById($(this).attr('id'));
// Create the event.
e = new MouseEvent("mousedown", {clientX: event.pageX, clientY: event.pageY});
var cancelled = !elem.dispatchEvent(e);
});
}
//重新分配“zIndex”的代码
功能降级(元素、可交互、事件){
//块在元素上拖动
可交互。可拖动(错误);
//获取低于目标的所有图像
var z=element.css(“zIndex”);
var images=$(“img”).filter(函数(){
返回编号($(this.css(“zIndex”))
不幸的是,这不起作用,因为mousedown事件没有向任何处理程序注册。为什么?
我在这里有所有(相关)代码:
请注意,这个JSFIDLE似乎不像在普通浏览器窗口中那样顺利工作,但我认为它展示了预期的功能
我尝试过的其他事情:
许多人提出了不同的方案来处理类似的问题(例如,将事件转发到较低的层,使用指针事件:none等),但似乎没有一个方案能够触发interact.js处理程序并在正确的元素上启动拖动交互。我也尝试过使用interaction.start(由interaction.js提供),但它似乎有问题——在这个主题上至少有一个开放的问题,当我尝试在我选择的目标上启动一个新的拖动交互时,我从库的代码中得到了很多错误
我并不反对重新访问这些解决方案本身,但我也想知道为什么手动触发mousedown事件不起作用。您是否尝试在更高级别上设置css属性
指针事件:none
(也可以通过javascript设置)?这个想法是监听父元素上的事件,并选择手动拖动目标。另外,我没有使用z-index来选择要拖动的图像,因为z-index不适用于position:static
。我并没有把优先权放在图像上,一切都取决于你
var-dragTarget;
函数dragMoveListener(事件){
var target=event.target,
//在data-x/data-y属性中保持拖动位置
x=(parseFloat(target.getAttribute('data-x'))| | 0)+event.dx,
y=(parseFloat(target.getAttribute('data-y'))| | 0)+event.dy;
//翻译元素
target.style.webkitTransform=
target.style.transform=
'翻译('+x+'px',+y+'px)';
//更新posiion属性
target.setAttribute('data-x',x);
target.setAttribute('data-y',y);
}
函数setDragTarget(事件){
//选择要拖动的图元
dragTarget=$(“#父项”).find('img'))
.过滤器(功能(i、el){
var clickCandicateCrect=el.getBoundingClientRect();
返回InsideBondingDirect(event.x、event.y、clickCandicateRect);
}).sort(按优先级).get(0);
}
函数inlineBondingDirect(x,y,rect){
返回(rect.left=y);
}
按优先级排序的函数(a,b){
返回$(b).data('priority')-$(a).data('priority');
}
功能启动(事件){
var交互=事件交互;
var目标=牵引目标;
如果(!interaction.interacting()){
interaction.start({name:'drag'},event.interactiable,target);
}
}
//按你的意愿优先考虑
$('#face1')。数据('优先级',2);
$('#face2')。数据('优先级',1);
交互(“#父项”)。可拖动({
//使用manualStart确定要拖动的元件
手动启动:正确,
onmove:dragMoveListener,
限制:{
限制:“家长”,
是的,
elementRect:{top:0,left:0,bottom:1,right:1}
},
})
.on('down',setDragTarget)
.on('move',startDrag);
您正在使用哪个浏览器?IE不支持构建Event
对象-您必须使用静态方法,如document.createEvent()
或其他什么。我在Chrome中工作。不过,我希望最大限度地提高兼容性,因此我将尝试重构以使用createEvent()。MDN表示createEvent()已被弃用,并且事件构造函数(您正在使用)是创建事件对象的首选方法。了解性能是否是一个关键方面对我很有帮助。我认为为了完成这项任务,你需要知道给定坐标下的给定像素是否可见。但是,此操作可能有点昂贵。性能不是太关键。我是
var dragTarget;
function dragMoveListener (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
function setDragTarget(event) {
//choose element to drag
dragTarget = $('#parent').find('img')
.filter(function(i, el) {
var clickCandicateRect = el.getBoundingClientRect();
return insideBoundingRect(event.x, event.y, clickCandicateRect);
}).sort(byPriority).get(0);
}
function insideBoundingRect(x, y, rect) {
return (rect.left <= x) && (rect.top <= y) && (rect.right >= x) && (rect.bottom >= y);
}
function byPriority (a, b) {
return $(b).data('priority') - $(a).data('priority');
}
function startDrag(event) {
var interaction = event.interaction;
var target = dragTarget;
if (!interaction.interacting()) {
interaction.start({ name: 'drag' }, event.interactable, target);
}
}
//Give priority as you wish
$('#face1').data('priority', 2);
$('#face2').data('priority', 1);
interact('#parent').draggable({
//use manualStart to determine which element to drag
manualStart: true,
onmove: dragMoveListener,
restrict: {
restriction: "parent",
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
})
.on('down', setDragTarget)
.on('move', startDrag);