Wednesday, 25 September 2013

100 keyboard shortcuts

100 keyboard shortcuts
*************** *************** ********************


* CTRL+C (Copy)
* CTRL+X (Cut)
* CTRL+V (Paste)
* CTRL+Z (Undo)
* DELETE (Delete)
* SHIFT+DELETE (Delete the selected item
permanently without placing the item in the
Recycle Bin)
* CTRL while dragging an item (Copy the
selected item)
* CTRL+SHIFT while dragging an item (Create a
shortcut to the selected item)
* F2 key (Rename the selected item)
* CTRL+RIGHT ARROW (Move the insertion
point to the beginning of the next word)
* CTRL+LEFT ARROW (Move the insertion point
to the beginning of the previous word)
* CTRL+DOWN ARROW (Move the insertion
point to the beginning of the next paragraph)
* CTRL+UP ARROW (Move the insertion point
to the beginning of the previous paragraph)
* CTRL+SHIFT with any of the arrow keys
(Highlight a block of text)
* SHIFT with any of the arrow keys (Select
more than one item in a window or on the
desktop, or select text in a document)
* CTRL+A (Select all)
* F3 key (Search for a file or a folder)
* ALT+ENTER (View the properties for the
selected item)
* ALT+F4 (Close the active item, or quit the
active program)
* ALT+ENTER (Display the properties of the
selected object)
* ALT+SPACEBAR (Open the shortcut menu for
the active window)
* CTRL+F4 (Close the active document in
programs that enable you to have multiple
documents open simultaneously)
* ALT+TAB (Switch between the open items)
* ALT+ESC (Cycle through items in the order
that they had been opened)
* F6 key (Cycle through the screen elements in
a window or on the desktop)
* F4 key (Display the Address bar list in My
Computer or Windows Explorer)
* SHIFT+F10 (Display the shortcut menu for
the selected item)
* ALT+SPACEBAR (Display the System menu for
the active window)
* CTRL+ESC (Display the Start menu)
* ALT+Underlined letter in a menu name
(Display the corresponding menu)
* Underlined letter in a command name on an
open menu (Perform the corresponding
command)
* F10 key (Activate the menu bar in the active
program)
* RIGHT ARROW (Open the next menu to the
right, or open a submenu)
* LEFT ARROW (Open the next menu to the
left, or close a submenu)
* F5 key (Update the active window)
* BACKSPACE (View the folder one level up in
My Computer or Windows Explorer)
* ESC (Cancel the current task)
* SHIFT when you insert a CD-ROM into the CD-
ROM drive (Prevent the CD-ROM from
automatically playing)
Dialog Box Keyboard Shortcuts
--------------- --------------- --------------- ----------
* CTRL+TAB (Move forward through the tabs)
* CTRL+SHIFT+TAB (Move backward through
the tabs)
* TAB (Move forward through the options)
* SHIFT+TAB (Move backward through the
options)
* ALT+Underlined letter (Perform the
corresponding command or select the
corresponding option)
* ENTER (Perform the command for the active
option or button)
* SPACEBAR (Select or clear the check box if
the active option is a check box)
* Arrow keys (Select a button if the active
option is a group of option buttons)
* F1 key (Display Help)
* F4 key (Display the items in the active list)
* BACKSPACE (Open a folder one level up if a
folder is selected in the Save As or Open
dialog box)
Microsoft Natural Keyboard Shortcuts
--------------- --------------- --------------- ----------
* Windows Logo (Display or hide the Start
menu)
* Windows Logo+BREAK (Display the System
Properties dialog box)
* Windows Logo+D (Display the desktop)
* Windows Logo+M (Minimize all of the
windows)
* Windows Logo+SHIFT+M (Restore the
minimized windows)
* Windows Logo+E (Open My Computer)
* Windows Logo+F (Search for a file or a
folder)
* CTRL+Windows Logo+F (Search for
computers)
* Windows Logo+F1 (Display Windows Help)
* Windows Logo+ L (Lock the keyboard)
* Windows Logo+R (Open the Run dialog
box)
* Windows Logo+U (Open Utility Manager)
Accessibility Keyboard Shortcuts
--------------- --------------- --------------- ----------
* Right SHIFT for eight seconds (Switch
FilterKeys either on or off)
* Left ALT+left SHIFT+PRINT SCREEN (Switch
High Contrast either on or off)
* Left ALT+left SHIFT+NUM LOCK (Switch the
MouseKeys either on or off)
* SHIFT five times (Switch the StickyKeys either
on or off)
* NUM LOCK for five seconds (Switch the
ToggleKeys either on or off)
* Windows Logo +U (Open Utility Manager)
Windows Explorer Keyboard Shortcuts
--------------- --------------- --------------- ----------
* END (Display the bottom of the active
window)
* HOME (Display the top of the active window)
* NUM LOCK+Asterisk sign (*) (Display all of
the subfolders that are under the selected
folder)
* NUM LOCK+Plus sign (+) (Display the
contents of the selected folder)
* NUM LOCK+Minus sign (-) (Collapse the
selected folder)
* LEFT ARROW (Collapse the current selection
if it is expanded, or select the parent folder)
* RIGHT ARROW (Display the current selection
if it is collapsed, or select the first subfolder)
Shortcut Keys for Character Map
--------------- --------------- --------------- ----------
* After you double-click a character on the
grid of characters, you can move through the
grid by using the keyboard shortcuts:
* RIGHT ARROW (Move to the right or to the
beginning of the next line)
* LEFT ARROW (Move to the left or to the end
of the previous line)
* UP ARROW (Move up one row)
* DOWN ARROW (Move down one row)
* PAGE UP (Move up one screen at a time)
* PAGE DOWN (Move down one screen at a
time)
* HOME (Move to the beginning of the line)
* END (Move to the end of the line)
* CTRL+HOME (Move to the first character)
* CTRL+END (Move to the last character)
* SPACEBAR (Switch between Enlarged and
Nor mal mode when a character is selected)
Microsoft Management Console (MMC) Main
Window Keyboard Shortcuts
--------------- --------------- --------------- ----------
* CTRL+O (Open a saved console)
* CTRL+N (Open a new console)
* CTRL+S (Save the open console)
* CTRL+M (Add or remove a console item)
* CTRL+W (Open a new window)
* F5 key (Update the content of all console
windows)
* ALT+SPACEBAR (Display the MMC window
menu)
* ALT+F4 (Close the console)
* ALT+A (Display the Action menu)
* ALT+V (Display the View menu)
* ALT+F (Display the File menu)
* ALT+O (Display the Favorites menu)
MMC Console Window Keyboard Shortcuts
--------------- --------------- --------------- ----------
* CTRL+P (Print the current page or active
pane)
* ALT+Minus sign (-) (Display the window
menu for the active console window)
* SHIFT+F10 (Display the Action shortcut
menu for the selected item)
* F1 key (Open the Help topic, if any, for the
selected item)
* F5 key (Update the content of all console
windows)
* CTRL+F10 (Maximize the active console
window)
* CTRL+F5 (Restore the active console
window)
* ALT+ENTER (Display the Properties dialog
box, if any, for the selected item)
* F2 key (Rename the selected item)
* CTRL+F4 (Close the active console window.
When a console has only one console
window, this shortcut closes the console)
Remote Desktop Connection Navigation
--------------- --------------- --------------- ----------
* CTRL+ALT+END (Open the m*cro$oft
Windows NT Security dialog box)
* ALT+PAGE UP (Switch between programs
from left to right)
* ALT+PAGE DOWN (Switch between programs
from right to left)
* ALT+INSERT (Cycle through the programs in
most recently used order)
* ALT+HOME (Display the Start menu)
* CTRL+ALT+BREAK (Switch the client
computer between a window and a full
screen)
* ALT+DELETE (Display the Windows menu)
* CTRL+ALT+Minus sign (-) (Place a snapshot
of the active window in the client on the
Terminal server clipboard and provide the
same functionality as pressing PRINT SCREEN
on a local computer.)
* CTRL+ALT+Plus sign (+) (Place a snapshot of
the entire client window area on the Terminal
server clipboard and provide the same
functionality as pressing ALT+PRINT SCREEN
on a local computer.)
Internet Explorer navigation
--------------- --------------- --------------- ----------
* CTRL+B (Open the Organize Favorites dialog
box)
* CTRL+E (Open the Search bar)
* CTRL+F (Start the Find utility)
* CTRL+H (Open the History bar)
* CTRL+I (Open the Favorites bar)
* CTRL+L (Open the Open dialog box)
* CTRL+N (Start another instance of the
browser with the same Web address)
* CTRL+O (Open the Open dialog box, the
same as CTRL+L)
* CTRL+P (Open the Print dialog box)
* CTRL+R (Update the current Web page)
* CTRL+W (Close the current window)

