可拖曳的代码不能与hammer.js一起使用
我已经成功实现了jQueryUI可拖动,但只要添加hammer.js代码,可拖动代码就不再起作用。
它不是我包含hammer.js,但只要我使用脚本。
为什么是这样? 我怎样才能让他们都能工作?
.dataCard
和#main
都适用于可拖动和锤子
可拖动的代码在这里工作正常(用锤子实现注释掉):http://goo.gl/MO5Pde
以下是可拖动代码的示例:
$('#main').draggable({
axis:'y',
revert:true,
start: function(event, ui){
topValue = ui.position.top;
},
drag: function(event, ui){
if(pastBreakpoint === false){
$('#searchInput').blur();
if(topValue > ui.position.top) return false;
if(ui.position.top >= 161){
if(pastBreakpoint === false){
pastBreakpoint = true;
if($('.loadingRefresh').length === 0) $('#main').before('<div class="loadingRefresh"></div>');
else{
$('.loadingRefresh').remove();
$('#main').before('<div class="loadingRefresh"></div>');
}
$('.loadingRefresh').fadeIn();
$('#main').mouseup();
setTimeout(function(){
location.reload();
}, 1000);
}
}
}
}
});
下面是未注释的锤子代码和可拖动的代码不工作:http://goo.gl/994pxF
这是锤子代码:
var hammertime = Hammer(document.getElementById('main'), {
transform_always_block: true,
transform_min_scale: 0
});
var posX = 0,
posY = 0,
lastPosX = 0,
lastPosY = 0,
bufferX = 0,
bufferY = 0,
scale = 1,
last_scale = 1;
hammertime.on('touch transform transformend', function(ev) {
if ((" " + ev.target.className + " ").indexOf(" dataCard ") < 0) return;
else manageMultitouch(ev, ev.target); });
function manageMultitouch(ev, element) {
switch (ev.type) {
case 'touch':
last_scale = scale;
return;
case 'transform':
scale = Math.min(last_scale * ev.gesture.scale, 10);
break;
}
if(scale <= 0.5) $(element).hide('clip');
if(scale > 1.0) $(element).addClass('focused');
var transform = "translate(" + 0 + "px," + 0 + "px) " + "scale(" + 1 + "," + scale + ")";
var style = element.style;
style.transform = transform;
style.oTransform = transform;
style.msTransform = transform;
style.mozTransform = transform;
style.webkitTransform = transform;
}
我在我的应用程序中遇到了同样的问题,即使包含触摸打孔。 我不得不做一个很好的研究,以找到停止jQuery UI拖动的问题。 发生的问题是在事件中设置了preventDefault(仅当包含锤子时),才能从jquery ui更改触发器方法的结果。
那么,让我们回到一点:你应该看到的第一种方法是_mouseMove()
,它与mousemove事件相关联。 只有当条件(this._mouseStart(this._mouseDownEvent, event) !== false)
为真时才会触发拖动。
_mouseMove: function (event) {
// IE mouseup check - mouseup happened when mouse was out of window
if ($.ui.ie && (!document.documentMode || document.documentMode < 9) && !event.button) {
return this._mouseUp(event);
}
if (this._mouseStarted) {
this._mouseDrag(event);
return event.preventDefault();
}
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
this._mouseStarted =
(this._mouseStart(this._mouseDownEvent, event) !== false);
(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
}
return !this._mouseStarted;
}
下一个方法将创建helper(元素的克隆),在元素中设置一些css并返回true(我们期望的值),除非this._trigger("start", event)
返回false。
_mouseStart: function(event) {
var o = this.options;
//Create and append the visible helper
this.helper = this._createHelper(event);
this.helper.addClass("ui-draggable-dragging");
//Cache the helper size
this._cacheHelperProportions();
//If ddmanager is used for droppables, set the global draggable
if($.ui.ddmanager) {
$.ui.ddmanager.current = this;
}
/*
* - Position generation -
* This block generates everything position related - it's the core of draggables.
*/
//Cache the margins of the original element
this._cacheMargins();
//Store the helper's css position
this.cssPosition = this.helper.css( "position" );
this.scrollParent = this.helper.scrollParent();
this.offsetParent = this.helper.offsetParent();
this.offsetParentCssPosition = this.offsetParent.css( "position" );
//The element's absolute position on the page minus margins
this.offset = this.positionAbs = this.element.offset();
this.offset = {
top: this.offset.top - this.margins.top,
left: this.offset.left - this.margins.left
};
//Reset scroll cache
this.offset.scroll = false;
$.extend(this.offset, {
click: { //Where the click happened, relative to the element
left: event.pageX - this.offset.left,
top: event.pageY - this.offset.top
},
parent: this._getParentOffset(),
relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
});
//Generate the original position
this.originalPosition = this.position = this._generatePosition(event);
this.originalPageX = event.pageX;
this.originalPageY = event.pageY;
//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
//Set a containment if given in the options
this._setContainment();
//Trigger event + callbacks
if(this._trigger("start", event) === false) {
this._clear();
return false;
}
//Recache the helper size
this._cacheHelperProportions();
//Prepare the droppable offsets
if ($.ui.ddmanager && !o.dropBehaviour) {
$.ui.ddmanager.prepareOffsets(this, event);
}
this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
if ( $.ui.ddmanager ) {
$.ui.ddmanager.dragStart(this, event);
}
return true;
}
下面是第一个叫做触发器的_trigger,它来自拖拽控件。
_trigger: function (type, event, ui) {
ui = ui || this._uiHash();
$.ui.plugin.call(this, type, [event, ui]);
//The absolute position has to be recalculated after plugins
if(type === "drag") {
this.positionAbs = this._convertPositionTo("absolute");
}
return $.Widget.prototype._trigger.call(this, type, event, ui);
}
此时结果将调用另一个触发器方法(这次是从$ .Widget),这就是我们遇到问题的地方。
_trigger: function (type, event, data) {
var prop, orig,
callback = this.options[type];
data = data || {};
event = $.Event(event);
event.type = (type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type).toLowerCase();
// the original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[0];
// copy original event properties over to the new event
orig = event.originalEvent;
if (orig) {
for (prop in orig) {
if (!(prop in event)) {
event[prop] = orig[prop];
}
}
}
return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false || event.isDefaultPrevented());
}
return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false || event.isDefaultPrevented());
我们的问题正是在这条线上。 更具体的|| 在event.isDefaultPrevented()
之前。 当包含锤子时,方法event.isDefaultPrevented()
将生成true,一旦在返回之前该值被拒绝,最终值将为false。 (没有锤子包含event.isDefaultPrevented()
返回false,如预期的那样)。在我们的_moseMouve()
,不是调用_mouseDrag()
方法,而是调用_mouseUp()
。 你可以看到它会解除事件并调用_mouseStop()
。
_mouseUp: function (event) {
$(document)
.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
if (this._mouseStarted) {
this._mouseStarted = false;
if (event.target === this._mouseDownEvent.target) {
$.data(event.target, this.widgetName + ".preventClickEvent", true);
}
this._mouseStop(event);
}
return false;
}
如果用AND(&&)更改OR(||)运算符,它会正常工作。 当然,这不是一个小小的改变,我一直在测试它,直到现在我还没有发现任何问题。 该行将是这样的:
return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false && event.isDefaultPrevented());
正如我所说,它不是100%安全的,但直到现在我没有找到一个理由|| 代替 &&。 我会继续测试几天。 除此之外,我已经向jquery ui的首席开发人员发送了一封电子邮件,询问了这件事。
我使用它与同构smartclient类似的问题。
我通过处理启动事件并将isDefaultPrevented重置为false来修复它
$(element).draggable({
start: function (event, ui) {
event.isDefaultPrevented = function () { return false; }
}
});
我有同样的问题,并在github上发现这个问题。
所示的解决方案使用事件代表团为我工作得很好:
$(document).hammer().on('touch transform transformend', '#main', function() {...});
链接地址: http://www.djcxy.com/p/77295.html
上一篇: Draggable code not working with hammer.js
下一篇: Null pointer after capturing image using android camera in nexus 5