Using different jQuery event listeners for responsive interaction

The web is moving inexorably away from the desktop, and this is the cookbook you need to make responsive websites that adapt fluidly to mobile devices. All the innovative techniques at your fingertips in one handy volume.

(For more resources related to this topic, see here.)

Getting Started

First we want to create JavaScript that transforms a select form element into a button widget that changes the value of the form element when a button is pressed. So the first part of that task is to build a form with a select element.

How to do it

This part is simple; start by creating a new web page. Inside it, create a form with a select element. Give the select element some options. Wrap the form in a div element with the class select. See the following example. I have added a title just for placement.

<h2>Super awesome form element</h2>
<div class="select">
<form>
<select>
<option value="1">1</option>
<option value="Bar">Bar</option>
<option value="3">3</option>
</select>
</form>
</div>

Next, create a new CSS file called desktop.css and add a link to it in your header. After that, add a media query to the link for screen media and min-device-width:321px. The media query causes the browser to load the new CSS file only on devices with a screen larger than 320 pixels. Copy and paste the link to the CSS, but change the media query to screen and min-width:321px. This will help you test and demonstrate the mobile version of the widget on your desktop.

<link rel="stylesheet" media="screen and (min-device-width:321px)"
href="desktop.css" />
<link rel="stylesheet" media="screen and (min-width:321px)"
href="desktop.css" />

Next, create a script tag with a link to a new JavaScript file called uiFunctions.js and then, of course, create the new JavaScript file. Also, create another script element with a link to the recent jQuery library.

<script src = "http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script src = "uiFunctions.js"></script>

Now open the new JavaScript file uiFunctions.js in your editor and add instructions to do something on a document load.

$(document).ready(function(){
//Do something
});

The first thing your JavaScript should do when it loads is determine what kind of device it is on—a mobile device or a desktop. There are a few logical tests you can utilize to determine whether the device is mobile. You can test navigator.userAgent; specifically, you can use the .test() method, which in essence tests a string to see whether an expression of characters is in it, checks the window width, and checks whether the screen width is smaller than 600 pixels. For this article, let's use all three of them. Ultimately, you might just want to test navigator.userAgent. Write this inside the $(document).ready() function.

if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/
i.test(navigator.userAgent) || $(window).width()<600 ||
window.screen.width<600) {
//Do something for mobile
} else {
//Do something for the desktop
}

Inside, you will have to create a listener for the desktop device interaction event and the mouse click event, but that is later. First, let's write the JavaScript to create the UI widget for the select element. Create a function that iterates for each select option and appends a button with the same text as the option to the select div element. This belongs inside the $(document).ready() function, but outside and before the if condition.

The order of these is important.

$('select option').each(function(){
$('div.select').append('<button>'+$(this).html()+'</button>');
});

Now, if you load the page on your desktop computer, you will see that it generates new buttons below the select element, one for each select option. You can click on them, but nothing happens. What we want them to do is change the value of the select form element.

To do so, we need to add an event listener to the buttons inside the else condition. For the desktop version, you need to add a .click() event listener with a function. Inside the function, create two new variables, element and itemClicked. Make element equal the string button, and itemClicked, the jQuery object event target, or $(event.target). The next line is tricky; we're going to use the .addClass() method to add a selected class to the element variable :nth-child(n). Also, the n of the :nth-child(n) should be a call to a function named .eventAction(), to which we will add the integer 2. We will create the function next.

$('button').click(function(){
var element = 'button';
var itemClicked = $(event.target);
$(element+':nth-child(' + (eventAction(itemClicked,element) + 2) +
')').addClass('selected');
});

Next, outside the $(document).ready() function, create the eventAction() function. It will receive the variables itemClicked and element. The reason we make this function is because it performs the same functions for both the desktop click event and the mobile tap or long tap events.

function eventAction(itemClicked,element){
//Do something!
};

Inside the eventAction() function, create a new variable called choiceAction. Make choiceAction equal to the index of the element object in itemClicked, or just take a look at the following code:

var choiceAction = $(element).index(itemClicked);

Next, use the .removeClass() method to remove the selected class from the element object.

$(element).removeClass('selected');

There are only two more steps to complete the function. First, add the selected attribute to the select field option using the .eq() method and the choiceAction variable. Finally, remember that when the function was called in the click event, it was expecting something to replace the n in :nth-child(n); so end the function by returning the value of the choiceAction variable.

$('select option').eq(choiceAction).attr('selected','selected');
return choiceAction;

That takes care of everything but the mobile event listeners. The button style will be added at the end of the article. See how it looks in the following screenshot:

This will be simple. First, using jQuery's $.getScript() method, add a line to retrieve the jQuery library in the first if condition where we tested navigator.userAgent and the screen sizes to see whether the page was loaded into the viewport of a mobile device. The jQuery Mobile library will transform the HTML into a mobile, native-looking app.