How Students Are Using The Internet For Studying

Does anyone out there remember actually having to go to the library to research for a paper? I remember having to order books from other libraries when I was in graduate school and -gasp- had to wait for them to be sent to me!

Annoying, right?

Even in that relatively short amount of time, we’ve been cultured to understand that we can learn from anything, anywhere, immediately. The landscape of researching and studying has changed quite a bit, hasn’t it? While I’m a little sad that there is no sourcing listed (and as such, I can’t cross check the information presented) the handy infographic below has taught me a few interesting things about current students’ online studying and research habits.

Did You Know?

  • Only 10% of students report using books from libraries to help them study
  • 100% of students report using Wikipedia to study
  • 80% of students report using social networks to help them study
  • 55% of students report using online services to help them write their papers
how-students-learn-today_51a483788c8ff

Friday, 13 September 2013

The Best Tools to Easily Perform Remote Tech Support

computer-phone-frustration

“Help, my computer is broken!” comes the phone call yet again. If you’re stuck playing tech support for family or friends, there are many free tools that allow you to remotely access the other person’s computer and fix it.

There are a million and one remote tech support options out there. We’ll look at the best ones here, whether you need to walk them through downloading one over the phone or want to set up remote access ahead of time.

TeamViewer

TeamViewer is the remote support tool of choice for many geeks. It can be used in several different ways. You can direct your partner to download the TeamViewer QuickSupport application, which can run without administrator access or any system configuration. It will give them a session ID and password that they can give to you, allowing you to easily remotely connect from your TeamViewer program. There’s no setup process here — just download the appropriate program and double-click it to launch it.



You could also opt to set up unattended access after installing the full TeamViewer client, giving you permanent remote access to the computer without the remote user having to give you any passwords or confirm anything. As long as their computer is on, you’ll be able to access it remotely. If you want to do preventative maintenance or fix their computer while they’re not around, this is a convenient option.


TeamViewer is also cross-platform, so you can use it to troubleshoot a Mac or troubleshoot your parents’ Windows computer from your Linux PC. You can even remotely connect from an Android or iOS device. We’ve taken an in-depth look at TeamViewer in the past.

Windows Remote Assistance

Windows has a built-in remote assistance feature designed for just this situation. While only Professional editions of Windows can use the remote desktop server software, every version of Windows can send a remote assistance invitation and invite someone else to assist with their computers. This can be a convenient option because it’s already installed on the remote Windows computer, so you don’t have to walk the person through installing anything.

To use this feature, tell the other person to launch Windows Remote Assistance — either by opening the Start menu, typing Windows Remote, and pressing Enter or navigating to Start -> All Programs -> Maintenance -> Windows Remote Assistance.

They’ll need to use the Invite someone you trust to help you option and then select Easy Connect, which will give them a password.

Note that Easy Connect won’t always be available — if it isn’t, the remote user will have to create an invitation file using the Windows Remote Assistance app and send it to you.


You’ll need to open the Windows Remote Assistance application on your computer, choose Help someone who has invited you, select Easy Connect, and enter the password. If Easy Connect isn’t available, you’ll have to provide the invitation file.

After they approve your connection, you’ll be able to see and control their desktop remotely so you can begin cleaning it of viruses, removing toolbars, or dealing with whatever other problems are there. Read our in-depth walkthrough to Windows Remote Assistance for more information.


Windows Remote Assistance can help in a pinch, but it’s not the ideal permanent solution. If you find yourself needing to connect regularly, there’s no way to connect without having the other person open the Remote Assistance app and tell you the password. If a solution that allows you to remotely log in without pestering the other person is ideal, set up TeamViewer or a similar program instead.

Chrome Remote Desktop

There’s a good chance both you and your recipient already have Google’s Chrome browser installed on your computers. If you do, you can use Chrome Remote Desktop app to connect to them remotely.
To do this, both you and the other person will need to have the Chrome Remote Desktop app installed. The other person will need to open the Chrome Remote Desktop app from their new tab page and click Enable remote connections.

They’ll then need to click the Share button to share their computer with someone, which will give them an access code.

Once they provide you with the access code, you’ll be able to open the Chrome Remote Desktop app, click the Access button, and enter the access code. You’ll then be connected to their computer.


You could also try setting up a PIN for permanent remote access. Like TeamViewer, this tool is cross-platform and also works on Mac, Linux, and Chrome OS. It will also likely be more robust than Windows Remote Assistance, as it shouldn’t fail — unlike the Easy Connect option in Windows Remote Assistance.
We’ve previously covered using Google Chrome to remotely access your computers.

More Options

Sure, there are more options, but they’re not all ideal. Skype has a screen-sharing feature, which is convenient because so many people have Skype installed — but Skype’s screen sharing feature doesn’t allow you to control the PC remotely, so you’d have to walk the person through clicking on the correct things.

LogMeIn is another remote desktop solution that’s occasionally used, but it’s much more focused on paid solutions for businesses. TeamViewer seems to be a better option for the average geek.
You could try enabling Remote Desktop in Windows for permanent remote access, but that would require the other person have a Professional version of Windows or better — not too common with average users. This would also require port forwarding to make the machine accessible from the Internet.


You could also set up a VNC server, which is the manual way of doing this. A VNC server is essentially a free alternative to Windows Remote Desktop, so you could install it on any edition of Windows. However, VNC servers are just a server — you have to manually forward ports and ensure it’s remotely accessible yourself. This is much more painful than just using one of the above solutions, which handles the connection setup itself without any messy port-forwarding.

Ultimately, you’re probably better off with TeamViewer. It’s easy to use, whether you’re trying to get the other person to download the QuickSupport application — no administrator access needed — and give you a password or configure remote, unattended access so you can always access their PC. The remote assistance features built into Windows and Chrome could also be useful as they should be quick to set up if you’re already using Windows or Chrome.

If you constantly find yourself having to perform remote tech support for the same people, you may want to get your relatives off of Windows entirely. Consider giving them a Mac, Chromebook, Linux PC, iPad, Android tablet — anything that’s more difficult to mess up than a good old-fashioned Windows desktop.

How To Troubleshoot Internet Connection Problems

hand-plugging-in-ethernet-cable

Internet connection problems can be frustrating. Rather than mashing F5 and desperately trying to reload your favorite website when you experience a problem, here are some ways you can troubleshoot the problem and identify the cause.

Ensure you check the physical connections before getting too involved with troubleshooting. Someone could have accidentally kicked the router or modem’s power cable or pulled an Ethernet cable out of a socket, causing the problem.
Image Credit: photosteve101 on Flickr

Ping

One of the first things to try when your connection doesn’t seem to be working properly is the ping command. Open a Command Prompt window from your Start menu and run a command like ping google.com or ping howtogeek.com.

This command sends several packets to the address you specify. The web server responds to each packet it receives. In the command below, we can see that everything is working fine – there’s 0% packet loss and the time each packet takes is fairly low.


If you see packet loss (in other words, if the web server didn’t respond to one or more of the packets you sent), this can indicate a network problem. If the web server sometimes takes a much longer amount of time to respond to some of your other packets, this can also indicate a network problem. This problem can be with the website itself (unlikely if the same problem occurs on multiple websites), with your Internet service provider, or on your network (for example, a problem with your router).

Note that some websites never respond to pings. For example, ping microsoft.com will never results in any responses.

Problems With a Specific Website

If you’re experiencing issues accessing websites and ping seems to be working properly, it’s possible that one (or more) websites are experiencing problems on their end.

To check whether a website is working properly, you can use Down For Everyone Or Just For Me, a tool that tries to connect to websites and determine if they’re actually down or not. If this tool says the website is down for everyone, the problem is on the website’s end.


If this tool says the website is down for just you, that could indicate a number of things. It’s possible that there’s a problem between your computer and the path it takes to get to that website’s servers on the network. You can use the traceroute command (for example, tracert google.com) to trace the route packets take to get to the website’s address and see if there are any problems along the way. However, if there are problems, you can’t do much more than wait for them to be fixed.

Modem & Router Issues

If you are experiencing problems with a variety of websites, they may be caused by your modem or router. The modem is the device that communicates with your Internet service provider, while the router shares the connection among all the computers and other networked devices in your household. In some cases, the modem and router may be the same device.

