我正在尝试创建一种插件或事件,以通过在ipad上滑动而使CSS转换(移动)元素。为此,到目前为止,我正在使用cocco的出色工作小代码段:
(function(D){
var M=Math,abs=M.abs,max=M.max,
ce,m,th=20,t,sx,sy,ex,ey,cx,cy,dx,dy,l,
f={
touchstart:function(e){
t=e.touches[0];
sx=t.pageX;
sy=t.pageY
},
touchmove:function(e){
m=1;
t=e.touches[0];
ex=t.pageX;
ey=t.pageY
},
touchend:function(e){
ce=D.createEvent("CustomEvent");
ce.initCustomEvent(m?(
max(dx=abs(cx=ex-sx),dy=abs(cy=ey-sy))>th?
dx>dy?cx<0?'swl':'swr':cy<0?'swu':'swd':'fc'
):'fc',true,true,e.target);
e.target.dispatchEvent(ce);
m=0
},
touchcancel:function(e){
m=0
}
}
for(l in f)D.addEventListener(l,f[l],false)
})(document);
对于过渡,我的网站上实现了rico st.cruz插件jquery-transit.js(当然还有jquery)
//用法(示例)
$("body").on( 'swu', function() {
fullscreenSwipeUp = true;
$("#Fullscreen").transition( { y: '-100%' }, 900, 'easeInSine' )
} );
到目前为止,一切都很好。
现在,我的想法是通过附加的触摸移动事件来指示可能的“向上滑动”,该事件会在手指轻按的同时移动元素。我成功添加了以下js:
// js部分以更凉爽的方式进行集成
var startY;
window.addEventListener( 'touchstart', function(e) {
e.preventDefault();
startY = e.targetTouches[0].pageY;
}, false );
window.addEventListener( 'touchmove', function(e) {
e.preventDefault();
// check if transition is going on and animations are ready
if ( !fullscreenSwipeUp ) { // find better solution f.e. to dispatch event on fullscreen transition?
var diffY = e.changedTouches[0].pageY - startY;
// fullscreen transition
if ( diffY <= 0 ) {
$("#Fullscreen").css( { y: diffY } );
} else {
// snap to clean starting value at bottom
$("#Fullscreen").css( { y: 0 } );
};
// do something else to indicate that swipe will be concluded when finger leaves
// min value based on variable th from custom swipe event
if ( diffY < -20 ) {
// indicate that swipe will be concluded
} else {
// indicate that swipe will not conclude
};
};
}, false );
// fullscreen fall back to bottom if swipe not concluded
window.addEventListener( 'touchend', function(e) {
e.preventDefault();
if ( !fullscreenSwipeUp ) {
// fall back to starting values / dequeue for smoother transition on second time
$("#Fullscreen").dequeue().transition( { y: 0 }, 150, 'easeInSine' );
};
}, false );
现在,我还看到在此代码中,基本自定义事件和我的东西中的两次触摸移动事件使各个部分相互重叠。如果有人可以给我一个如何整合这两个代码的想法,那就太了不起了。也许存在这样的东西?我找不到正确的东西。
感谢您的帮助!
PS我也尝试在这里制作小提琴:http://jsfiddle.net/Garavani/9zosg3bx/1/
但是可悲的是我太愚蠢,无法与所有外部脚本一起使用:-(
jquery-transit.js:
http://ricostacruz.com/jquery.transit/
编辑:
因此,我通过以下方式更改了代码。
我想我对原始的滑动事件(也包含触摸移动事件)和想要对该元素进行的操作感到困惑。
它可以工作,尽管可能仍然很混乱。
我必须设置一种标记来检查是否执行了滑动以暂时禁用触摸移动事件。有更好的方法吗?谢谢你的耐心!
var startY;
var swipeY = false; // for condition if condition for swipe is fullfilled
var swiped = false; // for check if swipe has been executed
window.addEventListener( 'touchstart', function(e) {
e.preventDefault();
startY = e.targetTouches[0].pageY;
}, false );
window.addEventListener( 'touchmove', function(e) {
e.preventDefault();
// check if swipe already executed
if ( !swiped ) { // find better solution f.e. to dispatch event when swiped?
var diffY = e.changedTouches[0].pageY - startY;
// check for final swipe condition
if ( diffY < -30 ) {
swipeY = true;
// do something with an element to indicate swipe will be executed
} else {
swipeY = false;
// do something with an element to indicate swipe will NOT be executed
};
};
}, false );
window.addEventListener( 'touchend', function(e) {
e.preventDefault();
if ( swipeY ) {
swiped = true;
// trigger the swipe action
} else {
// let the element fall back to original state
};
}, false );
编辑2:
var startY;
var swipeY = false;
var swiped = false;
var wh = $(window).height();
// fullscreen move on touchmove
function fm(e) {
e.preventDefault();
// check if transition is going on and animations are ready
if ( !swiped && ready ) { // !swiped is necessary, also / why?
var diffY = e.changedTouches[0].pageY - startY;
var scaleY = diffY/wh;
// calculate transition intermediate values
var osh = 0.91 - ( 0.09 * scaleY );
var ofsc = 0.86 - ( 0.14 * scaleY );
// fullscreen transition
if ( diffY <= 0 ) {
tfs(osh,[1,-scaleY],ofsc,diffY,0) // an extra module that does the animation with the calculated values
} else {
// snap to clean starting values at bottom
tfs(0.91,[1,0],0.86,0,0)
};
// rotate arrow to indicate surpassing minimum touch move leading to swipe
if ( diffY < -30 ) {
swipeY = true;
$arrowDown.addClass('rotation');
} else {
swipeY = false;
$arrowDown.removeClass('rotation');
};
};
};
// fullscreen swipe
function fs(e) {
e.preventDefault();
window.removeEventListener( 'touchmove', fm, false );
if ( !swiped ) { // this is necessary, also / why?
if ( swipeY ) {
$arrowbottomField.trigger('touchstart'); // trigger the full swipe (also available as element direct touch (on touch swiped is set to true in touchstart event handler, also)
window.removeEventListener( 'touchend', fs, false );
} else {
// fall back of animation to starting values
tfs(0.91,[1,0],0.86,0,0);
};
};
};
window.addEventListener( 'touchstart', function(e) {
e.preventDefault();
startY = e.targetTouches[0].pageY;
window.addEventListener( 'touchmove', fm, false );
}, false );
window.addEventListener( 'touchend', fs, false );
说明(尽我所能)
再次感谢Cocco的耐心配合。
同时,我再次修改了代码。
它的工作原理是:-)我知道您的眼中会一片混乱。
在我的网站上(应该也可以在ipad上工作,但不仅限于此),您可以触摸一个字段,并且全屏显示整个窗口(类似于www.chanel.com->“更多”)。
另外,(在iPad上)可以在整个身体上滑动以执行相同的操作。
阶段:
阶段1)用户点击并滑动(保持手指处于打开状态)全屏div跟随其手指。
暂停2)如果达到一定的滑动距离(仍在手指上),还会有一个小箭头指示:如果您现在离开,将执行滑动
暂停3)仍然用手指在距离上变得小于手指以完成滑动,箭头转回
阶段4)用手指离开已覆盖的距离,决定全屏将完全向上移动还是向下移动(如果距离不足)
对于小箭头,我可以按照您告诉我的方式使用类切换(比我做的要好!谢谢),但是对于动画的其余部分,不是因为值很大程度上取决于窗口大小。我整个站点的想法是,浏览器窗口可以具有任何大小或关系,所有内容都可以自适应(随时包含水平和垂直居中位置)
对于手机,一切都将彻底改变。
如果您想看一看,请访问:www.stefanseifert.com(如果要在ipad上查看效果,则必须触摸预告片div右下角的箭头来跳过简介)
我知道还有很多其他东西是最先进的编程技术(要非常谨慎地说:-),但是在某种程度上它是可行的。
而且我花了数周时间聘请一名程序员来重做所有事情。 ;-)
这是一种边干边学的方法(因为您可以猜到我一生中从未编程过;-)
因此,我非常感谢您提供的每一点信息,并帮助他们做得更好。
如果有人通过这里,我肯定会得到一些反对:-)
谢谢Cocco
圣诞节快乐!
最佳答案
该代码实际上是为低CPU设备,高性能..而在touchmove内部省去复杂计算的。无论如何(在touchstart和touchend之间)对元素进行动画处理,一个简单的解决方案是使用CSS(而不是jquery或其他占用大量资源的插件)。
然后逻辑地思考...您无法确定在touchstart上滑动的方向...您可以在做完一些数学运算后在touchend事件上做到这一点。或者,如上所述,touchmove会破坏整个代码。
选项1(简单且高性能)
演示
http://jsfiddle.net/z7s8k9r4/
添加一些行...。
(function(D){
var M=Math,abs=M.abs,max=M.max,
ce,m,th=20,t,sx,sy,ex,ey,cx,cy,dx,dy,l,
T, //<- THE TARGET
f={
touchstart:function(e){
t=e.touches[0];
sx=t.pageX;
sy=t.pageY;
T=e.target; T.classList.add('sw'); //<- ADD A CUSTOM CLASS FOR SWIPES
},
touchmove:function(e){
m=1;
t=e.touches[0];
ex=t.pageX;
ey=t.pageY
},
touchend:function(e){
ce=D.createEvent("CustomEvent");
ce.initCustomEvent(m?(
max(dx=abs(cx=ex-sx),dy=abs(cy=ey-sy))>th?
dx>dy?cx<0?'swl':'swr':cy<0?'swu':'swd':'fc'
):'fc',true,true,e.target);
e.target.dispatchEvent(ce);
m=0;
T.classList.remove('sw'); //<- REMOVE THE CLASS
},
touchcancel:function(e){
m=0
}
}
for(l in f)D.addEventListener(l,f[l],false)
})(document);
现在定义css类
element.sw{
background-color:yellow;
}
对元素上的移动设备使用适当的(HW)动画
element{
background-color:green;
-webkit-transition:background-color 200ms ease;
}
这是一个简单而肮脏的解决方案,它可以工作。保持简单。
该类仅适用于已定义的元素。 ;)
选项2
忘记上面的代码...
这是使用“弹跳”制作“快照”动画的另一种“性能”方式。
代码稍微复杂一点……并使用鼠标..用触摸事件替换鼠标事件。
http://jsfiddle.net/xgkbjwxb/
并带有更多数据点
http://jsfiddle.net/xgkbjwxb/1/
注意:请勿在移动设备中使用jquery或复杂的js插件。
额外
由于在没有触摸界面的PC上工作确实很成问题,因此我添加了一些行来强制鼠标根据我的功能要求模拟触摸。
http://jsfiddle.net/agmyjwb0/
编辑
该代码应该执行您想要的...
http://jsfiddle.net/xgkbjwxb/3/