$.getScript("http://code.jquery.com/mobile/1.2.0/
jquery.mobile-1.2.0.min.js");

The next step is to copy the desktop's click event listener, paste it below the $.getScript line, and change some values. Replace the .click() listener with a jQuery Mobile event listener, .tap() or .taphold(), change the value of the element variable to the string .uti-btn, and append the daisy-chained .parent().prev() methods to the itemClicked variable value, $(event.target). Replace the line that calls the eventAction() function in the :nth-child(n) selector with a more simple call to eventAction(), with the variables itemClicked and element.

$('button').click(function(){
var element = '.ui-btn';
var itemClicked = $(event.target).parent().prev();
eventAction(itemClicked,element);
});

When you click on the buttons to update the select form element in the mobile device, you will need to instruct jQuery Mobile to refresh its select menu. jQuery Mobile has a method to refresh its select element.

$('select').selectmenu("refresh",true);

That is all you need for the JavaScript file. Now open the HTML file and add a few things to the header. First, add a style tag to make the select form element and .ui-select hidden with the CSS display:none;. Next, add links to the jQuery Mobile stylesheets and desktop.css with a media query for media screen and max-width: 600px; or max-device-width:320px;.

<style>
select,.ui-select{display:none;}
</style>
<link rel="stylesheet" media="screen and (max-width:600px)"
href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css">
<link rel="stylesheet" media="screen and (min-width:600px)"
href="desktop.css" />

When launched on a mobile device, the widget will look like this:

Then, open the desktop.css file and create some style for the widget buttons. For the button element, add an inline display, padding, margins, border radius, background gradient, box shadow, font color, text shadow, and a cursor style.

button {
display:inline;
padding:8px 15px;
margin:2px;
border-top:1px solid #666;
border-left:1px solid #666;
border-bottom:1px solid #333;
border-right:1px solid #333;
border-radius:5px;
background: #7db9e8; /* Old browsers */
background:-moz-linear-gradient(top, #7db9e8 0%,#207cca 49%,#2989d8
50%,#1e5799 100%); /* FF3.6+ */
background:-webkit-gradient(linear,left top,left bottom,
color-stop(0%,#7db9e8), color-stop(49%,#207cca),
color-stop(50%,#2989d8), color-stop(100%,#1e5799)); /*
Chrome,Safari4+ */

background:-webkit-linear-gradient(top,#7db9e8 0%,#207cca 49%,
#2989d8 50%,#1e5799 100%);
/* Chrome10+,Safari5.1+ */
background:-o-linear-gradient(top,#7db9e8 0%,#207cca 49%,#2989d8
50%,#1e5799 100%); /*
Opera 11.10+ */
background:-ms-linear-gradient(top,#7db9e8 0%,#207cca 49%,#2989d8
50%,#1e5799 100%); /* IE10+ */
background:linear-gradient(to bottom,#7db9e8 0%,#207cca 49%,#2989d8
50%,#1e5799 100%); /* W3C */
filter:progid:DXImageTransform.Microsoft.gradient
( startColorstr='#7db9e8', endColorstr='#1e5799',GradientType=0 );
/* IE6-9 */
color:white;
text-shadow: -1px -1px 1px #333;
box-shadow: 1px 1px 4px 2px #999;
cursor:pointer;
}

Finally, add CSS for the .selected class that was added by the JavaScript. This CSS will change the button to look as if the button has been pressed in.

.selected{
border-top:1px solid #333;
border-left:1px solid #333;
border-bottom:1px solid #666;
border-right:1px solid #666;
color:#ffff00;
box-shadow:inset 2px 2px 2px 2px #333;
background: #1e5799; /* Old browsers */
background:-moz-linear-gradient(top,#1e5799 0%,#2989d8 50%,
#207cca 51%, #7db9e8 100%); /* FF3.6+ */
background:-webkit-gradient(linear,left top,left bottom,
color-stop(0%,#1e5799),color-stop(50%,#2989d8),
color-stop(51%,#207cca),color-stop(100%,#7db9e8)); /*
Chrome,Safari4+ */
background:-webkit-linear-gradient(top, #1e5799 0%,#2989d8 50%,
#207cca 51%,#7db9e8 100%); /* Chrome10+,Safari5.1+ */
background:-o-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca
51%,#7db9e8 100%); /* Opera 11.10+ */
background:-ms-linear-gradient(top, #1e5799 0%,#2989d8
50%,#207cca 51%,#7db9e8 100%); /* IE10+ */
background: linear-gradient(to bottom, #1e5799 0%,#2989d8
50%,#207cca 51%,#7db9e8 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient
( startColorstr='#1e5799', endColorstr='#7db9e8',GradientType=0 ); /*
IE6-9 */
}

How it works

This uses a combination of JavaScript and media queries to build a dynamic HTML form widget. The JavaScript tests the user agent and screen size to see if it is a mobile device and responsively delivers a different event listener for the different device types. In addition to that, the look of the widget will be different for different devices.

Summary

In this article we learned how to create an interactive widget that uses unobtrusive JavaScript, which uses different event listeners for desktop versus mobile devices. This article also helped you build your own web app that can transition between the desktop and mobile versions without needing you to rewrite your entire JavaScript code.

Resources for Article :


Further resources on this subject:


Books to Consider

comments powered by Disqus
X

An Introduction to 3D Printing

Explore the future of manufacturing and design  - read our guide to 3d printing for free