I've built a webapp, and for a little bit of polish, I wanted to add mousedown and mouseup handlers to swap out images (in this case, to make a button look like it's being pressed).
my code is something like this:
window.onload = function() { //preload mouse down image here via Image() $("#button_img").mousedown(function(){$("#button_img").attr("src","button_on.png");}); $("#button_img").mouseup(function(){$("#button_img").attr("src","button_off.png")}); }
This works swimmingly on the desktop, but on mobile (testing in iOS Safari), the mousedown and mouseup events happen at the same time, so effectively nothing happens.
I tried to use the vmousedown and vmouseup events in jQueryMobile, however this code:
//include jquerymobile.js and jquerymobile.css window.onload = function() { //preload mouse down image here via Image() $("#button_img").vmousedown(function(){$("#button_img").attr("src","button_on.png");}); $("#button_img").vmouseup(function(){$("#button_img").attr("src","button_off.png")}); }
Just gave me the errors that vmousedown and vmouseup don't exist. Also, jQueryMobile overrides the CSS I've already written for the page.
So is there a way to get vmousedown and vmouseup to work, and to do so without jQuery Mobile's CSS?
This works swimmingly on the desktop, but on mobile (testing in iOS Safari), the mousedown and mouseup events happen at the same time, so effectively nothing happens.
To cause a MouseDown event for a form section to occur, press the mouse button in a blank area of the form section. The following apply to MouseDown events: If a mouse button is pressed while the pointer is over a form or control, that object receives all mouse events up to and including the last MouseUp event.
When using a mouse, the target element class is added immediately when the mouse is held down, but when using the touchscreen, the target element class is not changed when the finger is held on the element.
Note: This differs from the click event in that click is fired after a full click action occurs; that is, the mouse button is pressed and released while the pointer remains inside the same element. mousedown is fired the moment the button is initially pressed.
.mousedown( handler )Returns: jQuery. JavaScript event, or trigger that event on an element. Type: Function( Event eventObject ) A function to execute each time the event is triggered. An object containing data that will be passed to the event handler.
The jQuery Mobile vmousedown event handler simulates the "onmousedown" event handler on mobile devices. This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .vmousedown () method may not fail directly, as the method still exists.
Following table lists some of the events for the mobile devices, which are supported by jQuery Mobile. It responds to user interaction when the user clicks on a certain page or hovers the mouse over an element, etc. It provides touch events when the user touches the screen.
The mousedown event is sent to an element when the mouse pointer is over the element, and the mouse button is pressed. Any HTML element can receive this event. The event handler can be bound to any <div>:
You're looking for touchstart
and touchend
. They are the events that vmousedown
and vmouseup
attempt to mimic.
Here's an example:
window.onload = function() { //preload mouse down image here via Image() $("#button_img").bind('touchstart', function(){ $("#button_img").attr("src","button_on.png"); }).bind('touchend', function(){ $("#button_img").attr("src","button_off.png"); }); }
This will work without any framework on any device that supports touch events. You could use something like Modernizr to do this test and if the device does not support touch events, bind to the regular desktop events.
When you use touchstart
/touchend
/touchmove
you get some interesting information, for instance how many touches are occurring at once, so you can detect if the user is scrolling or attempting to zoom.
UPDATE
Since the event
object inside an event handler differs for touch events and mouse events, if you want to know the coordinates of the event either way, you can do something like this (the example below assumes Modernizr has been loaded):
//determine which events to use var startEventType = 'mousedown', endEventType = 'mouseup'; if (Modernizr.touch === true) { startEventType = 'touchstart'; endEventType = 'touchend'; } //bind to determined event(s) $("#button_img").bind(startEventType, function(event) { //determine where to look for pageX by the event type var pageX = (startEventType === 'mousedown') ? event.pageX : event.originalEvent.touches[0].pageX; ... })...
UPDATE
I was looking this over and it seems like you don't need to detect the event type before binding the event handler:
//bind to determined event(s) $("#button_img").bind('mousedown touchstart', function(event) { //determine where to look for pageX by the event type var pageX = (event.type.toLowerCase() === 'mousedown') ? event.pageX : event.originalEvent.touches[0].pageX; ... })...
If you are worried about receiving both events in quick succession you could use a timeout to throttle the event handler:
//create timer var timer = null; //bind to determined event(s) $("#button_img").bind('mousedown touchstart', function(event) { //clear timer clearTimeout(timer); //set timer timer = setTimeout(function () { //determine where to look for pageX by the event type var pageX = (event.type.toLowerCase() === 'mousedown') ? event.pageX : event.originalEvent.touches[0].pageX; ... }, 50); })...
Note: You can force mousedown
and touchstart
events in quick succession with developer tools but I'm not sure about the real world use case here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With