Take a look at the router. If green lights are flashing on it, that’s normal and indicates network traffic. If you see a steady, blinking orange light, that generally indicates the problem. The same applies for the modem – a blinking orange light usually indicates a problem.


If the lights indicate that either devices are experiencing a problem, try unplugging them and plugging them back in. This is just like restarting your computer. You may also want to try this even if the lights are blinking normally – we’ve experienced flaky routers that occasionally needed to be reset, just like Windows computers. Bear in mind that it may take your modem a few minutes to reconnect to your Internet service provider.

If you still experience problems, you may need to perform a factory reset on your router or upgrade its firmware. To test whether the problem is really with your router or not, you can plug your computer’s Ethernet cable directly into your modem. If the connection now works properly, it’s clear that the router is causing you problems.
Image Credit: Bryan Brenneman on Flickr

Issues With One Computer

If you’re only experiencing network problems on one computer on your network, it’s likely that there’s a software problem with the computer. The problem could be caused by a virus or some sort of malware or an issue with a specific browser.

Do an antivirus scan on the computer and try installing a different browser and accessing that website in the other browser. There are lots of other software problems that could be the cause, including a misconfigured firewall.

DNS Server Problems

When you try to access Google.com, your computer contacts its DNS server and asks for Google.com’s IP address. The default DNS servers your network uses are provided by your Internet service provider, and they may sometimes experience problems.

You can try accessing a website at its IP address directly, which bypasses the DNS server. For example, plug this address into your web browser’s address bar to visit Google directly:
http://74.125.224.72


If the IP address method works but you still can’t access google.com, it’s a problem with your DNS servers. Rather than wait for your Internet service provider to fix the problem, you can try using a third-party DNS server like OpenDNS or Google Public DNS.


Ultimately, most connection problems you’ll run into are probably someone else’s problem – you can’t necessarily solve them yourself. Often, the only thing you can do is wait for your Internet service provider or a specific website to fix the problem you’re experiencing. (However, restarting a flaky router can solve lots of problems.)

If you are experiencing problems, you can always try calling your Internet service provider on the phone – you’re paying them for this service, after all. They will also be able to tell you whether it’s a problem that other users are also having — or whether it’s a problem on your end.

How to Sync External Folders with Your SkyDrive

image

Microsoft launched its new SkyDrive desktop app which is set to compete head-to-head with Dropbox and Google Drive. Here’s how to sync folders that are outside of your SkyDrive folder.

Using a Reparse Point

Known as the Soft Link to some, a Symbolic Link is the most common form of reparse point. Luckily for us Windows Vista and later include a command line utility, called mklink, which can be used to manage symbolic links. In order to create a symbolic link we first need to find your SkyDrive folder which, buy default, is located at:
C:\Users\”Your Username”\SkyDrive
This is also known as the %userprofile% environment variable, which makes it extra easy to create a symbolic link. So go ahead and fire up a administrative command prompt.

Now we need to use mklink to create a symbolic link, the syntax to link to a folder is:
mklink /d <link> <target>
For files we don’t need the “/d” switch so we can just use:
mklink <link> <target>
But as an added bonus we can use our environment variable, so we can do something like this:
mklink /d “%userprofile%\SkyDrive\Music” C:\Music

Above I created a symbolic link that points to the Music folder on the root of my “C” drive. This means that any files I put into that folder will be automatically uploaded to my SkyDrive, you can check this by looking at your SkyDrive.

As you can see my symlink is there and functioning just as we expected. That’s all there is to it, happy symlinking

Wednesday, 11 September 2013

Dynamically removing/ replacing an external JavaScript or CSS file

Any external JavaScript or CSS file, whether added manually or dynamically, can be removed from the page. The end result may not be fully what you had in mind, however. I'll talk about this a little later.

Dynamically removing an external JavaScript or CSS file

To remove an external JavaScript or CSS file from a page, the key is to hunt them down first by traversing the DOM, then call DOM's removeChild() method to do the hit job. A generic approach is to identify an external file to remove based on its file name, though there are certainly other approaches, such as by CSS class name. With that in mind, the below function removes any external JavaScript or CSS file based on the file name entered:

function removejscssfile(filename, filetype){
 var targetelement=(filetype=="js")? "script" : (filetype=="css")? "link" : "none" 
//determine element type to create nodelist from
 var targetattr=(filetype=="js")? "src" : (filetype=="css")? "href" : "none" 
//determine corresponding attribute to test for
 var allsuspects=document.getElementsByTagName(targetelement)
 for (var i=allsuspects.length; i>=0; i--){ 
//search backwards within nodelist for matching elements to remove
  if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!=null 
&& allsuspects[i].getAttribute(targetattr).indexOf(filename)!=-1)
   allsuspects[i].parentNode.removeChild(allsuspects[i]) 
//remove element by calling parentNode.removeChild()
 }
}

removejscssfile("somescript.js", "js") 
//remove all occurences of "somescript.js" on page
removejscssfile("somestyle.css", "css") 
//remove all occurences "somestyle.css" on page

The function starts out by creating a collection out of either all "SCRIPT" or "LINK" elements on the page depending on the desired file type to remove. The corresponding attribute to look at also changes accordingly ("src" or "href" attribute). Then, the function sets out to loop through the gathered elements backwards to see if any of them match the name of the file that should be removed. There's a reason for the reversed direction- if/whenever an identified element is deleted, the collection collapses by one element each time, and to continue to cycle through the new collection correctly, reversing the direction does the trick (it may encounter undefined elements, hence the first check for allsuspects[i] in the if statement). Now, to delete the identified element, the DOM method parentNode.removeChild() is called on it.

So what actually happens when you remove an external JavaScript or CSS file? Perhaps not entirely what you would expect actually. In the case of JavaScript, while the element is removed from the document tree, any code loaded as part of the external JavaScript file remains in the browser's memory. That is to say, you can still access variables, functions etc that were added when the external file first loaded (at least in IE7 and Firefox 2.x). If you're looking to reclaim browser memory by removing an external JavaScript, don't rely on this operation to do all your work. With external CSS files, when you remove a file, the document does reflow to take into account the removed CSS rules, but unfortunately, not in IE7 (Firefox 2.x and Opera 9 do).

Demo: "myscript.js" source:
var petname="Spotty"
alert("Pet Name: " + petname)
"mystyle.css" source:
#demotable td{
background-color: lightyellow;
}

#demotable b{
color: blue;
}

Dynamically replacing an external JavaScript or CSS file

Replacing an external JavaScript or CSS file isn't much different than removing one as far as the process goes. Instead of calling parentNode.removeChild(), you'll be using parentNode.replaceChild() to do the bidding instead:

function createjscssfile(filename, filetype){
 if (filetype=="js"){ //if filename is a external JavaScript file
  var fileref=document.createElement('script')
  fileref.setAttribute("type","text/javascript")
  fileref.setAttribute("src", filename)
 }
 else if (filetype=="css"){ //if filename is an external CSS file
  var fileref=document.createElement("link")
  fileref.setAttribute("rel", "stylesheet")
  fileref.setAttribute("type", "text/css")
  fileref.setAttribute("href", filename)
 }
 return fileref
}

function replacejscssfile(oldfilename, newfilename, filetype){
 var targetelement=(filetype=="js")? "script" : (filetype=="css")? "link" : "none"
 //determine element type to create nodelist using
 var targetattr=(filetype=="js")? "src" : (filetype=="css")? "href" : "none" 
//determine corresponding attribute to test for
 var allsuspects=document.getElementsByTagName(targetelement)
 for (var i=allsuspects.length; i>=0; i--){
 //search backwards within nodelist for matching elements to remove
  if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!=null 
&& allsuspects[i].getAttribute(targetattr).indexOf(oldfilename)!=-1)
{
   var newelement=createjscssfile(newfilename, filetype)
   allsuspects[i].parentNode.replaceChild(newelement, allsuspects[i])
  }
 }
}

replacejscssfile("oldscript.js", "newscript.js", "js")
 //Replace all occurences of "oldscript.js" with "newscript.js"
replacejscssfile("oldstyle.css", "newstyle", "css")
 //Replace all occurences "oldstyle.css" with "newstyle.css"
 
Notice the helper function createjscssfile(), which is essentially just a duplicate of loadjscssfile() as seen on the previous page, but modified to return the newly created element instead of actually adding it to the page. It comes in handy when parentNode.replaceChild() is called in replacejscssfile() to replace the old element with the new. Some good news here- when you replace one external CSS file with another, all browsers, including IE7, will reflow the document automatically to take into account the new file's CSS rules.

