2009-10-05 63 views
49

我正在使用與鼠標移動事件一起操作的YUI滑塊。我想讓它響應touchmove事件(iPhone和Android)。觸摸移動事件發生時,如何產生鼠標移動事件?我希望只需在頂部添加一些腳本,touchmove事件就會映射到鼠標移動事件上,而不必用滑塊來更改任何內容。JavaScript將觸摸事件映射到鼠標事件

+0

你可以發佈你到目前爲止的代碼嗎? – 2009-10-05 01:45:27

+0

我使用YUI庫中的這兩個滑塊: http://developer.yahoo.com/yui/examples/slider/slider-ticks_clean.html http://developer.yahoo.com/yui/examples/ slider/slider_dual_with_highlight.html – Questioner 2009-10-05 07:04:25

回答

95

我相信這是你想要什麼:

function touchHandler(event) 
{ 
    var touches = event.changedTouches, 
     first = touches[0], 
     type = ""; 
    switch(event.type) 
    { 
     case "touchstart": type = "mousedown"; break; 
     case "touchmove": type = "mousemove"; break;   
     case "touchend": type = "mouseup"; break; 
     default:   return; 
    } 

    // initMouseEvent(type, canBubble, cancelable, view, clickCount, 
    //    screenX, screenY, clientX, clientY, ctrlKey, 
    //    altKey, shiftKey, metaKey, button, relatedTarget); 

    var simulatedEvent = document.createEvent("MouseEvent"); 
    simulatedEvent.initMouseEvent(type, true, true, window, 1, 
            first.screenX, first.screenY, 
            first.clientX, first.clientY, false, 
            false, false, false, 0/*left*/, null); 

    first.target.dispatchEvent(simulatedEvent); 
    event.preventDefault(); 
} 

function init() 
{ 
    document.addEventListener("touchstart", touchHandler, true); 
    document.addEventListener("touchmove", touchHandler, true); 
    document.addEventListener("touchend", touchHandler, true); 
    document.addEventListener("touchcancel", touchHandler, true);  
} 

我捕捉觸摸事件,然後手動解僱我自己的鼠標事件相匹配。雖然代碼不是特別通用,但適應大多數現有的拖放庫以及大多數現有的鼠標事件代碼應該是微不足道的。希望這個想法對於爲iPhone開發Web應用程序的人來說非常方便。

更新:

在發佈此,我注意到,呼籲所有觸摸事件,preventDefault將阻止正常的工作聯繫。要撥打preventDefault的主要原因是要停止滾動電話,並且只能通過撥打touchmove回撥來呼叫。這樣做的唯一缺點是iPhone有時會在拖動原點上顯示懸停彈出窗口。如果我發現一種方法來防止這種情況發生,我會更新這篇文章。

第二次更新:

我已經找到了CSS屬性關閉標註:-webkit-touch-callout

+1

並非所有touchmove事件都會轉化爲mousemove事件!例如如果您只想在屏幕上向下滾動,touchmove事件也會被觸發,但會轉換爲滾動事件...! – nerdess 2013-03-18 12:03:06

+0

我發現這個最有幫助,同時試圖找出爲什麼觸摸屏顯示器不會在鼠標所在的屏幕上繪製。 Chrome和Firefox在這方面似乎有不同的行爲。在Firefox中,我發現你仍然可以從觸摸屏獲得鼠標移動事件,但Chrome瀏覽器不會。 – 2015-09-08 16:19:49

+1

現在不推薦使用initMouseEvent方法(https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent) – 2015-12-14 16:19:34

5

沿着@Mickey Shine的回答,Touch Punch提供了觸摸事件到點擊事件的映射。它的構建是爲了將這種支持加入到jQuery UI中,但the code是提供信息的。

1

我終於找到了一種方法來使用Mickey的解決方案,而不是他的init函數。在這裏使用init函數。

function init() { 
    document.getElementById('filter_div').addEventListener("touchstart", touchHandler, true); 
    document.getElementById('filter_div').addEventListener("touchmove", touchHandler, true); 
    document.getElementById('filter_div').addEventListener("touchend", touchHandler, true); 
    document.getElementById('filter_div').addEventListener("touchcancel", touchHandler, true); 
} 

如果你看到「filter_div」是圖表區域,我們有圖表範圍過濾器,只在這方面我們要改寫我們的觸摸控制!

謝謝米奇。這是一個很好的解決方案。

+2

如果你正在投票,請添加一個原因! – Sana 2015-03-15 23:22:30

3

對於未來的用戶,誰復出這裏下面的代碼可用於:

var eventMap = {}; 

(function(){ 
var eventReplacement = { 
    "mousedown": ["touchstart mousedown", "mousedown"], 
    "mouseup": ["touchend mouseup", "mouseup"], 
    "click": ["touchstart click", "click"], 
    "mousemove": ["touchmove mousemove", "mousemove"] 
}; 


for (i in eventReplacement) { 
    if (typeof window["on" + eventReplacement[i][0]] == "object") { 
     eventMap[i] = eventReplacement[i][0]; 
    } 
    else { 
     eventMap[i] = eventReplacement[i][1]; 
    }; 
}; 
})(); 

然後在事件使用類似以下內容:

$(".yourDiv").on(eventMap.mouseup, function(event) { 
     //your code 
} 
0

爲了使@米奇的代碼工作在邊緣和Internet Explorer中,在要發生模擬的元素的.css中添加以下行:

.areaWhereSimulationHappens { 
    overflow: hidden; 
    touch-action: none; 
    -ms-touch-action: none; 
} 

這些行防止邊緣和IE的默認觸摸。但是,如果將它添加到錯誤的元素中,則它也會禁用滾動(這在邊緣和觸摸設備上的IE上默認會發生)。