Context Menu Example with jQuery Mobile

This post is more than 2 years old.

Yesterday a reader asked me about building context menu support for images within a jQuery Mobile operation. Turns out it's pretty easy. Obviously there is no such thing as a right-click menu on a touch device. That being said - the convention that most mobile applications use is a "taphold" listener. You touch the item with your finger and wait. In a second or two, the context menu pops up. The taphold event is trivial to use in jQuery Mobile (with a caveat I'll get to in a second), but what isn't as trivial is deciding what UI to use. jQuery Mobile will - soon - have a popup UI item. For now though I decided on the excellent SimpleDialog2 plugin by JTSage. Let's look at an example.

I've taken a few simple images and embedded them into the page. Note that each employs a class, touchableImage.

In the code block at the bottom, I register an event listener for the taphold event and fire off a call to the SimpleDialog2 control. I won't go into a lot of detail over the options, use the link above for details, but I basically wanted a non-modal window with a set of options for the image. (For now those links don't actually do anything, but you get the idea.) You can demo this yourself below. Remember that if you are not on a touch device, you're screwed, unless you use Chrome which allows you to emulate touch events now.

Here's a quick screen shot so you can see it in action.

Ok, if you want to stop reading now, you can. What follows is an interesting issue I discovered with iOS and tap events and how I debugged it using Adobe Shadow. Still here? Ok, I warned you.

One of the nice features of the SimpleDialog2 control is that you can auto-dismiss it if you click anywhere else in the DOM. The attribute, forceInput, when set to false, allows for easy dismissal of the control. I wanted to use that feature, and it worked great in Android, but on iOS, it did not. As soon as the dialog showed up it went away.

Here's where Shadow comes in. I was using Shadow to load the page and I remembered that I could use the console there too. I added a quick event listener for tap, went back to the iPad, and tested again. I saw my first tap event, I saw the taphold, and when I lifted my finger, I saw another tap event! Apparently this is (I believe) normal for iOS. You can see some discussion of this here.

So for now, I switched forceInput to true which requires the user to forcibly close the dialog, which isn't horrible I guess. I could - possibly - sniff for iOS/Android and toggle the field depending on the platform, but for now, I'm satisfied with it.

And once again - Shadow helps save the day. I know I sound like a broken record, and I know I work for Adobe, but damn, this is probably one of the best development tools I've used in a long time.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by kim_ras posted on 5/23/2012 at 8:45 PM

First of all thanks for the quick and nice sample!! It is exactly what I need in the lag of the next version Popup's.

One question which might be trivial but how do you reference to the object so you know what Image to "Send to Facebook"/"Send to Twitter" ...

Again thanks for our support

Comment 2 by Raymond Camden posted on 5/23/2012 at 11:41 PM

Basic idea would be:

The taphold event is passed the item you clicked on as this. Store a copy of that in a global variable.

Use event listeners for the 3 links. When clicked, fetch the global variable.

Does that make sense?

Comment 3 by Peter Doyle posted on 5/24/2012 at 9:21 AM


When i ran the demo on my S2 i first got the 'copy image' android dialogue open. Your context menu opened below that?

Bit unusual not sure if this just on my phone

Comment 4 by kim_ras posted on 5/24/2012 at 12:38 PM

HI Ray,
Yes it makes sense, I did see the global variable afterwards.. not a big fan of global variables for events, but easy enough to handle..
Thanks again

Comment 5 by Gareth Arch posted on 5/24/2012 at 6:12 PM

Is there a stopPropgation in Phonegap? So capture the event then stop the next ("tap") event firing after the taphold? This is the way I handle adding buttons to lists in Flex to stop the list "indexChanged" event firing when I've added a button on top of a list item.

Comment 6 by Raymond Camden posted on 5/24/2012 at 6:31 PM

+Peter Doyle: Shoot, I see that too on my One X. Let me investigate.

+Kim_ras: I hear ya - I think in this case it is ok though.

+Gareth: Remember - this isn't a PG issue but a web issue. PG is using webkit to render the content. So it isn't "Does PG support it", but can we do it in JS anyway. I'll try it on iOS and let you know. (As it stands, this isn't using PG anyway - just normal web pages.)