Demo: "oldscript.js" source:
var petname="Spotty"
alert("Pet Name: " + petname)
"newscript.js" source:
var petname="Beauty"
alert("Pet Name: " + petname)
"oldstyle.css" source:
#demotable2 td{
background-color: lightyellow;
}

#demotable2 b{
color: blue;
}
"newstyle.css" source:
#demotable2 td{
background-color: lightblue;
}

#demotable2 b{
color: red;
}

Conclusion

So when is all this useful? Well, in today's world of Ajax and ever larger web applications, being able to load accompanying JavaScript/ CSS files asynchronously and on demand is not only handy, but in some cases, necessary. Have fun finding out what they are, or implementing the technique. :)

Dynamically loading an external JavaScript or CSS file

The conventional way to loading external JavaScript (ie: .js) and CSS (ie: .css) files on a page is to stick a reference to them in the HEAD section of your page, for example:
<head>
<script type="text/javascript" src="myscript.js"></script>
<link rel="stylesheet" type="text/css" href="main.css" />
</head>
Files that are called this way are added to the page as they are encountered in the page's source, or synchronously. For the most part, this setup meets our needs just fine, though in the world of synchronous Ajax design patterns, the ability to also fire up JavaScript/ CSS on demand is becoming more and more handy. In this tutorial, lets see how it's done.

Dynamically loading external JavaScript and CSS files

To load a .js or .css file dynamically, in a nutshell, it means using DOM methods to first create a swanky new "SCRIPT" or "LINK" element, assign it the appropriate attributes, and finally, use element.appendChild() to add the element to the desired location within the document tree. It sounds a lot more fancy than it really is. Lets see how it all comes together:
function loadjscssfile(filename, filetype){
 if (filetype=="js"){ //if filename is a external JavaScript file
  var fileref=document.createElement('script')
  fileref.setAttribute("type","text/javascript")
  fileref.setAttribute("src", filename)
 }
 else if (filetype=="css"){ //if filename is an external CSS file
  var fileref=document.createElement("link")
  fileref.setAttribute("rel", "stylesheet")
  fileref.setAttribute("type", "text/css")
  fileref.setAttribute("href", filename)
 }
 if (typeof fileref!="undefined")
  document.getElementsByTagName("head")[0].appendChild(fileref)
}

loadjscssfile("myscript.js", "js") //dynamically load and add this .js file
loadjscssfile("javascript.php", "js") //dynamically load "javascript.php" as a JavaScript file
loadjscssfile("mystyle.css", "css") ////dynamically load and add this .css file
Demo: "myscript.js" source:
var petname="Spotty"
alert("Pet Name: " + petname)
"mystyle.css" source:
#demotable td{
background-color: lightyellow;
}

#demotable b{
color: blue;
}

Since external JavaScript and CSS files can technically end with any custom file extension (ie: "javascript.php"), the function parameter "filetype" lets you tell the script what file type to expect before loading. After that, the function sets out to create the element using the appropriate DOM methods, assign it the proper attributes, and finally, add it to the end of the HEAD section. Now, where the created file gets added is worth elaborating on:

document.getElementsByTagName("head")[0].appendChild(fileref)
By referencing the HEAD element of the page first and then calling appendChild(), this means the newly created element is added to the very end of the HEAD tag. Furthermore, you should be aware that no existing element is harmed in the adding of the new element- that is to say, if you call loadjscssfile("myscript.js", "js") twice, you now end up with two new "SCRIPT" elements both pointing to the same JavaScript file. This is problematic only from an efficiency standpoint, as you'll be adding redundant elements to the page and using unnecessary browser memory in the process. A simple way to prevent the same file from being added more than once is to keep track of the files added by loadjscssfile(), and only load a file if it's new:
var filesadded="" //list of files already added

function checkloadjscssfile(filename, filetype){
 if (filesadded.indexOf("["+filename+"]")==-1){
  loadjscssfile(filename, filetype)
  filesadded+="["+filename+"]" //List of files added in the form "[filename1],[filename2],etc"
 }
 else
  alert("file already added!")
}

checkloadjscssfile("myscript.js", "js") //success
checkloadjscssfile("myscript.js", "js") //redundant file, so file not added
Here I'm just crudely detecting to see if a file that's set to be added already exists within a list of added files' names stored in variable filesadded before deciding whether to proceed or not.

Tuesday, 10 September 2013

Handling runtime errors in JavaScript using try/catch/finally



                                    Error handling, like many aspects of JavaScript, has been maturing since the dark ages of Netscape and IE4. No longer are you forced to settle for what the browser throws in your face in an event of a JavaScript error, but instead can take the matter into your own hands. The try/catch/finally statement of JavaScript lets you dip your toes into error prune territory and "reroute" when a JavaScript "exception" is encountered. Along with other defensive coding techniques such as Object detection and the onError event, try/catch/finally adds the ability to navigate around certain errors that in the past would have instantly stopped your script at its tracks. No more!

try/catch/finally

