我经历了几次代码,但我找不到基于触摸的设备失败的原因:
/**
* Initialize touch event listener.
*
* @returns {Plugin}
*/
touch: function () {
var self = this;
this._$body.bind('touchstart', function (event) {
var startEvent = event.originalEvent.touches[0];
event.preventDefault();
self._$body.bind('touchmove', function (event) {
var moveEvent = event.originalEvent.touches[0];
var diff = { x: startEvent.clientX - moveEvent.clientX, y: startEvent.clientY - moveEvent.clientY };
var nextStep;
event.preventDefault();
if ((diff.y <= -100 || diff.y >= 100) && Math.abs(diff.y) > Math.abs(diff.x)) {
nextStep = diff.y < 0 ? self._currentStep - 1 : self._currentStep + 1;
self.customScrollTo(nextStep);
}
return false;
});
return false;
});
return this;
},
demo(自签名ssl,别担心!):https://sandbox.idev.ge/roomshotel/html5_v3/
问题:触摸时,滚动会直接跳到底部。
预期结果:单触互动等于滚动1个部分。
有什么想法吗?
答案 0 :(得分:1)
首先,我建议您使用Modernizr来检测触摸
if (Modernizr.touch) {
$("body").swipe({
//Generic swipe handler for all directions
swipe: function (event, direction, distance, duration, fingerCount, fingerData) {
if(distance >= 100) //Check the units in px or unit
{
if (direction === "up") {
self.customScrollTo(nextStep);
} else if (direction === "down") {
self.customScrollTo(prevStep);
}
}
}
});
}
我只是把逻辑放在上面。 “自我”只是你的对象。
要使滑动事件起作用,您必须包含一个jquery插件https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
答案 1 :(得分:0)
我认为事件touchmove多次触发,尝试使用touchend。
关于:http://css-tricks.com/the-javascript-behind-touch-friendly-sliders/ 我已经使用谷歌浏览器实时javascript编辑测试了您的代码。 它在touchmove事件中使用了以下修改。
setTimeout(function(){ self.customScrollTo(nextStep); }, 250);
答案 2 :(得分:0)
我也认为每次触摸动作都会触发touchmove
事件的回调。通过从该函数返回false
,您只能取消单个触摸移动事件,而不是所有后续触摸移动事件。
您不能使用touchend
事件,因为您想在指针移动100px后立即调用self.customScrollTo(nextStep);
。
您希望在指针移动100px后阻止执行touchmove
回调,这可以通过多种方式完成,即。
var trackPointer = true;
之类的标志变量,检查此标志
每次触发touchmove
时,将此标志设置为false
指针已走过100px。startEvent
设置为null
并检查此变量
touchmove
。touchmove
事件
走了100px。注意:每次在此元素上触发 touchmove
时,touchstart
事件被绑定,这些事件不会相互覆盖但会堆叠!因此,您可能需要考虑仅将事件绑定一次(即,在DOM就绪时)或在不再需要时解除绑定事件。
后者可能是最简单的,也可以做到,即。 on touchend
(使用名称空间只是为了确保不解除绑定其他脚本绑定的相同事件):
// Unbind all touchmove.myNameSpace events on touchend.myNameSpace.
self._$body.bind('touchend.myNameSpace').function (event) {
self._$body.unbind('touchmove.myNameSpace');
});
当指针移动100px时:
self.customScrollTo(nextStep);
// Unbind all touchmove.myNameSpace events.
self._$body.unbind('touchmove.myNameSpace');
由于当指针位于元素之外时未触发'touchend'(我不确定touchmove
),您可能还想在绑定之前解除绑定:
event.preventDefault();
// Unbind all touchmove.myNameSpace events and (re)bind touchmove.myNameSpace event.
self._$body.unbind('touchmove.myNameSpace').bind('touchmove.myNameSpace', function (event) {
var moveEvent = event.originalEvent.touches[0];
所以你可以尝试(我没有测试过):
/**
* Initialize touch event listener.
*
* @returns {Plugin}
*/
touch: function () {
var self = this;
this._$body.bind('touchstart', function (event) {
var startEvent = event.originalEvent.touches[0];
event.preventDefault();
self._$body.unbind('touchmove.myNameSpace').bind('touchmove.myNameSpace', function (event) {
var moveEvent = event.originalEvent.touches[0];
var diff = { x: startEvent.clientX - moveEvent.clientX, y: startEvent.clientY - moveEvent.clientY };
var nextStep;
event.preventDefault(); // <- Not necessary since you completely cancel the event by returning false.
if ((diff.y <= -100 || diff.y >= 100) && Math.abs(diff.y) > Math.abs(diff.x)) {
nextStep = diff.y < 0 ? self._currentStep - 1 : self._currentStep + 1;
self.customScrollTo(nextStep);
// Unbind all touchmove.myNameSpace events.
self._$body.unbind('touchmove.myNameSpace');
}
return false;
});
return false;
});
// Unbind all touchmove.myNameSpace events on touchend.myNameSpace.
self._$body.bind('touchend.myNameSpace').function (event) {
self._$body.unbind('touchmove.myNameSpace');
});
return this;
},
PS:您可能希望使用像HammerJS(https://github.com/hammerjs/hammer.js)这样的库来使手势在浏览器和非触摸设备上工作。
答案 3 :(得分:0)
/**
* Initialize touch event listener.
*
* @returns {Plugin}
*/
touch: function () {
var self = this;
var flag = false;
this._$body.bind('touchstart', function (event) {
var startEvent = event.originalEvent.touches[0];
self._$body.bind('touchmove', function (event) {
var moveEvent = event.originalEvent.touches[0];
var diff = { x: startEvent.clientX - moveEvent.clientX, y: startEvent.clientY - moveEvent.clientY };
var nextStep;
if (((diff.y <= -100 || diff.y >= 100) && Math.abs(diff.y) > Math.abs(diff.x)) && flag == true) {
nextStep = diff.y < 0 ? self._currentStep - 1 : self._currentStep + 1;
self.customScrollTo(nextStep);
startEvent = event.originalEvent.touches[0]; // Just added this line here.
}
event.preventDefault();
return false;
});
return false;
});
return this;
},
我想有一个简单的编辑需要。 超过“diff”100或-100之后,只需更新“startEvent”变量的值即可。因此我添加了声明
startEvent = event.originalEvent.touches[0];
因此,当触发“self.customScrollTo(nextStep)”事件时,“startEvent”值为新值,即触摸点的当前位置。因此,再次调用touchmove事件。它将再次获得一组新的值来计算。 请检查此代码并告诉我这是否有效。即使它不对。