브라우저에 마우스가없고 터치 전용임을 감지 터치 (손가락을 클릭하면 화면이 숨겨 짐)와 마우스

터치 (손가락을 클릭하면 화면이 숨겨 짐)와 마우스 (호버 미리보기에 크게 의존)와 매우 다른 인터페이스를 가진 웹 응용 프로그램 (흥미로운 텍스트 페이지가있는 웹 사이트가 아님)을 개발 중입니다. 사용자에게 올바른 인터페이스를 제공 할 마우스가 없는지 어떻게 알 수 있습니까? 마우스와 터치가있는 사람 (예 : 일부 노트북)을위한 스위치를 남겨 둘 계획입니다.

브라우저의 터치 이벤트 기능이 실제로 사용자가 터치 장치를 사용하고 있다는 것을 의미하지는 않습니다 (예 : 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);


답변

가장 큰 문제는 다음과 같은 다른 종류의 장치 / 사용 사례가 있다는 것입니다.

  1. 마우스 및 키보드 (데스크톱)
  2. 터치 만 (전화 / 태블릿)
  3. 마우스, 키보드 및 터치 (터치 랩톱)
  4. 터치 및 키보드 (태블릿의 블루투스 키보드)
  5. 마우스 만 (사용 불가능한 사용자 / 브라우징 환경 설정)
  6. 키보드 만 (사용 불가능한 사용자 / 브라우징 환경 설정)
  7. 터치 및 마우스 (예 : Galaxy Note 2 펜의 호버 이벤트)

더 나쁜 것은,이 클래스 중 일부에서 다른 클래스로 전환 할 수 있거나 (마우스에 연결하고 키보드에 연결) 사용자가 화면에 닿아 화면을 터치 할 때까지 일반 랩톱에있는 것처럼 보일 수 있습니다.

브라우저에 이벤트 생성자가 존재하는 것이 앞으로 나아갈 수있는 좋은 방법이 아니라고 가정합니다 (일관되지 않음). 또한 매우 구체적인 이벤트를 추적하거나 위의 몇 가지 클래스 만 배제하지 않는 한 이벤트 자체를 사용하는 것이 완벽한 증거는 아닙니다.

예를 들어, 사용자가 실제 마우스 이동 (터치 이벤트에서 잘못된 마우스 이동이 아님)을 발견 한 경우 http://www.html5rocks.com/en/mobile/touchandmouse/를 참조하십시오 . )을 .

그리고 뭐?

호버 스타일을 사용 하시겠습니까? 버튼을 더 추가 하시겠습니까?

어느 쪽이든 이벤트가 발생할 때까지 기다려야하므로 유리 컵 시간이 늘어나고 있습니다.

그러나 고귀한 사용자가 마우스를 뽑고 풀 터치하고 싶을 때 어떤 일이 벌어 지나요? 지금 밀려 난 인터페이스를 만질 때까지 기다렸다가 지금 붐비는 UI를 찾기 위해 노력한 후 바로 변경 하시겠습니까?

글 머리 기호 형식으로 https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101 에서 stucox를 인용 하십시오.

  • 마우스의 존재를 감지하고 싶다
  • 아마도 이벤트가 시작되기 전에는 감지 할 수 없습니다
  • 따라서 우리가 감지하는 것은이 세션에서 마우스가 사용 된 경우입니다. 즉, 페이지로드에서 즉시 발생하지는 않습니다.
  • 또한 마우스가 없다는 것을 감지하지 못할 수도 있습니다. 사실까지는 정의되지 않을 것입니다.
  • 그리고 아마도 세션 중 마우스 연결이 끊어 졌는지 감지 할 수 없습니다. 사용자가 마우스를 포기하는 것과 구분할 수 없을 것입니다

따로 : 브라우저는 사용자가 마우스를 연결하거나 키보드에 연결할 때 알고 있지만 JavaScript에 노출하지 않습니다 .. dang!

이것은 다음으로 이어질 것입니다 :