try/catch/finally are so called exception handling statements in JavaScript. An exception is an error that occurs at runtime due to an illegal operation during execution. Examples of exceptions include trying to reference an undefined variable, or calling a non existent method. This versus syntax errors, which are errors that occur when there is a problem with your JavaScript syntax. Consider the following examples of syntax errors versus exceptions:
  • alert("I am missing a closing parenthesis //syntax error
  • alert(x) //exception assuming "x" isn't defined yet
  • undefinedfunction() //exception
try/catch/finally lets you deal with exceptions gracefully. It does not catch syntax errors, however (for those, you need to use the onerror event). Normally whenever the browser runs into an exception somewhere in a JavaScript code, it displays an error message to the user while aborting the execution of the remaining code. You can put a lid on this behaviour and handle the error the way you see fit using try/catch/finally. At its simplest you'd just use try/catch to try and run some code, and in the event of any exceptions, suppress them:

try{
 undefinedfunction()
}
catch(e){
 //catch and just suppress error
}

Assuming undefinedfunction() is undefined, when the browser runs the above, no errors will be shown. The syntax for try/catch/finally is a try clause followed by either a catch or finally clause (at least one or both of them). The catch clause if defined traps any errors that has occurred from try, and is indirectly passed the error object that contains additional info about the error. Lets see a slightly more complex example now:

try{
 undefinedfunction()
 alert('I guess you do exist')
}
catch(e){
 alert('An error has occurred: '+e.message)
}

 
Demo:

Click on the above button, and notice how only "An Error has occurred" alert pops up, but not "I guess you do exist". This tells us that when try encounters an error, it immediately skips any remaining code inside it and goes straight to catch. The default error message is obviously suppressed, though you can still retrieve this information by accessing the Error object that gets indirectly passed into catch. We'll look at the Error object in detail on the next page.

There's another clause, finally, that if defined will be executed regardless of whether an error occurs in the try clause proceeding it:

try{
 undefinedfunction()
 alert('I guess you do exist')
}
catch(e){
 alert('An error has occurred: '+e.message)
}
finally{
 alert('I am alerted regardless of the outcome above')
}

finally can be useful when you need to "clean up" after some code inside try. While it's true finally will always be executed if defined, certain statements inside try such as continue, break, return, or when an error has occurred and there is no catch clause will all cause finally to be executed immediately thereafter. In the following example, the value "5" is alerted, since control is handed over to finally when i reaches 5 inside try:

try{
 for (var i=0; i<10; i++){
  if (i==5)
   break
  x=i
 }
}
finally{
 alert(i) //alerts 5
}

Nested try/catch/finally statements

As a reminder, try should never be defined just by itself, but always followed by either catch, finally, or both. Within each clause, you can define additional try/catch/finally statements following the same aforementioned rule. Take the instance where an error has occurred within the catch clause- defining an additional try/catch statement inside it takes care of it:
var ajaxrequest=null
if (window.ActiveXObject){ //Test for support for different versions of ActiveXObject in IE
 try {
  ajaxrequest=new ActiveXObject("Msxml2.XMLHTTP")
 }
 catch (e){
  try{
   ajaxrequest=new ActiveXObject("Microsoft.XMLHTTP")
  } //end inner try
  catch (e){
   alert("I give up. Your IE doesn't support Ajax!")
  } //end inner catch

 } //end outer catch
}
else if (window.XMLHttpRequest) // if Mozilla, Safari etc
 ajaxrequest=new XMLHttpRequest()

ajaxrequest.open('GET', 'process.php', true) //do something with request

Here I'm using a nested try/catch statement to try and determine in IE which version of the ActiveX Object it supports that's needed to initialize an Ajax request. Using object detection won't work here, since the issue isn't whether the browser supports ActiveXObject here, but which version.

The Error object and throwing your own errors

The Error Object

As promised, we're going to take a closer look at the Error object that gets passed into the catch clause to see just what we can extract from it in an event of an error. The Error object in all browsers support the following two properties:
  1. name: The name of the error, or more specifically, the name of the constructor function the error belongs to.
  2. message: A description of the error, with this description varying depending on the browser.
try{
 document.body.filters[0].apply()
}
catch(e){
 alert(e.name + "\n" + e.message)
}
Demo:
Six possible values can be returned by the name property, which as mentioned correspond to the names of the error's constructors. They are:
Error Name Description
EvalError An error in the eval() function has occurred.
RangeError Out of range number value has occurred.
ReferenceError An illegal reference has occurred.
SyntaxError A syntax error within code inside the eval() function has occurred. All other syntax errors are not caught by try/catch/finally, and will trigger the default browser error message associated with the error. To catch actual syntax errors, you may use the onerror event.
TypeError An error in the expected variable type has occurred.
URIError An error when encoding or decoding the URI has occurred (ie: when calling encodeURI()).

This level of detail may be useful when you wish to sniff out a specific type of error in your catch clause. In the below, no DIV on the page exists with ID="mydiv". When trying to set its .innerHTML property, a TypeError occurs, since we're trying to assign the .innerHTML property to a null object:
try{
 document.getElementById("mydiv").innerHTML='Success' //assuming "mydiv" is undefined
}
catch(e){
 if (e.name.toString()=="TypeError") //evals to true in this case
  //do something
}

Ok, so maybe it's not that useful most of the time, but you just never know.

Throwing your own errors (exceptions)

Instead of waiting for one of the 6 types of errors above to occur before control is automatically transferred from the try block to the catch block, you can also explicitly throw your own exceptions to force that to happen on demand. This is great for creating your own definitions of what an error is and when control should be transferred to catch.
To throw an error, invoke, well, the throw statement inside your try/catch/finally blocks. The syntax is:
throw myerrorobject
Where myerrorobject can in fact be anything from a string, number, Boolean, to a new or one of the 6 default Error Constructor functions. What myerrorobject is set to mainly just affects what error.name and error.message returns in your catch clause. Most commonly you would just throw a new Error object:
  • throw new Error("Oh oh, an error has occured")
Lets see a meaningful example of throw in action:
function entrycheck(){
 try{
  var agecheck=prompt("This movie is rated PG-13. Please enter your age before continuing:")
  if (isNaN(parseInt(agecheck)))
   throw new Error("Please enter a valid age")
  else if (agecheck<13)
   throw new Error("Sorry, but you are too young for this movie")
  alert("Enjoy the movie!")
 }
 catch(e){
  alert(e.name+" "+e.message)
 }
}

Demo:
Try entering a none numeric value (ie: "haha") or a number less than 13 (ie: 11). In both cases, by using throw, control is instantly transferred to catch, with e.message displaying a different message. Technically entering a string or number less than 13 certainly doesn't constitute an exception in JavaScript, though for our purpose here, they should. That's how throw can be useful- when you need to specify your own parameters of what an error is inside try/catch/finally.
As mentioned, there are a number of other things apart from new Error() you can throw, which changes the contents of the error object passed into catch. The following are all valid throws:
  • throw "An error has occurred"
  • throw true
  • throw new Error("I detect an error!")
  • throw new SyntaxError("Your syntax is no good")
In the last instance, you can substitute SyntaxError with one of the 6 Error constructor function names to throw a specific type of error. In our age check example above, we could have thrown a SyntaxError when the value entered was a string, and a RangeError when the value was less than 13:
function entrycheck(){
 try{
  var agecheck=prompt("This movie is rated PG-13. Please enter your age before continuing:")
  if (isNaN(parseInt(agecheck)))
   throw new SyntaxError("Please enter a valid age")
  else if (agecheck<13)
   throw new RangeError("Sorry, but you are too young for this movie")
  alert("Enjoy the movie!")
 }
 catch(e){
  alert(e.name+" "+e.message)
 }
}
This has the effect of changing what e.name returns- SyntaxError and RangeError, respectively. If that's not enough, you can even throw a generic Error object with custom name and message properties:
throw{
 name: "JavaScriptKit Error",
 message: "Error detected. Please contact webmaster"
}

And with that we throw in the towel!

Introduction to Touch events in JavaScript

In this tutorial lets get touchy feely with JavaScript, but examining its touch related events and how they are used to detect and respond to touch and swipe events. With touch based devices ever growing in numbers, grasping these events is as essential as understanding the age old mouse events. Examples in this tutorial can be appreciated in both touch and non-touch enabled devices, with the later falling back to your trusted mouse instead. Ready to give those fingers a bit of a workout? Lets go!

JavaScript Touch Events

So lets dive right into it. The following lists the supported touch events in JavaScript:
JavaScript Touch Events
Event Name Description
touchstart Triggers when the user makes contact with the touch surface and creates a touch point inside the element the event is bound to.
touchmove Triggers when the user moves the touch point across the touch surface.
touchend Triggers when the user removes a touch point from the surface. It fires regardless of whether the touch point is removed while inside the bound-to element, or outside, such as if the user's finger slides out of the element first or even off the edge of the screen.
touchenter Triggers when the touch point enters the bound-to element. This event does not bubble.
touchleave Triggers when the touch point leaves the bound-to element. This event does not bubble.
touchcancel Triggers when the touch point no longer registers on the touch surface. This can occur if the user has moved the touch point outside the browser UI or into a plugin, for example, or if an alert modal pops up.
These events can be attached to any element on the page, and is passed an event object containing details about the touch point, such as its coordinates on the page. Use element.addEventListener() to attach the event(s), for example to the BODY of the page:
window.addEventListener('load', function(){ // on page load
 
 document.body.addEventListener('touchstart', function(e){
  alert(e.changedTouches[0].pageX) // alert pageX coordinate of touch point
 }, false)
 
}, false)
Here I've attached the "touchstart" event to document.body once the page has loaded (you may want to do this on DOMContentLoaded instead). Inside the anonymous function for touchstart, we look at the changedTouches object of the Event object, which contains information on each touch point initiated by that touch event on the touch surface. Here we're only interested in the first touch point (ie: finger) that has made contact, specifically, its pageX coordinate on the page when the touch is made.
The Event object whenever a touch event is fired holds a wealth of information about the touch action; you already saw its changedTouches object, which contains information on touch points changed since the last touch event . Lets take the above example a bit further now, by bringing in the touchmove and touchend events to show the distance traveled by a touch action from beginning to end on a DIV, from a finger touching down on an object to lifting up.
Example (mouse simulation added for non touch devices):

Touch Me!

Status: touchend
Resting x coordinate: 1033px

Touch then move your finger to see the current state of the touch and the distance traveled. The HTML markup for the DIV consists simply of:
<div class="box" id="box1">
<h3> Touch Me! </h3>
</div>
 
<h3 id="statusdiv">Status</h3>
The script looks like this:
<script>
 
window.addEventListener('load', function(){
 
 var box1 = document.getElementById('box1')
 var statusdiv = document.getElementById('statusdiv')
 var startx = 0
 var dist = 0
 
 
 box1.addEventListener('touchstart', function(e){
  var touchobj = e.changedTouches[0] // reference first touch point (ie: first finger)
  startx = parseInt(touchobj.clientX) // get x position of touch point relative to left edge of browser
  statusdiv.innerHTML = 'Status: touchstart<br /> ClientX: ' + startx + 'px'
  e.preventDefault()
 }, false)
 
 box1.addEventListener('touchmove', function(e){
  var touchobj = e.changedTouches[0] // reference first touch point for this event
  var dist = parseInt(touchobj.clientX) - startx
  statusdiv.innerHTML = 'Status: touchmove<br /> Horizontal distance traveled: ' + dist + 'px'
  e.preventDefault()
 }, false)
 
 box1.addEventListener('touchend', function(e){
  var touchobj = e.changedTouches[0] // reference first touch point for this event
  statusdiv.innerHTML = 'Status: touchend<br /> Resting x coordinate: ' + touchobj.clientX + 'px'
  e.preventDefault()
 }, false)
 
}, false)
 
 
</script>
A few points worth mentioning here:
  • We call event.preventDefault() to prevent the default action associated with each event from occurring. In the case of touchstart and touchend for instance, if the bound-to element was a link, not suppressing the default action would cause the browser to navigate to the link, cutting short our custom sequence of actions. In the case of touchmove, calling event.preventDefault() stops the browser from scrolling the page when the user is moving his finger inside the bound-to element.
  • Once again, we access the first element inside event.changedTouches[] for each of the touch events to reference the first touch point made to the element (there could be multiple fingers used), and examine the clientX property to get the horizontal coordinate of the touch point relative to the left edge of the browser (not including any scroll offsets). This property is adequate for what we're trying to do here, which is simply to get the relative distance traveled while a touch is maintained on the element.
  • To get the distance traveled between touchstart and touchend events, we define a startx variable at the touchstart phase that gets the starting clientX position of the touch. Then throughout the touchmove event, we get the clientX position of the touch and subtract from it the startx value to get the distance traveled while the touch point is maintained.
  • Notice how the touchend event is still fired and displays the final resting x coordinates even if your finger is outside the bound-to element at the time of lifting up your finger.
The object event.changedTouches[] is just one of numerous properties of the Event object that gets populated during touch related events. It's high time to look at this object in detail now.

Event object during Touch

The Event object is this mystical unicorn in JavaScript that contains information on an event when it occurs, whether it's the URL of a link in an onclick event, the keyCode of the key pressed in an onkeypress event etc. With touch related events, the Event object is populated with a slew of unique properties that give us insight into all aspects of the touch point, from how many fingers (or toes for that matter etc) touched down on the touch surface to their precise coordinates on the screen.
Event Object during Touch
Property Description
altkey Boolean indicating whether the alt key was pressed at time of touch event.
changedTouches A list of Touch objects representing each touch point directly involved in this event. Specifically:
  • In touchstart, it contains a list of fingers that have made contact with the touch surface during this touchstart event.
  • In touchmove, it contains a list of fingers that have moved during this touchmove event.
  • In touchend, it contains a list of fingers that have just been removed from the touch surface during this touchend event.
  • In touchenter, it contains a list of fingers that have entered the touch surface during this touchenter event.
  • In touchleave, it contains a list of fingers that have exited the touch surface during this touchleave event.
You can use the length property to get the number of Touch objects inside changedTouches[].
ctrlKey Boolean indicating whether the crtrl key was pressed at time of touch event.
metaKey Boolean indicating whether the meta key was pressed at time of touch event.
shiftKey Boolean indicating whether the shift key was pressed at time of touch event.
targetTouches A list of touch points currently making contact with the touch surface AND started out from the same element that is the target of this event. For example, lets say you bind the touchstart event to a DIV and place two fingers down on the surface. targetTouches will only contain information on the finger(s) placed inside the DIV, and not any outside.
You can use the length property to get the number of Touch objects inside targetTouches[].
touches A list of Touch objects representing all touch points currently in contact with the touch surface, regardless of which element a touch point is on at the moment.
type The type of event that triggered the Event object, such as touchstart, touchmove, etc.
target The target element of the touches associated with this event.
So for example, during a touchstart event, the Event object's touches property lets us access all touch points currently in contact with touch surface in general
document.body.addEventListener('touchstart', function(e){
 var touchlist = e.touches
 for (var i=0; i<touchlist.length; i++){ // loop through all touch points currently in contact with surface
  //do something with each Touch object (point)
 }
}, false)
The Event object's three properties evt.changedTouches, evt.targetTouches, and evt.touches are all list objects containing a list of Touch objects, one Touch object for each touch point made. It is through a Touch object you get details about a specific touch point, such as its coordinates on the screen, its unique identifier to help you identify which touch point is which, and so on. You saw in the beginning some code that accesses a Touch object contained inside evt.changedTouches:
box1.addEventListener('touchstart', function(e){
 var touchobj = e.changedTouches[0] // reference first touch point (ie: first finger)
 startx = parseInt(touchobj.clientX) // get x position of touch point relative to left edge of browser
 e.preventDefault()
}, false)
Here e.changedTouches[0] is a Touch object, with clientX being one property of the Touch object. Lets take a formal look at the Touch object now:
Touch object
Property Description
identifier An value to help uniquely identify each touch point currently in contact with the touch surface. The value starts at 0 for the first unique touch point on the surface, 1 for the second etc. This value is maintained for each touch point until the user's finger is lifted off the surface.Lets say the user puts two fingers down on an element. Each finger at this point is assigned a unique identifier. When you move the fingers, you can use each touch point's identifier to identify which touch point is which.
screenX The x coordinate of the touch point relative to the left edge of the user's screen.
screenY The y coordinate of the touch point relative to the top edge of the user's screen.
clientX The x coordinate of the touch point relative to the left edge of the viewport, not including scroll offsets.
clientY The y coordinate of the touch point relative to the top edge of the viewport, not including scroll offsets.
pageX The x coordinate of the touch point relative to the left edge of the viewport, including scroll offsets.
pageY The y coordinate of the touch point relative to the top edge of the viewport, including scroll offsets.
radiusX The radius of the ellipse which most closely defines the touching area (e.g. finger, stylus) along the x-axis.
radiusY The radius of the ellipse which most closely defines the touching area (e.g. finger, stylus) along the y-axis.
rotationAngle The angle (in degrees) that the ellipse described by radiusX and radiusY is rotated clockwise about its center.
force Returns the force of the touch point in the form of an integer between 0 and 1, where 0 is no force as detected by the device, and 1, the highest.
target The target element of the touch point; in other words, the element the touch point landed on, which may be different from the element its corresponding touch event was originally bounded to. In the following, this always returns the BODY element, while Touch.target returns the element the finger actually touched down on, which could be a DIV, a SPAN etc:
document.body.addEventListener('touchstart', function(e){
 var touchobj = e.changedTouches[0]
 console.log(this.tagName) // returns BODY
 console.log(touchobj.target) // returns element touch point landed on
}, false)
The properties of the Touch object you'll most frequently be accessing are those relating to coordinates, to help you determine where, and with a little Math, in what direction and how fast a touch action is performed.
Lets rewind now back to the Event object and talk a bit more about the Touches, changedTouches, and targetTouches properties, to help more clearly explain their differences:
  • Touches: A list of all touch points currently making contact with the touch surface.
  • changedTouches: A list of touch points involved in this event. For example, in a touchmove event, changedTouches contains only a list of touch points that are currently moving, whereas Touches would contain all touch points currently on the surface.
  • targetTouches: A list of touch points currently making contact with the touch surface AND started out from the same element that is the target of this event. For example, lets say you bind the touchstart event to a DIV and place two fingers down on the surface. targetTouches will only contain information on the finger(s) placed inside the DIV, and not any outside.
Andrei at Stackoverflow gave a very illuminating example that clarifies the subtle differences between these three properties:
  • When I put a finger down, all three lists will have the same information. It will be in changedTouches because putting the finger down is what caused the event
  • When I put a second finger down, touches will have two items, one for each finger. targetTouches will have two items only if the finger was placed in the same node as the first finger. changedTouches will have the information related to the second finger, because it’s what caused the event
  • If I put two fingers down at exactly the same time, it’s possible to have two items in changedTouches, one for each finger
  • If I move my fingers, the only list that will change is changedTouches and will contain information related to as many fingers as have moved (at least one).
  • When I lift a finger, it will be removed from touches, targetTouches and will appear in changedTouches since it’s what caused the event
  • Removing my last finger will leave touches and targetTouches empty, and changedTouches will contain information for the last finger

Moving an object using touch

Using touch to move a DIV horizontally or vertically across the screen is very simple. Take a look at the below, which moves a DIV horizontally across a track when touched and dragged:
Example (mouse simulation added for non touch devices):
Drag
<script>
 
window.addEventListener('load', function(){
 
 var box2 = document.getElementById('box2'),
 boxleft, // left position of moving box
 startx, // starting x coordinate of touch point
 dist = 0, // distance traveled by touch point
 touchobj = null // Touch object holder
 
 box2.addEventListener('touchstart', function(e){
  touchobj = e.changedTouches[0] // reference first touch point
  boxleft = parseInt(box2.style.left) // get left position of box
  startx = parseInt(touchobj.clientX) // get x coord of touch point
  e.preventDefault() // prevent default click behavior
 }, false)
 
 box2.addEventListener('touchmove', function(e){
  touchobj = e.changedTouches[0] // reference first touch point for this event
  var dist = parseInt(touchobj.clientX) - startx // calculate dist traveled by touch point
 // move box according to starting pos plus dist
 // with lower limit 0 and upper limit 380 so it doesn't move outside track:
  box2.style.left = ( (boxleft + dist > 380)? 380 : (boxleft + dist < 0)? 0 : boxleft + dist ) + 'px'
  e.preventDefault()
 }, false)
 
}, false)
 
</script>
 
<div id="track" class="track">
<div id="box2" style="left:0; top:0">Drag Me</div>
</div>
The outer #track DIV is a relatively positioned element, while the #box2 DIV contained inside is absolutely positioned. We get #box2 DIV's initial left position and the x coordinate of the touch point at the touchstart event. Note I'm using touchobj.clientX here; we could have easily used touchobj.pageX instead, it doesn't matter, since we're only using this property to help ascertain the relative distance traveled by touch point.
During the touchmove event, we calculate the distance traveled by the moving touch point, by getting its current x coordinate and subtracting from that the initial x coordinate. Then, to move the #box2 DIV, we add that distance to the DIV's initial left position, throwing in a lower and upper limit of 0 and 380px, so to prevent the DIV from moving outside the parent DIV. And with that our DIV box now moves with our finger!



Detecting a swipe (left, right, top or down) using touch

Swiping in touch is the act of quickly moving your finger across the touch surface in a certain direction. There is currently no "onswipe" event in JavaScript, which means it's up to us to implement one using the available touch events, plus define just when a swipe is a, well, "swipe".
Lets first define when a movement across the touch surface should be considered a swipe. There are two variables at play here- the distance traveled by the user's finger on the x or y-axis from touchstart to touchend, and, the time it took. Based on these two factors, we can decide whether that action qualifies as a swipe and in what direction.
With that said, lets put ideas into action and see how to go about detecting a swipe right (from left to right). Once we can do that, detecting swipe in the other 3 directions is pretty much identical. For this exercise we'll stipulate that a right swipe has occurred when the user has moved his finger across the touch surface a minimum of 150px horizontally in 200 ms or less from left to right. Furthermore, there should be no more than 100px traveled vertically, to avoid "false positives" whereby the user swipes diagonally across, which we don't want to qualify as a swipe right.
Example (mouse simulation added for non touch devices):
Swipe Me
<script>
window.addEventListener('load', function(){
 var touchsurface = document.getElementById('touchsurface'),
  startX,
  startY,
  dist,
  threshold = 150, //required min distance traveled to be considered swipe
  allowedTime = 200, // maximum time allowed to travel that distance
  elapsedTime,
  startTime
 function handleswipe(isrightswipe){
  if (isrightswipe)
   touchsurface.innerHTML = 'Congrats, you\'ve made a <span style="color:red">right swipe!</span>'
  else{
   touchsurface.innerHTML = 'Condition for right swipe not met yet'
  }
 }
 touchsurface.addEventListener('touchstart', function(e){
  touchsurface.innerHTML = ''
  var touchobj = e.changedTouches[0]
  dist = 0
  startX = touchobj.pageX
  startY = touchobj.pageY
  startTime = new Date().getTime() // record time when finger first makes contact with surface
  e.preventDefault()
 }, false)
 touchsurface.addEventListener('touchmove', function(e){
  e.preventDefault() // prevent scrolling when inside DIV
 }, false)
 touchsurface.addEventListener('touchend', function(e){
  var touchobj = e.changedTouches[0]
  dist = touchobj.pageX - startX // get total dist traveled by finger while in contact with surface
  elapsedTime = new Date().getTime() - startTime // get time elapsed
  // check that elapsed time is within specified, horizontal dist traveled >= threshold, and vertical dist traveled <= 100
var swiperightBol = (elapsedTime <= allowedTime && dist >= threshold && Math.abs(touchobj.pageY - startY) <= 100)
handleswipe(swiperightBol)
e.preventDefault()
}, false)
}, false)
</script>
<div id="touchsurface">Swipe Me</div>
Inside touchend, we check that the dist traveled from touchstart to touchend is a positive number above the specified threshold value (ie: 150), since in a right swipe, that dist should always be positive based on the equation used (versus negative for a left swipe). At the same time, we make sure any vertical lateral movement traveled is less than 100px to weed out diagonal swipes. Since the vertical movement can occur either above the starting touch point or below, we use Math.abs() when getting the absolute vertical dist traveled so both scenarios are covered when comparing it to our vertical threshold value of 100.

A generic swipe detecting function

Now that we got right swipe down, lets create a more generic function that detects swiping in either of the 4 directions (left, right, up, or down):
function swipedetect(el, callback){
 var touchsurface = el,
 swipedir,
 startX,
 startY,
 distX,
 distY,
 threshold = 150, //required min distance traveled to be considered swipe
 restraint = 100, // maximum distance allowed at the same time in perpendicular direction
 allowedTime = 300, // maximum time allowed to travel that distance
 elapsedTime,
 startTime,
 handleswipe = callback || function(swipedir){}
 touchsurface.addEventListener('touchstart', function(e){
  var touchobj = e.changedTouches[0]
  swipedir = 'none'
  dist = 0
  startX = touchobj.pageX
  startY = touchobj.pageY
  startTime = new Date().getTime() // record time when finger first makes contact with surface
  e.preventDefault()
 }, false)
 touchsurface.addEventListener('touchmove', function(e){
  e.preventDefault() // prevent scrolling when inside DIV
 }, false)
 touchsurface.addEventListener('touchend', function(e){
  var touchobj = e.changedTouches[0]
  distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface
  distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface
  elapsedTime = new Date().getTime() - startTime // get time elapsed
  if (elapsedTime <= allowedTime){ // first condition for awipe met
   if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint){ // 2nd condition for horizontal swipe met
    swipedir = (distX < 0)? 'left' : 'right' // if dist traveled is negative, it indicates left swipe
   }
   else if (Math.abs(distY) >= threshold && Math.abs(distX) <= restraint){ // 2nd condition for vertical swipe met
    swipedir = (distY < 0)? 'up' : 'down' // if dist traveled is negative, it indicates up swipe
   }
  }
  handleswipe(swipedir)
  e.preventDefault()
 }, false)
}
//USAGE:
/*
var el = document.getElementById('someel')
swipedetect(el, function(swipedir){
 swipedir contains either "none", "left", "right", "top", or "down"
 if (swipedir =='left')
   alert('You just swiped left!')
})
*/
swipedetect() accepts two parameters, the element to bind the touch events to, plus a function to execute when a swipe has occurred. The function parameter "swipedir" tells you the type of swipe that was just made with five possible values: "none", "left", "right", "top", or "down".
The below uses the swipedetect() function to show a "left", "right", "top", or "down" background image (overlaid on top of a default background image) depending on the swipe that has just occurred:
Example (mouse simulation added for non touch devices):
Swipe Me
The code used is:
window.addEventListener('load', function(){
 var el = document.getElementById('touchsurface2')
 var inner = document.getElementById('inner')
 var hidetimer = null
 swipedetect(el, function(swipedir){
  if (swipedir != 'none'){
   clearTimeout(hidetimer)
   var bgimage = swipedir + 'arrow.png' // naming convention is "leftarrow.png", "rightarrow.png" etc
   inner.style.background = 'transparent url(' + bgimage + ') center center no-repeat'
   hidetimer = setTimeout(function(){ // reset background image after 1 second
    inner.style.background = ''
   }, 1000)
  }
 })
}, false)
The HTML markup is:
<div id="touchsurface2">
 <div id="inner">
  Swipe Me
 </div>
