브라우저에 마우스가 없고 터치 전용임을 감지
터치(클릭 시 손가락이 화면을 숨깁니다)와 마우스(호버 프리뷰에 크게 의존하는)를 위한 매우 다른 인터페이스를 가진 웹 앱(흥미로운 텍스트 페이지가 있는 웹 사이트가 아님)을 개발하고 있습니다.사용자가 올바른 인터페이스를 제공할 마우스가 없다는 것을 어떻게 알 수 있습니까?마우스와 터치(몇몇 노트처럼)를 함께 사용하는 사람들을 위해 스위치를 남겨둘 계획입니다.
브라우저의 터치 이벤트 기능은 실제로 사용자가 터치 장치를 사용하고 있음을 의미하지 않습니다(예: Modernizr는 이를 자르지 않음).장치에 마우스가 있으면 질문에 올바르게 대답하는 코드가 거짓으로 반환되고 그렇지 않으면 참으로 반환됩니다.마우스와 터치가 있는 장치의 경우 거짓을 반환해야 합니다(터치만 해당하는 것은 아님).
참고로, 터치 인터페이스는 키보드 전용 장치에도 적합할 수 있으므로 마우스가 부족합니다.
필요성을 보다 명확히 하기 위해 구현하고자 하는 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);
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 something
}
관련:
W3 문서: https://www.w3.org/TR/mediaqueries-4/ # mf-interaction
브라우저 지원: https://caniuse.com/ #search=media %20
비슷한 문제:클라이언트 디바이스가 :hover 및 :focus 상태를 지원하는지 탐지합니다.
가장 큰 문제는 다음과 같은 다양한 종류의 장치/사용 사례가 있다는 것입니다.
- 마우스 및 키보드(데스크톱)
- 터치 전용(전화/태블릿)
- 마우스, 키보드 및 터치(노트북 터치)
- 터치 및 키보드(태블릿의 블루투스 키보드)
- 마우스만 해당(사용자/브라우징 기본 설정 비활성화)
- 키보드만 해당(사용자/브라우징 기본 설정 사용 안 함)
- 터치 및 마우스(즉, Galaxy Note 2 펜에서 이벤트 호버)
더 나쁜 것은 이러한 클래스 중 일부에서 다른 클래스(마우스의 플러그, 키보드에 연결)로 전환하거나 사용자가 손을 뻗어 화면을 터치할 때까지 일반 노트북에 있는 것처럼 보일 수 있다는 것입니다.
브라우저에 이벤트 생성자가 있는 것이 앞으로 나아가는 좋은 방법이 아니라고 가정하는 것이 맞습니다(그리고 다소 일관되지 않음).또한 특정 이벤트를 추적하거나 위의 몇 가지 클래스만 제외하려고 하지 않는 한 이벤트 자체를 사용하는 것은 완전한 증거가 되지 않습니다.
예를 들어, 사용자가 실제 마우스 움직임(터치 이벤트에서 거짓이 아닌)을 내보냈다는 것을 발견했다고 가정합니다. http://www.html5rocks.com/en/mobile/touchandmouse/) 을 참조하십시오.
그럼 뭐예요?
호버 스타일을 사용할 수 있습니까?단추를 더 넣으시나요?
어느 쪽이든 이벤트가 발생할 때까지 기다려야 하기 때문에 유리 제조 시간을 늘리는 것입니다.
하지만 고귀한 사용자가 마우스 플러그를 뽑고 풀터치를 하기로 결정하면 어떻게 됩니까?당신은 그가 당신의 현재 꽉 찬 인터페이스를 터치할 때까지 기다렸다가, 그가 당신의 현재 혼잡한 UI를 정확히 집어내기 위해 노력한 직후에 그것을 바꾸려고 하십니까?
총알 형태로, https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101 의 stucox를 인용합니다.
- 우리는 쥐의 존재를 탐지하기를 원합니다.
- 이벤트가 발생하기 전에는 감지할 수 없을 겁니다
- 따라서 이 세션에서 마우스를 사용한 적이 있는지 여부를 확인할 수 있습니다. 즉, 페이지 로드가 즉시 발생하지는 않습니다.
- 마우스가 없다는 것도 감지할 수 없습니다. 사실일 때까지 정의되지 않습니다. (사실이 입증될 때까지 거짓으로 설정하는 것보다 이것이 더 합리적이라고 생각합니다.)
- 세션 도중에 마우스가 연결이 끊겼는지 여부를 감지할 수 없습니다. 이는 사용자가 마우스를 포기하는 것과 구별할 수 없습니다.
별도: 브라우저는 사용자가 마우스를 꽂거나 키보드에 연결할 때는 알 수 있지만 자바스크립트에는 노출되지 않습니다.젠장!
이를 통해 다음과 같은 결과를 얻을 수 있습니다.
특정 사용자의 현재 기능을 추적하는 것은 복잡하고, 신뢰할 수 없으며, 가치가 불분명합니다.
그러나 점진적 향상이라는 개념은 여기에 꽤 잘 적용됩니다.사용자의 상황에 상관없이 원활하게 작동하는 경험을 구축합니다.그런 다음 브라우저 기능/미디어 쿼리를 기반으로 가정하여 가정한 컨텍스트에서 상대적인 기능을 추가합니다.마우스의 존재는 다양한 장치의 여러 사용자가 웹 사이트를 경험하는 다양한 방법 중 하나일 뿐입니다.커널에 장점이 있는 것을 만들고 사람들이 버튼을 클릭하는 방식에 대해 너무 걱정하지 마십시오.
문서에서 마우스 이동 이벤트를 들어보는 것은 어떨까요?그런 다음 해당 이벤트를 들을 때까지 장치가 터치 또는 키보드로만 구성되어 있다고 가정합니다.
var mouseDetected = false;
function onMouseMove(e) {
unlisten('mousemove', onMouseMove, false);
mouseDetected = true;
// initializeMouseBehavior();
}
listen('mousemove', onMouseMove, false);
(어디에listen
그리고.unlisten
위임을 보다addEventListener
아니면attachEvent
필요에 따라서.)
너무 많은 시각적 충격을 주지 않기를 바랍니다. 모드에 따라 대규모 재배치가 필요하다면..
@와이엇의 대답은 훌륭하고 우리에게 많은 생각을 하게 해줍니다.
제 경우에는 첫 번째 상호작용을 듣고 행동을 설정하기로 했습니다.그래서 사용자가 마우스를 가지고 있더라도 첫 번째 상호작용이 터치였다면 저는 터치 디바이스로 취급할 것입니다.
이벤트가 처리되는 주어진 순서를 고려하면 다음과 같습니다.
- 터치 스타트
- 터치 동작
- 만지다
- 마우스로 보다
- 마우스 동작
- 콧수염을 기른
- 마우스를 갖다 대다
- 딸깍 소리를 내다
마우스 이벤트가 터치 전에 트리거되면 에뮬레이트된 이벤트가 아니라 실제 마우스 이벤트라고 가정할 수 있습니다.예제(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에 대한 액세스를 제한합니다.
이러한 것들에 접근하기 위해 플러그인/확장자를 작성할 수도 있지만 자바스크립트와 DOM을 통해 이러한 탐지는 이러한 목적으로 제한되며 다양한 OS 플랫폼에 맞는 플러그인을 작성해야 합니다.
따라서 결론적으로, 그러한 탐지는 "좋은 추측"에 의해서만 추정될 수 있습니다.
브라우저에서 미디어 쿼리 레벨 4를 사용할 수 있게 되면 마우스로 장치를 탐지하기 위해 "포인터" 및 "호버" 쿼리를 사용할 수 있게 됩니다.
우리가 정말로 자바스크립트에 그 정보를 전달하고 싶다면, CSS 쿼리를 사용하여 디바이스 유형에 따라 특정 스타일을 설정한 후 사용할 수 있습니다.getComputedStyle
자바스크립트로 해당 스타일을 읽고 원본 디바이스 유형을 유도합니다.
그러나 마우스는 언제든지 연결하거나 플러그를 뽑을 수 있으며, 사용자는 터치와 마우스 사이를 전환하기를 원할 수 있습니다.따라서 이러한 변경을 감지하고 인터페이스를 자동으로 변경하거나 변경할 것을 제안해야 할 수도 있습니다.
어쨌든 인터페이스 간에 전환할 수 있는 방법을 제공할 예정이니 단순히 링크나 버튼을 클릭하여 응용 프로그램의 올바른 버전을 "입력"하도록 사용자에게 요청하는 것이 가능하겠습니까?그러면 당신은 그들이 앞으로 방문하는 것을 선호하는 것을 기억할 수 있을 것입니다.하이테크는 아니지만 100% 신뢰할 수 있습니다 :-)
이것은 저에게도 비슷한 상황에서 효과가 있었습니다.기본적으로 마우스 다운이나 마우스 업을 개입시키지 않고 짧은 일련의 마우스 연속 이동을 볼 때까지 사용자에게 마우스가 없다고 가정합니다.그다지 우아하진 않지만, 효과는 있습니다.
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);
@Samuel Rossille 불행하게도 제가 알고 있는 브라우저는 마우스의 존재를 노출하지 않습니다.
그러니 지금의 선택지로 최선을 다하면 되는 겁니다사건.당신이 원하는게 아닌걸 알아요현재로서는 이상과는 거리가 멀다는 데 동의했습니다.
우리는 사용자가 어떤 순간에 마우스를 사용하는지 터치를 사용하는지 파악하기 위해 최선을 다 할 수 있습니다.다음은 jQuery & Knout을 사용한 빠르고 더러운 예입니다.
//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');
이제 마우스() & 를 사용하여 바인딩/구독할 수 있습니다.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 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
내가 찾은 유일한 문제는 터치 이벤트를 제대로 감지하기 위해 스크롤할 수 있어야 한다는 것입니다. 탭(터치) 하나로 문제가 생길 수 있습니다.
다른 사람들이 지적한 것처럼, 마우스를 가졌는지 아닌지를 결정적으로 감지하는 것은 신뢰할 수 없습니다.이는 기기에 따라 쉽게 변경될 수 있습니다.적어도 문서 규모에서는 부울 참 또는 거짓으로 확실하게 수행할 수 없는 작업입니다.
터치 이벤트와 마우스 이벤트는 독점적입니다.따라서 다양한 행동을 취할 때 어느 정도 도움이 될 수 있습니다.문제는 터치 이벤트가 마우스 업/다운/무브 이벤트에 더 가깝고 클릭 이벤트도 트리거한다는 것입니다.
당신의 질문에서 당신은 미리 보기를 위해 호버링을 하고 싶다고 말합니다.그 외에 당신의 인터페이스에 대해서는 자세히 알지 못합니다.마우스가 없어서 클릭 한 번으로 미리 보기를 원하는 반면 호버 미리 보기 때문에 다른 작업을 수행하는 것으로 가정합니다.
이 경우 탐지에 다소 게으른 접근 방식을 취할 수 있습니다.
클릭 시 이벤트에는 항상 마우스를 사용한 마우스 오버 이벤트가 선행됩니다.마우스가 클릭된 요소의 맨 위에 있음을 기록합니다.
문서 전체의 마우스 이동 이벤트를 통해 이 작업을 수행할 수 있습니다.사용가능event.target
마우스가 어떤 요소에 있는지 기록합니다.그런 다음 클릭 이벤트 내부에서 마우스가 실제로 클릭 중인 요소 위에 있는지(또는 요소의 자식인지)를 확인할 수 있습니다.
여기서 둘 다 클릭 이벤트에 의존하고 결과에 따라 A 또는 B 동작을 수행하도록 선택할 수 있습니다.일부 터치 장치에서 클릭 이벤트가 발생하지 않으면 B 동작이 아무것도 아닐 수 있습니다(대신 터치* 이벤트에 의존해야 함).
(물론 제가 아는 한) 터치 전용 기기를 식별하는 것은 불가능하다고 생각합니다.가장 큰 문제는 모든 마우스와 키보드 이벤트가 터치 장치에 의해서도 발생한다는 것입니다.다음 예를 참조하십시오. 터치 디바이스에 대해서는 두 경고가 모두 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 토론에서 볼 수 있듯이 마우스 이동 이벤트까지 모방하는 것이 사실이므로 조금 조심해야 합니다.
터치 기반 브라우저는 사용자가 화면을 두드릴 때(사용자의 손가락이 아래로 떨어짐)에만 이 이벤트를 모방하는 것이 타당합니다.즉, 마우스 이동 핸들러 중에 테스트를 추가하여 이벤트 중에 어떤 마우스 버튼이 다운되었는지(있는 경우) 확인해야 합니다.마우스 버튼이 다운되지 않은 경우, 실제 마우스가 존재하는 것으로 안전하게 가정할 수 있습니다.마우스 버튼이 닫혀 있으면 테스트 결과가 나오지 않습니다.
그렇다면 이를 어떻게 구현할 것인가요?이 질문은 마우스 이동 중에 어떤 마우스 버튼이 다운되었는지 확인하는 가장 신뢰할 수 있는 방법은 마우스 이동, 마우스 다운 및 마우스 업의 세 가지 이벤트를 문서 수준에서 실제로 청취하는 것입니다.위쪽과 아래쪽은 글로벌 부울 플래그만 설정합니다.이 동작은 테스트를 수행합니다.움직임이 있는데 부울이 거짓이면 마우스가 있다고 가정할 수 있습니다.정확한 코드 예제는 질문을 참조하십시오.
마지막 댓글 하나..이 테스트는 로드 시간에 수행할 수 없기 때문에 이상적이지 않습니다.따라서 앞서 제시한 바와 같이 점진적 향상 방법을 사용하고자 합니다.기본적으로 마우스별 호버 인터페이스를 지원하지 않는 버전을 표시합니다.마우스가 발견되면 JS를 사용하여 런타임에 이 모드를 활성화합니다.이것은 사용자에게 가능한 한 매끄럽게 보여야 합니다.
사용자 구성 변경(즉, 마우스 연결이 끊어짐)을 지원하기 위해 주기적으로 다시 테스트할 수 있습니다.이 경우에는 단순히 사용자에게 두 가지 모드에 대해 알려주고 사용자가 수동으로 전환하도록 하는 것이 더 나을 것이라고 생각합니다(항상 반대로 전환할 수 있는 모바일/데스크톱 선택처럼).
다양한 PC, Linux, iPhone, Android 전화기 및 탭에서 몇 가지 테스트를 실행했습니다.방탄이 쉬운 해결책이 없다는 게 이상합니다.터치가 있고 마우스가 없는 일부는 여전히 터치 및 마우스 이벤트를 응용 프로그램에 표시할 때 문제가 발생합니다.마우스 전용 인스턴스와 터치 전용 인스턴스를 지원하고 싶으므로 두 가지를 모두 처리하고 싶지만 이로 인해 사용자 상호 작용이 이중으로 발생합니다.장치에 마우스가 없다는 것을 알 수 있는 경우 가짜/삽입된 마우스 이벤트를 무시할 수 있습니다.마우스 무브가 발생하면 플래그를 설정하려고 했지만, 일부 브라우저는 가짜 마우스 무브와 마우스 업, 마우스 다운을 던집니다.타임스탬프를 검사하려고 했지만 너무 위험하다고 생각했습니다.최종 결과:가짜 마우스 이벤트를 만든 브라우저는 항상 마우스 다운을 삽입하기 직전에 마우스 무브 하나를 삽입했습니다.99.99%의 경우 실제 마우스가 있는 시스템에서 실행할 경우 마우스 이동 이벤트가 여러 개 연속적으로 발생합니다(최소 두 개).따라서 시스템에 MouseMove 이벤트가 두 번 연속 발생하는지 여부를 추적하고 이 조건이 충족되지 않으면 마우스가 없다고 선언합니다.이것은 너무 간단할 수도 있지만 모든 테스트 설정에서 작동합니다.더 나은 해결책을 찾을 때까지 이 문제를 계속 해결해 나갈 생각입니다. - 짐 W.
모바일 기기에서도 '마우스 이동' 이벤트가 발생하는 문제를 해결하는 jQuery의 간단한 솔루션입니다.터치 시작 청취자를 추가하여 마우스 이동 청취자를 제거하면 터치 시 트리거되지 않습니다.
$('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
// ...
}
});
저는 제 폰갭 앱을 위해 몇 시간 동안 이 문제를 파악했고 이 해킹을 생각해 냈습니다.트리거된 이벤트가 "패시브" 이벤트일 경우 콘솔 경고를 생성합니다. 즉, 변경 사항을 활성화하지는 않지만 작동합니다.개선할 수 있는 아이디어나 더 나은 방법에 관심이 있습니다.하지만 이를 통해 $.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>
여기서 보이는 가장 큰 문제는 대부분의 터치 장치가 코어 대응 터치 원(터치 시작 -> 마우스 다운, 터치 무브 -> 마우스 무브 등)과 함께 마우스 이벤트를 발생시킨다는 것입니다.키보드만 있는 경우, 현대 키보드의 경우, 일반 브라우저를 가지고 있어서 마우스 이벤트 클래스의 존재조차 감지할 수 없습니다.
제 생각에 여기서 덜 고통스러운 해결책은 (키보드 사용자만을 위한 'alt' 관리 기능이 있는) 시작 시 메뉴를 표시하고, 다음 방문자가 왔을 때 동일한 선택 사항을 유지하기 위해 로컬 스토리지/쿠키/서버 사이드 또는 기타에 선택 사항을 저장하는 것입니다.
아래의 토막글을 실행하여 이를 시험해 봅니다.
var msg = (window.matchMedia("(any-pointer: coarse)").matches ? "Touchscreen" : "Mouse");
var msg = (window.matchMedia("(any-pointer: coarse)").matches ? "Touchscreen" : "Mouse");
document.getElementById('info').innerHTML = msg;
body {
background: black;
color: cornflowerblue;
}
#info {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 30vmin;
font-family: verdana, arial, helvetica;
}
<div id='info'></div>
(에 대한 자세한 내용은 다음과 같습니다.)
저는 이 접근 방식에 반대할 것을 강력히 권고합니다.터치 스크린, 데스크톱 크기의 장치를 고려해 보면 해결해야 할 문제가 다양합니다.
마우스 없이 앱을 사용할 수 있도록 하십시오(예: 호버 프리뷰 없음).
일반적으로 OS/브라우저 유형을 감지하는 것보다 마우스 오버 기능이 지원되는지 여부를 감지하는 것이 더 좋습니다.이 작업은 다음과 같은 방법으로 간단히 수행할 수 있습니다.
if (element.mouseover) {
//Supports the mouseover event
}
다음 작업을 수행하지 않도록 하십시오.
if (element.mouseover()) {
// Supports the mouseover event
}
후자는 실제로 그 존재를 확인하기 보다는 방법을 부를 것입니다.
여기서 더 자세히 보실 수 있습니다: http://www.quirksmode.org/js/support.html
언급URL : https://stackoverflow.com/questions/7838680/detecting-that-the-browser-has-no-mouse-and-is-touch-only
'programing' 카테고리의 다른 글
리눅스: sig_atomic_type이 int로 지정되는 이유는 무엇입니까? (0) | 2023.10.23 |
---|---|
a에서 jQuery Change 이벤트a에서 jQuery Change 이벤트요소 - 이전 값을 유지할 수 있는 방법이 있습니까?요소 - 이전 값을 유지할 수 있는 방법이 있습니까? (0) | 2023.10.23 |
구조물의 함수 (0) | 2023.10.23 |
NSS 문자열을 설정 길이로 자르는 방법은 무엇입니까? (0) | 2023.10.23 |
Wordpress 사이트에 대한 도메인 마스킹이 있는 htaccess 리디렉션이 작동하지 않습니다. (0) | 2023.10.23 |