특정 사용자의 현재 기능을 추적하는 것은 복잡하고 신뢰할 수 없으며 모호한 장점이 있습니다.

그러나 점진적 향상이라는 아이디어는 여기서도 잘 적용됩니다. 사용자의 상황에 관계없이 원활하게 작동하는 경험을 구축하십시오. 그런 다음 브라우저 기능 / 미디어 쿼리를 기반으로 가정하여 가정 된 상황에서 상대적으로 기능을 추가합니다. 마우스의 존재는 여러 장치의 서로 다른 사용자가 웹 사이트를 경험하는 다양한 방법 중 하나 일뿐입니다. 커널에 장점이있는 무언가를 만들고 사람들이 버튼을 클릭하는 방식에 대해 너무 걱정하지 마십시오.


답변

문서에서 mousemove 이벤트를 수신하는 것은 어떻습니까. 그런 다음 해당 이벤트가 들릴 때까지 장치가 터치 또는 키보드 전용이라고 가정합니다.

var mouseDetected = false;
function onMouseMove(e) {
  unlisten('mousemove', onMouseMove, false);
  mouseDetected = true;
  // initializeMouseBehavior();
}
listen('mousemove', onMouseMove, false);

(여기서 listenunlisten대리자 addEventListener또는 attachEvent적절한.)

바라건대 이것은 시각적으로 너무 많은 영향을 미치지 않을 것입니다. 모드에 따라 대규모 재 레이아웃이 필요하다면 짜증날 것입니다 …


답변

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
}

관련 :

W3 설명서 : https://www.w3.org/TR/mediaqueries-4/#mf-interaction

브라우저 지원 : https://caniuse.com/#search=media%20features

비슷한 문제 : 클라이언트 장치가 : hover 및 : focus 상태를 지원하는지 감지


답변

@Wyatt의 대답은 훌륭하고 우리가 생각할 많은 것을 제공합니다.

제 경우에는 첫 번째 상호 작용을 듣고 행동을 설정하기로 결정했습니다. 따라서 사용자에게 마우스가 있어도 첫 번째 상호 작용이 터치 인 경우 터치 장치로 취급합니다.

이벤트가 처리되는 주어진 순서를 고려하십시오 .

  1. 터치 스타트
  2. 터치
  3. 터치
  4. 마우스 오버
  5. mousemove
  6. 마우스 다운
  7. 마우스
  8. 딸깍 하는 소리

마우스 이벤트가 터치 전에 트리거되면 에뮬레이트 된 이벤트가 아니라 실제 마우스 이벤트라고 가정 할 수 있습니다. 예 (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);
});

그것은 나를 위해 일했다


답변

브라우저가 터치 가능한지 여부 만 감지 할 수 있습니다. 실제로 터치 스크린이나 마우스가 연결되어 있는지 알 수있는 방법이 없습니다.

터치 기능이 감지되면 마우스 이벤트 대신 터치 이벤트를 수신하여 사용의 우선 순위를 지정할 수 있습니다.

터치 기능 크로스 브라우저를 감지하려면

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 쿼리를 사용하여 장치 유형에 따라 특정 스타일을 설정 한 다음 getComputedStyle Javascript를 하여 해당 스타일을 읽고 원래 장치 유형을 파생시킬 수 있습니다.

그러나 언제든지 마우스를 연결 하거나 분리 할 수 있으며 사용자는 터치와 마우스를 전환하려고 할 수 있습니다. 따라서이 변경 을 감지 하고 인터페이스 변경 또는 자동 변경을 제안 해야 할 수도 있습니다 .


답변

어쨌든 인터페이스 간을 전환 할 수있는 방법을 제공 할 계획이므로 사용자에게 링크 나 버튼을 클릭하여 올바른 버전의 응용 프로그램을 “입력”하도록 요청하는 것이 가능합니까? 그러면 향후 방문에 대한 선호도를 기억할 수 있습니다. 첨단 기술은 아니지만 100 % 신뢰할 수 있습니다 🙂