브라우저에 마우스가없고 터치 전용임을 감지
터치 (손가락을 클릭하면 화면이 숨겨 짐)와 마우스 (호버 미리보기에 크게 의존 함)와 매우 다른 인터페이스로 웹 응용 프로그램 (흥미로운 텍스트 페이지가있는 웹 사이트가 아님)을 개발 중입니다. 사용자에게 올바른 인터페이스를 제공 할 마우스가 없는지 어떻게 알 수 있습니까? 마우스와 터치가있는 사람 (예 : 일부 노트북)을위한 스위치를 남겨 둘 계획입니다.
브라우저의 터치 이벤트 기능이 실제로 사용자가 터치 장치를 사용하고 있다는 것을 의미하지는 않습니다 (예 : Modernizr가 자르지 않음). 장치에 마우스가 있으면 질문에 올바르게 대답하는 코드는 false를, 그렇지 않으면 true를 반환해야합니다. 마우스와 터치가있는 장치의 경우 false를 반환해야합니다 (터치 만이 아님)
참고로, 터치 인터페이스는 키보드 전용 장치에도 적합 할 수 있으므로 감지하려는 마우스가 더 적습니다.
요구를보다 명확하게하기 위해 구현하려는 API는 다음과 같습니다.
// Level 1
// The current answers provide a way to do that.
hasTouch();
// Returns true if a mouse is expected.
// Note: as explained by the OP, this is not !hasTouch()
// I don't think we have this in the answers already, that why I offer a bounty
hasMouse();
// Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking)
// callback is called when the result of "hasTouch()" changes.
listenHasTouchChanges(callback);
// callback is called when the result of "hasMouse()" changes.
listenHasMouseChanges(callback);
가장 큰 문제는 다음과 같은 다른 종류의 장치 / 사용 사례가 있다는 것입니다.
- 마우스 및 키보드 (데스크톱)
- 터치 만 (전화 / 태블릿)
- 마우스, 키보드 및 터치 (터치 랩톱)
- 터치 및 키보드 (태블릿의 블루투스 키보드)
- 마우스 만 (사용 불가능한 사용자 / 브라우징 환경 설정)
- 키보드 만 (사용하지 않는 사용자 / 브라우징 환경 설정)
- 터치 및 마우스 (예 : Galaxy Note 2 펜의 호버 이벤트)
더 나쁜 것은,이 클래스 중 일부에서 다른 클래스로 전환 할 수 있거나 (마우스에 연결하고 키보드에 연결) 사용자가 화면에 닿아 화면을 터치 할 때까지 일반 랩톱에있는 것처럼 보일 수 있습니다.
브라우저에 이벤트 생성자가 존재하는 것이 앞으로 나아갈 수있는 좋은 방법이 아니며 다소 일관성이 없다고 가정하면 정확합니다. 또한 매우 구체적인 이벤트를 추적하거나 위의 몇 가지 클래스 만 배제하지 않는 한 이벤트 자체를 사용하는 것이 완벽한 증거는 아닙니다.
예를 들어, 사용자가 실제 마우스 이동 (터치 이벤트에서 잘못된 마우스 이동이 아님을 발견 한 경우 http://www.html5rocks.com/en/mobile/touchandmouse/ 참조 )을 발견했다고 가정하십시오 .
그리고 뭐?
호버 스타일을 사용 하시겠습니까? 버튼을 더 추가 하시겠습니까?
어느 쪽이든 이벤트가 발생할 때까지 기다려야하므로 유리 컵 시간이 늘어나고 있습니다.
그러나 고귀한 사용자가 마우스를 뽑고 풀 터치하고 싶을 때 어떤 일이 벌어 지나요? 현재 밀려 난 인터페이스를 만질 때까지 기다렸다가 지금 붐비는 UI를 찾기 위해 노력한 후 바로 변경 하시겠습니까?
글 머리 기호 형식으로 https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101 에서 stucox를 인용 하십시오.
- 마우스의 존재를 감지하고 싶다
- 이벤트가 시작되기 전에 Ae가 감지하지 못할 수 있음
- 따라서 우리가 감지하는 것은이 세션에서 마우스가 사용 된 경우입니다. 즉, 페이지로드에서 즉시 발생하지는 않습니다.
- 또한 마우스가 없다는 것을 감지하지 못할 수도 있습니다. 사실이 될 때까지 정의되지 않을 것입니다 (검증 될 때까지 거짓으로 설정하는 것보다 더 의미가 있다고 생각합니다)
- 그리고 아마도 세션 중 마우스 연결이 끊어 졌는지 감지 할 수 없습니다. 사용자가 마우스를 포기하는 것과 구분할 수 없을 것입니다
따로 : 브라우저는 사용자가 마우스를 연결하거나 키보드에 연결할 때 알고 있지만 JavaScript에 노출하지 않습니다 .. dang!
이것은 다음으로 이어질 것입니다 :
특정 사용자의 현재 기능을 추적하는 것은 복잡하고 신뢰할 수 없으며 모호한 장점이 있습니다.
그러나 점진적 향상이라는 아이디어는 여기서도 잘 적용됩니다. 사용자의 상황에 관계없이 원활하게 작동하는 경험을 구축하십시오. 그런 다음 브라우저 기능 / 미디어 쿼리를 기반으로 가정하여 가정 된 상황에서 상대적으로 기능을 추가합니다. 마우스의 존재는 다른 장치의 다른 사용자가 웹 사이트를 경험하는 다양한 방법 중 하나 일뿐입니다. 커널에 장점이있는 무언가를 만들고 사람들이 버튼을 클릭하는 방식에 대해 너무 걱정하지 마십시오.
문서에서 mousemove 이벤트를 수신하는 것은 어떻습니까. 그런 다음 해당 이벤트가 들릴 때까지 장치가 터치 또는 키보드 전용이라고 가정합니다.
var mouseDetected = false;
function onMouseMove(e) {
unlisten('mousemove', onMouseMove, false);
mouseDetected = true;
// initializeMouseBehavior();
}
listen('mousemove', onMouseMove, false);
(여기서 listen및 unlisten대리자 addEventListener또는 attachEvent적절한.)
희망적으로 이것은 너무 많은 시각적 인 잔물결로 이어지지 않을 것입니다. 모드에 따라 대규모 재 레이아웃이 필요하다면 짜증날 것입니다 ...
@Wyatt의 대답은 훌륭하고 우리가 생각할 많은 것을 제공합니다.
제 경우에는 첫 번째 상호 작용을 듣고 행동을 설정하기로 결정했습니다. 따라서 사용자에게 마우스가 있어도 첫 번째 상호 작용이 터치 인 경우 터치 장치로 취급합니다.
이벤트가 처리되는 지정된 순서를 고려하십시오 .
- 터치 스타트
- 터치
- 터치
- 마우스 오버
- mousemove
- 마우스 다운
- 마우스
- 딸깍 하는 소리
마우스 이벤트가 터치 전에 트리거되면 에뮬레이트 된 이벤트가 아니라 실제 마우스 이벤트라고 가정 할 수 있습니다. 예 (jQuery 사용) :
$(document).ready(function() {
var $body = $('body');
var detectMouse = function(e){
if (e.type === 'mousedown') {
alert('Mouse interaction!');
}
else if (e.type === 'touchstart') {
alert('Touch interaction!');
}
// remove event bindings, so it only runs once
$body.off('mousedown touchstart', detectMouse);
}
// attach both events to body
$body.on('mousedown touchstart', detectMouse);
});
그것은 나를 위해 일했다
2018 년 현재 브라우저에 마우스 (또는 유사한 입력 장치)가 있는지 감지하는 좋고 신뢰할 수있는 방법이 있습니다 : CSS4 미디어 상호 작용 기능 은 현재 거의 모든 최신 브라우저 (IE 11 및 특수 모바일 브라우저 제외)에서 지원됩니다.
W3C :
포인터 미디어 기능은 마우스와 같은 포인팅 장치의 존재와 정확성을 쿼리하는 데 사용됩니다.
다음 옵션을 참조하십시오.
/* The primary input mechanism of the device includes a
pointing device of limited accuracy. */
@media (pointer: coarse) { ... }
/* The primary input mechanism of the device
includes an accurate pointing device. */
@media (pointer: fine) { ... }
/* The primary input mechanism of the
device does not include a pointing device. */
@media (pointer: none) { ... }
/* Primary input mechanism system can
hover over elements with ease */
@media (hover: hover) { ... }
/* Primary input mechanism cannot hover
at all or cannot conveniently hover
(e.g., many mobile devices emulate hovering
when the user performs an inconvenient long tap),
or there is no primary pointing input mechanism */
@media (hover: none) { ... }
/* One or more available input mechanism(s)
can hover over elements with ease */
@media (any-hover: hover) { ... }
/* One or more available input mechanism(s) cannot
hover (or there are no pointing input mechanisms) */
@media (any-hover: none) { ... }
미디어 쿼리는 JS에서도 사용할 수 있습니다.
if(window.matchMedia("(any-hover: none)").matches) {
// do sth
}
관련 :
공식 작업 초안 : https://drafts.csswg.org/mediaqueries/#mf-interaction
브라우저 지원 : https://caniuse.com/#search=media%20features
비슷한 문제 : 클라이언트 장치가 : hover 및 : focus 상태를 지원하는지 감지
브라우저가 터치 가능한지 여부 만 감지 할 수 있습니다. 실제로 터치 스크린이나 마우스가 연결되어 있는지 알 수있는 방법이 없습니다.
터치 기능이 감지되면 마우스 이벤트 대신 터치 이벤트를 수신하여 사용의 우선 순위를 지정할 수 있습니다.
터치 기능 크로스 브라우저를 감지하려면
function hasTouch() {
return (('ontouchstart' in window) || // html5 browsers
(navigator.maxTouchPoints > 0) || // future IE
(navigator.msMaxTouchPoints > 0)); // current IE10
}
그런 다음 이것을 사용하여 확인할 수 있습니다.
if (!hasTouch()) alert('Sorry, need touch!);
또는들을 이벤트를 선택하십시오.
var eventName = hasTouch() ? 'touchend' : 'click';
someElement.addEventListener(eventName , handlerFunction, false);
또는 터치 대 비 터치에 대해 별도의 접근 방식을 사용하십시오.
if (hasTouch() === true) {
someElement.addEventListener('touchend' , touchHandler, false);
} else {
someElement.addEventListener('click' , mouseHandler, false);
}
function touchHandler(e) {
/// stop event somehow
e.stopPropagation();
e.preventDefault();
window.event.cancelBubble = true;
// ...
return false; // :-)
}
function mouseHandler(e) {
// sorry, touch only - or - do something useful and non-restrictive for user
}
마우스의 경우 마우스 사용 여부를 감지 할 수 있습니다. 마우스가 사용법에 의해 감지되었음을 나타내는 전역 플래그를 설정할 수 있습니다 (기존 답변과 유사하지만 약간 단순화 됨).
var hasMouse = false;
window.onmousemove = function() {
hasMouse = true;
}
(하나는 터치로 트리거 할 수 mouseup있거나 포함 할 수 없으므로 mousedown)
브라우저는 사용중인 시스템의 하드웨어 기능과 같은 기능을 감지하는 데 필요한 저수준 시스템 API에 대한 액세스를 제한합니다.
플러그인 / 확장 프로그램을 작성하여 액세스 할 수는 있지만 JavaScript 및 DOM을 통해 이러한 탐지는이 목적으로 제한되며 다양한 OS 플랫폼에 맞는 플러그인을 작성해야합니다.
결론적으로, 이러한 탐지는 "좋은 추측"에 의해서만 추정 될 수 있습니다.
때 미디어 쿼리 레벨 4가 브라우저에서 사용할 수 있습니다, 우리는 마우스 장치를 탐지하기 위해 "포인터"와 "가져가"쿼리를 사용할 수 있습니다.
이 정보를 Javascript와 실제로 통신하려면 CSS 쿼리를 사용하여 장치 유형에 따라 특정 스타일을 설정 한 다음 getComputedStyleJavascript를 사용 하여 해당 스타일을 읽고 원래 장치 유형을 파생시킬 수 있습니다.
그러나 언제든지 마우스를 연결 하거나 분리 할 수 있으며 사용자가 터치와 마우스를 전환하려고 할 수 있습니다. 따라서이 변경 을 감지 하고 인터페이스 변경 또는 자동 변경을 제안 해야 할 수도 있습니다 .
어쨌든 인터페이스 간을 전환하는 방법을 제공 할 계획이므로, 사용자에게 링크 또는 버튼을 클릭하여 올바른 버전의 응용 프로그램을 "입력"하도록 요청하는 것이 가능합니까? 그러면 향후 방문에 대한 선호도를 기억할 수 있습니다. 첨단 기술은 아니지만 100 % 신뢰할 수 있습니다 :-)
@SamuelRossille 유감스럽게도 마우스의 존재 (또는 부족)를 노출시키는 브라우저는 없습니다.
따라서, 우리는 기존 옵션 인 이벤트로 최선을 다해야합니다. 나는 그것이 당신이 찾고있는 것이 아니라는 것을 알고 있습니다 ... 현재는 이상적이지 않다는 데 동의했습니다.
주어진 순간에 사용자가 마우스를 사용하는지 아니면 터치를 사용하는지 파악하기 위해 최선을 다할 수 있습니다. 다음은 jQuery & Knockout을 사용하는 빠르고 더러운 예입니다.
//namespace
window.ns = {};
// for starters, we'll briefly assume if touch exists, they are using it - default behavior
ns.usingTouch = ko.observable(Modernizr.touch); //using Modernizr here for brevity. Substitute any touch detection method you desire
// now, let's sort out the mouse
ns.usingMouse = ko.computed(function () {
//touch
if (ns.usingTouch()) {
//first, kill the base mousemove event
//I really wish browsers would stop trying to handle this within touch events in the first place
window.document.body.addEventListener('mousemove', function (e) {
e.preventDefault();
e.stopImmediatePropagation();
}, true);
//remove mouse class from body
$('body').removeClass("mouse");
//switch off touch listener
$(document).off(".ns-touch");
// switch on a mouse listener
$(document).on('mousemove.ns-mouse', function (e) {
if (Math.abs(window.lastX - e.clientX) > 0 || window.lastY !== e.clientY) {
ns.usingTouch(false); //this will trigger re-evaluation of ns.usingMouse() and result in ns.usingMouse() === true
}
});
return false;
}
//mouse
else {
//add mouse class to body for styling
$('body').addClass("mouse");
//switch off mouse listener
$(document).off(".ns-mouse");
//switch on a touch listener
$(document).on('touchstart.ns-touch', function () { ns.usingTouch(true) });
return true;
}
});
//tests:
//ns.usingMouse()
//$('body').hasClass('mouse');
이제 usingMouse () 및 usingTouch () 를 바인딩 / 구독 하거나 body.mouse 클래스로 인터페이스 스타일을 지정할 수 있습니다. 마우스 커서가 감지되고 터치 스타트되면 인터페이스가 앞뒤로 전환됩니다.
바라건대 우리는 곧 브라우저 공급 업체로부터 더 나은 옵션을 얻게 될 것입니다.
Tera-WURFL 은 브라우저 서명 을 데이터베이스와 비교 하여 사이트 를 방문하는 장치의 기능을 알려줍니다 . 그것에게 무료로보세요!
터치 감지 및 / 또는 마우스 움직임에 반응 할 수있는 기능을 감지하는 것이 어떻습니까?
// This will also return false on
// touch-enabled browsers like Chrome
function has_touch() {
return !!('ontouchstart' in window);
}
function has_mouse() {
return !!('onmousemove' in window);
}
이것은 비슷한 상황에서 저에게 효과적이었습니다. 기본적으로 마우스 다운이나 마우스 업을 거치지 않고 일련의 짧은 마우스 동작이 연속적으로 표시 될 때까지 사용자에게 마우스가 없다고 가정합니다. 매우 우아하지는 않지만 작동합니다.
var mousedown = false;
var mousemovecount = 0;
function onMouseDown(e){
mousemovecount = 0;
mousedown = true;
}
function onMouseUp(e){
mousedown = false;
mousemovecount = 0;
}
function onMouseMove(e) {
if(!mousedown) {
mousemovecount++;
if(mousemovecount > 5){
window.removeEventListener('mousemove', onMouseMove, false);
console.log("mouse moved");
$('body').addClass('has-mouse');
}
} else {
mousemovecount = 0;
}
}
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mouseup', onMouseUp, false);
여기서 볼 수있는 주요 문제는 대부분의 터치 장치가 코어 터치 장치와 함께 마우스 이벤트를 발생시키는 것입니다 (touchstart-> mousedown, touchmove-> mousemove 등). 키보드의 경우에만 현대의 키보드에는 일반 브라우저가 있으므로 MouseEvent 클래스의 존재를 감지 할 수도 없습니다.
내 생각에, 덜 고통스러운 해결책은 시작시 메뉴를 표시하고 (키보드 전용 사용자를위한 'alt'관리 기능을 가진) 메뉴를 로컬 저장 장치 / 쿠키 / 서버 측에 저장하거나 다른 방법으로 다음 선택을 유지하는 것입니다 방문자가 올 시간.
modenizr의 특징 중 하나는 터치입니다.
http://modernizr.com/docs/#features-misc
완전히 테스트하지는 않았지만 잘 작동하는 것 같습니다.
또한 이것은 modernizr 페이지 http://www.html5rocks.com/en/mobile/touchandmouse/ 에서 링크됩니다
다른 사람들이 지적했듯이 마우스가 있는지 여부를 확실하게 감지하는 것은 신뢰할 수 없습니다. 장치에 따라 쉽게 변경할 수 있습니다. 적어도 문서 규모에서 부울 true 또는 false로 안정적으로 수행 할 수없는 것입니다.
터치 이벤트 및 마우스 이벤트는 독점적입니다. 따라서 이것은 다른 행동을 취하는 데 다소 도움이 될 수 있습니다. 문제는 터치 이벤트가 마우스 업 / 다운 / 이동 이벤트에 더 가깝고 클릭 이벤트를 트리거한다는 것입니다.
당신의 질문에서 당신은 당신이 미리보기를 가리키고 싶다고 말합니다. 그 외에도 나는 당신의 인터페이스에 대한 다른 구체적인 사항을 모른다. 난 가정 클릭이 때문에 호버 미리보기의 다른 작업을 수행하는 동안, 당신은 미리보기에 탭을 원하는 마우스의 부족으로 그.
이 경우 감지에 다소 게으른 접근 방식을 취할 수 있습니다.
onclick 이벤트는 항상 마우스가있는 onmouseover 이벤트보다 우선합니다. 마우스는 클릭 한 요소 위에 있습니다.
문서 전체의 onmousemove 이벤트로이를 수행 할 수 있습니다. event.target마우스가 상주하는 요소를 기록하는 데 사용할 수 있습니다 . 그런 다음 onclick 이벤트 내에서 마우스가 실제로 클릭되는 요소 (또는 요소의 자식) 위에 있는지 여부를 확인할 수 있습니다.
여기에서 클릭 이벤트에 의존하고 결과에 따라 A 또는 B 조치를 수행하도록 선택할 수 있습니다. 일부 터치 장치에서 클릭 이벤트가 발생하지 않으면 B 동작은 아무 것도 될 수 없습니다 (대신 ontouch * 이벤트에 의존해야 함).
(물론 내 지식으로는) 터치 전용 장치를 식별하는 것이 가능하지 않다고 생각합니다. 주요 문제는 모든 마우스 및 키보드 이벤트가 터치 장치에서도 발생한다는 것입니다. 다음 예를 참조하면 터치 장치에 대해 두 경고가 모두 true를 반환합니다.
function is_touch_present() {
return ('ontouchstart' in window) || ('onmsgesturechange' in window);
}
function is_mouse_present() {
return (('onmousedown' in window) && ('onmouseup' in window) && ('onmousemove' in window) && ('onclick' in window) && ('ondblclick' in window) && ('onmousemove' in window) && ('onmouseover' in window) && ('onmouseout' in window) && ('oncontextmenu' in window));
}
alert("Touch Present: " + is_touch_present());
alert("Mouse Present: " + is_mouse_present());
내 생각에 가장 좋은 아이디어는 mousemove듣는 사람 (현재 가장 좋은 대답)입니다. 이 방법을 약간 조정해야한다고 생각합니다. 이 iOS 토론 에서 볼 수 있듯이 터치 기반 브라우저는 mousemove 이벤트를 에뮬레이트하는 것이 사실 이므로 조금 조심해야합니다.
터치 기반 브라우저는 사용자가 화면을 누를 때 (사용자의 손가락이 눌린 경우)에만이 이벤트를 에뮬레이트합니다. 이것은 우리가 mousemove 처리기 동안 테스트를 추가하여 이벤트 동안 어떤 마우스 버튼이 눌 렸는지 (있는 경우) 확인해야한다는 것을 의미합니다. 마우스 버튼을 누르지 않으면 실제 마우스가 있다고 가정 할 수 있습니다. 마우스 버튼이 눌려 있으면 테스트는 확정되지 않습니다.
그렇다면 어떻게 구현할까요? 이 질문 은 mousemove 중 어떤 마우스 버튼이 눌 렸는지 검사하는 가장 안정적인 방법은 실제로 문서 레벨에서 mousemove, mousedown 및 mouseup의 3 가지 이벤트를 수신하는 것임을 보여줍니다. 위와 아래는 전역 부울 플래그 만 설정합니다. 이동이 테스트를 수행합니다. 움직임이 있고 부울이 거짓이면 마우스가 있다고 가정 할 수 있습니다. 정확한 코드 예제는 질문을 참조하십시오.
마지막 설명입니다.이 테스트는로드 시간에 수행 할 수 없기 때문에 이상적이지 않습니다. 따라서 이전에 제안한대로 점진적 향상 방법을 사용합니다. 기본적으로 마우스 특정 호버 인터페이스를 지원하지 않는 버전이 표시됩니다. 마우스가 발견되면 런타임시 JS를 사용하여이 모드를 사용하십시오. 사용자에게 가능한 한 매끄럽게 표시되어야합니다.
사용자 구성의 변경을 지원하기 위해 (예 : 마우스 연결이 끊어짐) 주기적으로 다시 테스트 할 수 있습니다. 이 경우 단순히 사용자에게 2 가지 모드에 대해 알리고 사용자가 수동으로 전환 할 수 있도록하는 것이 좋습니다 (모바일 / 데스크톱 선택과 마찬가지로 항상 되돌릴 수 있음).
다양한 PC, Linux, iPhone, Android 전화 및 탭에서 일부 테스트를 실행했습니다. 쉬운 방탄 솔루션이 없다는 것이 이상합니다. Touch가 있고 마우스가없는 일부 응용 프로그램에 여전히 Touch 및 Mouse 이벤트가있는 경우 문제가 발생합니다. 마우스 전용 및 터치 전용 인스턴스를 지원하려고하므로 둘 다 처리하려고하지만 두 번의 사용자 상호 작용이 발생합니다. 장치에 마우스가 없다는 것을 알 수 있으면 가짜 / 삽입 된 마우스 이벤트를 무시하는 것을 알 수 있습니다. MouseMove가 발생하면 설정 플래그를 시도했지만 일부 브라우저는 MouseUp 및 MouseDown뿐만 아니라 가짜 MouseMove를 발생시킵니다. 타임 스탬프 검사를 시도했지만 이것이 너무 위험하다고 생각했습니다. 결론 : 가짜 마우스 이벤트를 만든 브라우저는 항상 MouseDown을 삽입하기 직전에 단일 MouseMove를 삽입했습니다. 제 경우의 99.99 %에서 실제 마우스가있는 시스템에서 실행할 때는 여러 개의 연속적인 MouseMove 이벤트가 있습니다 (최소 2 회). 따라서 시스템에서 두 개의 연속적인 MouseMove 이벤트가 발생하는지 여부를 추적하고이 조건이 충족되지 않으면 마우스가 존재하지 않는 것으로 선언하십시오. 이것은 아마도 너무 간단하지만 모든 테스트 설정에서 작동합니다. 더 나은 솔루션을 찾을 때까지 계속 사용하겠습니다. -짐 W
마우스 사용을 감지하는 jQuery의 간단한 솔루션으로 모바일 장치가 'mousemove'이벤트를 트리거하는 문제를 해결합니다. 터치 스타트 리스너를 추가하여 마우스 이동 리스너를 제거하면 터치시 트리거되지 않습니다.
$('body').one('touchstart.test', function(e) {
// Remove the mousemove listener for touch devices
$('body').off('mousemove.test');
}).one('mousemove.test', function(e) {
// MOUSE!
});
물론 장치는 여전히 터치 앤 마우스 일 수 있지만 위의 방법으로 실제 마우스를 사용할 수 있습니다.
내가 아주 우아하다고 생각하는 해결책을 찾았습니다.
// flag as mouse interaction by default
var isMouse = true;
// detect a touch event start and flag it
$(window).on('touchstart', function () {
// if triggers touchstart, toggle flag
// since touch events come before mouse event / click
// callback of mouse event will get in callback
// `isMouse === false`
isMouse = false;
});
// now the code that you want to write
// should also work with `mouse*` events
$('a.someClass').on('click', function () {
if (isMouse) {
// interaction with mouse event
// ...
} else {
// reset for the next event detection
// this is crucial for devices that have both
// touch screen and mouse
isMouse = true;
// interaction with touch event
// ...
}
});
동일한 문제가 발생하여 단일 터치가 클릭으로 등록되었습니다. 내가 가장 많이 투표 한 답변에 대한 의견을 읽은 후 내 솔루션을 생각해 냈습니다.
var body = document.getElementsByTagName('body')[0];
var mouseCount = 0;
// start in an undefined state
// (i use this to blend in elements once we decide what input is used)
var interactionMode = 'undefined';
var registerMouse = function() {
// count up mouseCount every time, the mousemove event is triggered
mouseCount++;
// but dont set it instantly.
// instead wait 20 miliseconds (seems to be a good value for multiple move actions),
// if another mousemove event accoures switch to mouse as interaction
setTimeout(function() {
// a touch event triggers also exactly 1 mouse move event.
// So only if mouseCount is higher than 1 we are really moving the cursor by mouse.
if (mouseCount > 1) {
body.removeEventListener('mousemove', registerMouse);
body.removeEventListener('touchend', registerTouch);
interactionMode = 'mouse';
console.log('now mousing');
listenTouch();
}
// set the counter to zero again
mouseCount = 0;
}, 20);
};
var registerTouch = function() {
body.removeEventListener('mousemove', registerMouse);
body.removeEventListener('touchend', registerTouch);
interactionMode = 'touch';
console.log('now touching');
mouseCount = 0;
listenMouse();
};
var listenMouse = function() {
body.addEventListener("mousemove", registerMouse);
};
var listenTouch = function() {
body.addEventListener("touchend", registerTouch);
};
listenMouse();
listenTouch();
// after one second without input, assume, that we are touching
// could be adjusted to several seconds or deleted
// without this, the interactionMode would stay 'undefined' until first mouse or touch event
setTimeout(function() {
if (!body.classList.contains('mousing') || body.classList.contains('touching')) {
registerTouch();
}
}, 1000);
/* fix, so that scrolling is possible */
html,
body {
height: 110%;
}
Mouse or touch me
내가 찾은 유일한 문제는 터치 이벤트를 올바르게 감지하기 위해 스크롤 할 수 있어야한다는 것입니다. 단일 탭 (터치)으로 인해 문제가 발생할 수 있습니다.
Phonegap 앱 에서이 문제를 알아내는 데 몇 시간을 보냈 으며이 해킹을 생각해 냈습니다. 트리거 된 이벤트가 "수동적"이벤트 인 경우 콘솔 경고를 생성합니다. 즉, 변경 사항이 발생하지 않지만 작동합니다! 개선이나 더 나은 방법에 대한 아이디어가 필요합니다. 그러나 이것은 효과적으로 $ .touch ()를 보편적으로 사용할 수있게합니다.
$(document).ready(function(){
$("#aButton").touch(function(origElement, origEvent){
console.log('Original target ID: ' + $(origEvent.target).attr('id'));
});
});
$.fn.touch = function (callback) {
var touch = false;
$(this).on("click", function(e){
if (!touch)
{
console.log("I click!");
let callbackReal = callback.bind(this);
callbackReal(this, e);
}else{
touch = true;
}
touch = false;
});
$(this).on("touchstart", function(e){
if (typeof e.touches != typeof undefined)
{
e.preventDefault();
touch = true;
console.log("I touch!");
let callbackReal = callback.bind(this);
callbackReal(this, e);
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="aButton">A Button</button>
이 방법을 사용하지 않는 것이 좋습니다. 터치 스크린, 데스크탑 크기의 장치를 고려하면 해결해야 할 다른 문제가 있습니다.
마우스없이 앱을 사용할 수있게하십시오 (예 : 마우스 오버 미리보기 없음).
나를 도와주는 스크립트를 추천하고 싶습니다 :
나는 충분한 결과없이 제안 된 모든 것을 읽고 시도했다.
그런 다음 좀 더 조사 하고이 코드를 발견했습니다 -device.js
나는 클라이언트의 웹 사이트에서 이것을 사용하여 마우스 존재를 감지합니다.
( 클래스 <html>가 있어야 함 desktop) 꽤 좋아 보입니다. touch지원 을 위해 정기적으로 확인 'ontouchend' in document하고 두 가지 감지 정보를 사용하여 필요한 특정 것을 가정합니다.
일반적으로 OS / 브라우저 유형을 감지하는 대신 마우스 오버 기능이 지원되는지 감지하는 것이 좋습니다. 다음과 같이 간단하게 수행 할 수 있습니다.
if (element.mouseover) {
//Supports the mouseover event
}
다음 을 수행하지 않아야 합니다.
if (element.mouseover()) {
// Supports the mouseover event
}
후자는 실제로 메소드의 존재를 확인하는 대신 메소드를 호출합니다.
자세한 내용은 여기를 참조하십시오 : http://www.quirksmode.org/js/support.html
'Programming' 카테고리의 다른 글
| MVC2에서 Html.Partial (view, model)과 Html.RenderPartial (view, model)의 차이점은 무엇입니까? (0) | 2020.06.21 |
|---|---|
| history.pushState를 통해 히스토리 변경 사항에 대한 알림을받는 방법은 무엇입니까? (0) | 2020.06.21 |
| Swift에서 가변 개수의 인수를 가진 함수에 배열 전달 (0) | 2020.06.21 |
| SQL Server NOLOCK 및 조인 (0) | 2020.06.21 |
| ASP.NET 임시 파일 정리 (0) | 2020.06.21 |