</div>
We bind swipedetect() to "#touchsurface2", and whenever a valid swipe has occurred inside it, we change the "#inner" DIV's background image accordingly to reflect the type of swipe that has just occurred.

Monitoring touch actions at every stage, swipe image gallery

On the previous page, you saw how to detect swipes on a touch surface, and packaged that knowledge into a generic swipedetect() function:
swipedetect(el, function(swipedir){
 swipedir contains either "none", "left", "right", "top", or "down"
 if (swipedir =='left')
   alert('You just swiped left!')
})
That's all fine and dandy, but swipedetect() is limited in that it only lets us react to after a swipe has been made, and not during, or as the user is moving his finger across the touch surface. The later is useful in applications that need to react in tandem to a touch movement across the touch surface, such as an image gallery whereby the user can drag his finger to get a preview of the next or previous slide.

A generic ontouch function

Lets set out to create a generic ontouch() function that can be used to execute custom code at every step of a touch action, from the finger's initial contact with the surface, movement across, to lifting the finger up to end it. Surprisingly it's not much different from our swipedetect() function, only that we'll be scrutinizing the touchmove event more closely this time:
function ontouch(el, callback){
 var touchsurface = el,
 dir,
 swipeType,
 startX,
 startY,
 distX,
 distY,
 threshold = 150, //required min distance traveled to be considered swipe
 restraint = 100, // maximum distance allowed at the same time in perpendicular direction
 allowedTime = 500, // maximum time allowed to travel that distance
 elapsedTime,
 startTime,
 handletouch = callback || function(evt, dir, phase, swipetype, distance){}
 touchsurface.addEventListener('touchstart', function(e){
  var touchobj = e.changedTouches[0]
  dir = 'none'
  swipeType = 'none'
  dist = 0
  startX = touchobj.pageX
  startY = touchobj.pageY
  startTime = new Date().getTime() // record time when finger first makes contact with surface
  handletouch(e, 'none', 'start', swipeType, 0) // fire callback function with params dir="none", phase="start", swipetype="none" etc
  e.preventDefault()
 }, false)
 touchsurface.addEventListener('touchmove', function(e){
  var touchobj = e.changedTouches[0]
  distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface
  distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface
  if (Math.abs(distX) > Math.abs(distY)){ // if distance traveled horizontally is greater than vertically, consider this a horizontal movement
   dir = (distX < 0)? 'left' : 'right'
   handletouch(e, dir, 'move', swipeType, distX) // fire callback function with params dir="left|right", phase="move", swipetype="none" etc
  }
  else{ // else consider this a vertical movement
   dir = (distY < 0)? 'up' : 'down'
   handletouch(e, dir, 'move', swipeType, distY) // fire callback function with params dir="up|down", phase="move", swipetype="none" etc
  }
  e.preventDefault() // prevent scrolling when inside DIV
 }, false)
 touchsurface.addEventListener('touchend', function(e){
  var touchobj = e.changedTouches[0]
  elapsedTime = new Date().getTime() - startTime // get time elapsed
  if (elapsedTime <= allowedTime){ // first condition for awipe met
   if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint){ // 2nd condition for horizontal swipe met
    swipeType = dir // set swipeType to either "left" or "right"
   }
   else if (Math.abs(distY) >= threshold && Math.abs(distX) <= restraint){ // 2nd condition for vertical swipe met
    swipeType = dir // set swipeType to either "top" or "down"
   }
  }
  // Fire callback function with params dir="left|right|up|down", phase="end", swipetype=dir etc:
  handletouch(e, dir, 'end', swipeType, (dir =='left' || dir =='right')? distX : distY)
  e.preventDefault()
 }, false)
}
// USAGE:
/*
ontouch(el, function(evt, dir, phase, swipetype, distance){
 // evt: contains original Event object
 // dir: contains "none", "left", "right", "top", or "down"
 // phase: contains "start", "move", or "end"
 // swipetype: contains "none", "left", "right", "top", or "down"
 // distance: distance traveled either horizontally or vertically, depending on dir value
 if ( phase == 'move' && (dir =='left' || dir == 'right') )
  console.log('You are moving the finger horizontally by ' + distance)
})
*/
During each phase of a touch action- "start", "move", and "end", we get things like the direction of the touch point, distance traveled, and at the "end" phase, whether the touch movement constituted a swipe in one of the four directions, based on the same rules as that defined inside swipedetect() we saw earlier. The following illustrates ontouch in action to show various info about a touch action over a DIV:
Example (mouse simulation added for non touch devices):
Dir: down
Phase: end
Swipe Type: none
Distance: 210
<script>
window.addEventListener('load', function(){
 var el = document.getElementById('touchsurface2')
 ontouch(el, function(evt, dir, phase, swipetype, distance){
  var touchreport = ''
  touchreport += '<b>Dir:</b> ' + dir + '<br />'
  touchreport += '<b>Phase:</b> ' + phase + '<br />'
  touchreport += '<b>Swipe Type:</b> ' + swipetype + '<br />'
  touchreport += '<b>Distance:</b> ' + distance + '<br />'
  el.innerHTML = touchreport
 })
}, false)
</script>
<div id="touchsurface2">
</div>