Comment 7 by Raymond Camden posted on 5/24/2012 at 6:39 PM

Peter/Gareth: stopProp worked great for the Android phone. I'm updating the Gist now (give it a few seconds). Thanks.

It did not - however - allow me to switch back the forceInput thing.

Comment 8 by gaurav posted on 9/3/2012 at 2:58 PM

how can we pass parameters to taphold event

Comment 9 by Raymond Camden posted on 9/3/2012 at 4:59 PM

You don't. Parameters (involving the event) are passed already. Provide more detail on what you are trying to do and maybe I can help.

Comment 10 by RQX posted on 12/4/2012 at 12:33 PM

It doesn't work on Windows Phone device!

Comment 11 by Raymond Camden posted on 12/4/2012 at 6:02 PM

It doesn't work how? Saying it doesn't work isn't helpful. Is it not rendering the menu in the right place? Did you add a console.log(...) to the taphold event to ensure it was firing at least? I need more details on -where- it fails.

Comment 12 by RQX posted on 12/5/2012 at 5:02 AM

On windows phone's IE browser, when taphold on a link/img/a etc. the default action is show a context menu, like "open in new tab"/"copy the link address". it won't show our simpdialog.

If you have a windows phone mobile, you can run your demo page and you will see this problem soon.


Comment 13 by Raymond Camden posted on 12/5/2012 at 6:40 AM

Hmpth, you got me there. Best I can recommend is posting to the jQuery Mobile forum and letting us know. I don't have access to a Windows Phone right now.

Comment 14 by pavan posted on 5/31/2013 at 2:03 PM

Pavan @(<a href="">pavanh</a>)

Very nice tutorial with efficent and detailed explaination, you can also check
this one <a href="">context menu</a>

Comment 15 by Raymond Camden posted on 5/31/2013 at 3:48 PM

@pavan: To be clear, that is for native development. This blog post is about how to do it for mobile web or hybrid apps.

Comment 16 by Max Bürgi posted on 4/8/2014 at 11:17 AM

I do jquery only for a couple of month.

I refer to

I ran this on firefox (no touchscreen) and emulated taphold by mousedown and liked it very much.

Then i ran it on my android cellphone. But the context dialog (right click) showed up first and then the simple dialog. Can happen the sd is completely hidden behind context dialog. how to supress firing context dialog just for this single event?

Comment 17 by Raymond Camden posted on 4/8/2014 at 7:18 PM

Hmm. You may want to try this:

Comment 18 by PrinceJava posted on 4/23/2014 at 7:16 PM

Mr. Raymond Camden, please helpe me, do you can telle why it does not work this code?
$ (document). ready (function () {
$ (". various".) on ("taphold", "img", function () {
    $ (this) fancybox ().;


Comment 19 by Raymond Camden posted on 4/23/2014 at 8:43 PM

No, I can't, because you didn't say how it wasn't working.

Comment 20 by Peter Hancox posted on 9/3/2014 at 10:44 AM

Is there any way to get the location of the taphold so that popup menu can be displayed relative to the touch location?

Comment 21 by Raymond Camden posted on 9/3/2014 at 3:07 PM

Not sure actually - try dumping the event object. It may contain the position.

Comment 22 by Raymond Camden posted on 9/3/2014 at 3:08 PM

First result via Google:

Comment 23 by Peter Hancox posted on 9/3/2014 at 3:36 PM

I'd tried examining the event object and experimented with different attributes but found nothing useful.

After posting this question, I found the post you mentioned and implemented that approach.

Was hoping for something a little less convoluted as I would have expected this information to be available on the event. It appears to be available in the original "touchstart" event as something like touches[0].clientX and clientY but doesn't make it through to the "taphold" event.

Thanks very much for your response (and the other articles of yours I've been learning from).


Comment 24 by Raymond Camden posted on 9/3/2014 at 3:51 PM

In theory - you could raise this as an issue with the jQM team as they added the taphold support for their framework. In theory. ;)