모 바 일 웹 개발, click, touch, tap 사건 에 대한 분석
8336 단어 js
둘 다 클릭 할 때 터치 하지만 핸드폰 WEB 에서 click 이 있 습 니 다. 200 ~ 300 ms 이 므 로 클릭 이벤트 대신 tap 를 사용 하 십시오.
singleTap 과 doubleTap 은 각각 한 번 의 클릭 과 두 번 의 클릭 을 나타 낸다.
2. tap 에 대한 점 투과 처리
zepto 프레임 워 크 의 tap 를 사용 하여 모 바 일 브 라 우 저 내 클릭 이 벤트 를 사용 하여 click 이벤트 의 지연 응답 을 피 할 때 비 현재 층 의 클릭 이 벤트 를 촉발 할 수 있 습 니 다.
처리 방법:
(1)、
github 에 fastclick 라 는 라 이브 러 리 가 있 습 니 다. 모 바 일 장치 에서 click 이벤트 의 지연 응답 도 피 할 수 있 습 니 다.https://github.com/ftlabs/fastclick 이 를 script 태그 로 페이지 에 도입 할 수 있 습 니 다. (이 라 이브 러 리 는 AMD 를 지원 하기 때문에 AMD 규범 에 따라 require. js 와 같은 모듈 로 더 를 도입 할 수 있 습 니 다) 그리고 dom ready 시 body 에 초기 화 할 수 있 습 니 다. 예 를 들 어:
1
2
3
$(
function
(){
new
FastClick(document.body);
})
그리고 '지연 없 는 클릭' 이 필요 한 요소 에 click 이벤트 (zepto 에 연 결 된 tap 이벤트 가 아 닙 니 다) 를 연결 하면 됩 니 다.물론 body 에서 초기 화 하지 않 고 어떤 dom 에서 초기 화 할 수도 있 습 니 다. 그러면 이 dom 과 그 하위 요소 만 '지연 없 음' 클릭 을 누 릴 수 있 습 니 다.
실제 개발 에서 요소 가 fastclick 에 연결 되면 click 응답 속도 가 tap 보다 조금 빠 른 것 으로 나 타 났 습 니 다.하하.
(2) 요소 에 touch end 이 벤트 를 연결 하고 내부 에 e. preventDefault () 를 추가 합 니 다.
$demo.on(
'touchend'
,
function
(e){
// ,tap body , touchend , dom
$demo.hide()
e.preventDefault();
// “ ”
})
3. touch 사건 touch 는 터치 스크린 핸드폰 의 터치 사건 을 대상 으로 한다.
현재 대부분의 터치 스크린 핸드폰 webkit 커 널 이 제공 되 고 있 습 니 다.
터치 이벤트 의 감청 은 개발 자가 사용자 가 화면 을 만 질 때의 정 보 를 얻 을 수 있 도록 합 니 다.
터치 스타트, 터치 모 브, 터치 엔 드, 터치 캔 슬 등 네 가지 이벤트
touch start, touch move, touch end 사건 은 mousedown, mouseover, mouseup 의 트리거 와 유사 할 수 있 습 니 다.
touch start: 손가락 이 화면 에 닿 으 면 터치 합 니 다.
touch move: 손가락 이 화면 에서 이동 할 때 터치 합 니 다.
touch end: 손가락 이 화면 을 떠 날 때 터치 합 니 다.
한편, touch cancel 은 많은 사람들 이 언제 촉발 되 는 지 모 르 고 무시 합 니 다. 사실은 손가락 이 화면 을 떠 나 지 않 았 을 때 시스템 급 작업 이 발생 했 을 때 touch cancel 을 촉발 합 니 다. 예 를 들 어 alert 와 confirm 탄 상자 나 안 드 로 이 드 시스템 의 기능 탄 창 등 입 니 다.
예 를 들 면:
이 네 사건 의 촉발 순 서 는 다음 과 같다.
touchstart -> touchmove -> …… -> touchmove ->touchend
그러나 감청 위의 단일 사건 만 으로 는 터치 스크린 핸드폰 에서 흔히 볼 수 있 는 제스처 조작, 예 를 들 어 더 블 클릭, 길 게 누 르 기, 좌우 미끄럼, 확대 등 제스처 조작 을 완성 하 는 것 을 만족 시 킬 수 없다.이 사건 들 을 조합 해서 감청 해 야 합 니 다.
사실 시장 에 있 는 많은 프레임 워 크 들 이 핸드폰 브 라 우 저 를 대상 으로 이러한 제스처 를 밀봉 했다. 예 를 들 어 jqmobile, zepto, jqtouch 등 이다. 그러나 비극 이 발생 했다. 일부 안 드 로 이 드 시스템 (내 가 테스트 한 안 드 로 이 드 4.0. x) 에 대해 touch move 와 touch end 사건 은 잘 촉발 되 지 못 한다. 예 를 들 어 설명 한다.
예 를 들 어 손가락 이 화면 에서 위 에서 아래로 페이지 를 끌 때 이론 적 으로 하 나 를 촉발 할 수 있다. touch start, 여러 번 touchmove, 그리고 마지막. touch end, 그러나 안 드 로 이 드 4.0 에서 touch move 는 한 번 만 촉발 되 었 고 트리거 시간 과 touch start 의 차이 가 많 지 않 으 며 touch end 는 직접 촉발 되 지 않 았 습 니 다.이것 은 매우 심각 한 bug 입 니 다. google Issue 에서 이미 많은 사람들 이 제기 하 였 습 니 다. http://code.google.com/p/android/issues/detail?id=19827
잠시 안 드 로 이 드 4.0 에 이 bug 가 있 는 것 만 발 견 했 습 니 다. ios 3. x 버 전도 있다 고 합 니 다.
분명 한 것 은 jqmobile, zepto 등 이 이 bug 가 감청 실현 에 미 치 는 심각 한 영향 을 의식 하지 못 하기 때문에 이러한 프레임 워 크 를 직접 사용 하 는 이벤트 에 서 는 많 든 적 든 호환성 문제 가 발생 할 수 있 습 니 다!(개인 이 직접 쓴 경험)
그래서 저 는 zepto 의 이벤트 모듈 을 수정 하고 이벤트 트리거 파 라 메 터 를 추가 하여 가용성 을 강화 하 였 습 니 다.
(function($){
$.fn.touchEventBind = function(touch_options)
{
var touchSettings = $.extend({
tap Duration Threshold: 250, / 터치 스크린 이 이 시간 보다 크 면 tap 로 사용 하지 않 습 니 다.
scrollSupression Threshold: 10, / 터치 모 브 의 민감 도 를 촉발 합 니 다.
swipe Duration Threshold: 750, / / 이 시간 보다 크 면 swipe 로 생각 하지 않 습 니 다.
horizontal Distance Threshold: 30, / swipe 의 트리거 수직 방향 move 는 이 거리 보다 작 아야 합 니 다.
vertical Distance Threshold: 75, / swipe 의 트리거 수평 방향 move 는 이 거리 보다 커 야 합 니 다.
tap Hold Duration Threshold: 750, / swipe 의 트리거 수평 방향 move 는 이 거리 보다 커 야 합 니 다.
doubleTap Interval: 250 / / swipe 의 트리거 수평 방향 move 는 이 거리 보다 커 야 합 니 다.
}, touch_options || {})
var touch = {}, touchTimeout ,delta ,longTapTimeout;
function parentIfText(node){
return 'tagName' in node ? node : node.parentNode
}
function swipeDirection(x1, x2, y1, y2){
var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
}
function longTap()
{
longTapTimeout = null
touch.el.trigger('longTap');
touch.longTap = true;
touch = {};
}
function cancelLongTap()
{
if (longTapTimeout) clearTimeout(longTapTimeout)
longTapTimeout = null
}
this.data('touch_event_bind',"true");
this.bind('touchstart', function(e)
{
touchTimeout && clearTimeout(touchTimeout);
touch.el = $(parentIfText(e.touches[0].target));
now = Date.now();
delta = now - (touch.last_touch_time || now);
touch.x1 = e.touches[0].pageX;
touch.y1 = e.touches[0].pageY;
touch.touch_start_time = now;
touch.last_touch_time = now;
if (delta > 0 && delta <= touchSettings.doubleTapInterval) touch.isDoubleTap = true;
longTapTimeout = setTimeout(function(){
longTap();
},touchSettings.tapHoldDurationThreshold);
}).bind('touchmove',function(e)
{
cancelLongTap();
touch.x2 = e.touches[0].pageX;
touch.y2 = e.touches[0].pageY;
// prevent scrolling
if ( Math.abs( touch.x1 - touch.x2 ) > touchSettings.scrollSupressionThreshold )
{
e.preventDefault();
}
touch.touch_have_moved = true;
}).bind('touchend',function(e)
{
cancelLongTap();
now = Date.now();
touch_duration = now - (touch.touch_start_time || now);
if(touch.isDoubleTap)
{
touch.el.trigger('doubleTap');
touch = {};
}
else if(!touch.touch_have_moved && touch_duration < touchSettings.tapDurationThreshold)
{
touch.el.trigger('tap');
touchTimeout = setTimeout(function(){
touchTimeout = null;
touch.el.trigger('singleTap');
touch = {};
}, touchSettings.doubleTapInterval);
}
else if ( touch.x1 && touch.x2 )
{
if ( touch_duration < touchSettings.swipeDurationThreshold && Math.abs( touch.x1 - touch.x2 ) > touchSettings.verticalDistanceThreshold && Math.abs( touch.y1 - touch.y2 ) < touchSettings.horizontalDistanceThreshold )
{
touch.el.trigger('swipe').trigger( touch.x1 > touch.x2 ? "swipeLeft" : "swipeRight" );
touch = {};
}
}
}).bind('touchcancel',function(e){
touchTimeout && clearTimeout(touchTimeout);
cancelLongTap();
touch = {};
})
}
$.fn.touchbind = function(m,callback,touch_options)
{
if(this.data('touch_event_bind')!="true")
{
this.touchEventBind(touch_options);
}
this.bind(m,callback);
}
;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m)
{
$.fn[m] = function(touch_options,callback)
{
if(typeof(touch_options)=="object" && typeof(callback)=="function")
{
return this.touchbind(m, callback , touch_options)
}
else if(typeof(touch_options)=="function")
{
var callback = touch_options;
return this.touchbind(m, callback)
}
}
})
})(Zepto)
위의 코드 는 zepto 를 바탕 으로 원래 zepto 의 이 부분 을 교체 하면 됩 니 다. 그러나 독립 적 으로 써 도 됩 니 다. 저 는 zepto 의 bid 함수 로 사건 감청 을 했 을 뿐 실현 하 는 사고 도 분명 합 니 다.
호 환 되 는 해결 방법 은 touch move 에서 제스처 트 렌 드 가 설정 값 보다 크다 고 판단 할 때 (설정 값 보다 크 면 move 동작 트 렌 드 가 있 음 을 증명 함) 기본 동작 을 중단 하 는 것 입 니 다. e. preventDefault () 를 사용 하면 touch dn 이 정상적으로 작 동 할 수 있 습 니 다. 진심으로 google 의 이 bug 는 핸드폰 웹 상호작용 에 매우 영향 을 주 는 bug 라 고 생각 합 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[2022.04.19] 자바스크립트 this - 생성자 함수와 이벤트리스너에서의 this18일에 this에 대해 공부하면서 적었던 일반적인 함수나 객체에서의 this가 아닌 오늘은 이벤트리스너와 생성자 함수 안에서의 this를 살펴보기로 했다. new 키워드를 붙여 함수를 생성자로 사용할 때 this는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.