A swipe image gallery

With the ontouch function, we can use it to create a swipe image gallery that responds to not just swiping for changing a slide, but dragging to get a preview of the next slide. Take a look at the below:
Example (drag or swipe to move gallery, mouse simulation added for non touch device):
<style>
.touchgallery{
position: relative;
overflow: hidden;
width: 350px; /* default gallery width */
height: 270px; /* default gallery height */
background: #eee;
}
.touchgallery ul{
list-style: none;
margin: 0;
padding: 0;
left: 0;
position: absolute;
-moz-transition: all 100ms ease-in-out; /* image transition. Change 100ms to desired transition duration */
-webkit-transition: all 100ms ease-in-out;
transition: all 100ms ease-in-out;
}
.touchgallery ul li{
float: left;
display: block;
width: 350px;
text-align: center;
}
.touchgallery ul li img{ /* CSS for images within gallery */
max-width: 100%; /* make each image responsive, so its native width can occupy up to 100% of gallery's width, but not beyond */
height: auto;
}
</style>
<script>
window.addEventListener('load', function(){
 var el = document.getElementById('swipegallery') // reference gallery's main DIV container
 var gallerywidth = el.offsetWidth
 var ul = el.getElementsByTagName('ul')[0]
 var liscount = ul.getElementsByTagName('li').length, curindex = 0, ulLeft = 0
 ul.style.width = gallerywidth * liscount + 'px' // set width of gallery to parent container's width * total images
 ontouch(el, function(evt, dir, phase, swipetype, distance){
  if (phase == 'start'){ // on touchstart
   ulLeft = parseInt(ul.style.left) || 0 // initialize ulLeft var with left position of UL
  }
  else if (phase == 'move' && (dir =='left' || dir =='right')){ //  on touchmove and if moving left or right
   var totaldist = distance + ulLeft // calculate new left position of UL based on movement of finger
   ul.style.left = Math.min(totaldist, (curindex+1) * gallerywidth) + 'px' // set gallery to new left position
  }
  else if (phase == 'end'){ // on touchend
   if (swipetype == 'left' || swipetype == 'right'){ // if a successful left or right swipe is made
    curindex = (swipetype == 'left')? Math.min(curindex+1, liscount-1) : Math.max(curindex-1, 0) // get new index of image to show
   }
   ul.style.left = -curindex * gallerywidth + 'px' // move UL to show the new image
  }
 }) // end ontouch
}, false)
</script>
<div id="swipegallery" class="touchgallery">
<ul>
<li><img src="../script/script2/food1.jpg" /></li>
<li><img src="../script/script2/food2.jpg" /></li>
<li><img src="../script/script2/food3.jpg" /></li>
<li><img src="../script/script2/food4.jpg" /></li>
<li><img src="../script/script2/food5.jpg" /></li>
</ul>
</div>
Markup wise our gallery consists of a relatively positioned main DIV with an absolutely positioned UL element inside it. Each of the LI elements (images) are floated left so they appear side by side horizontally. We set the total width of the UL element to the width of the gallery DIV multiplied by the number of LI elements inside our script. With such a set up, to show the 2nd image for example, we'd simply set the left position of the UL element to (nth image -1) * width of gallery DIV (ie: 1 * 350).

Now to our ontouch function, which like a magic wand is what transforms our otherwise static series of images into a touch and swipe image gallery! We call ontouch() and pass in a reference to the gallery's DIV container as the first parameter, or the element to monitor touch actions on. The anonymous function that follows lets us respond to all touch actions taking place inside on a granular level. When the user first touches down on the gallery, we get the current UL element's left position (0 when page first loads). Then as the user moves his finger across the touch surface, if the dir is left or right we access the distance parameter to get the distance traveled horizontally. That value when added to the UL's initial left position gives us the new left position of the UL, which we then set the UL to, causing the gallery to move left or right in tandem with the user's finger movement.

When the user lifts his finger off the gallery (phase equals "end"), we use the swipetype parameter to determine if a legitimate left or right swipe has occurred (versus just a slow drag for example). If so, we increment or decrement the current index (curindex) of the gallery before moving the gallery to show the new image.

And there you have it. As you can see, implementing touch friendly UIs in JavaScript is relatively straightforward thanks to the Touch API

.