Commit 8b4d3638 authored by Nature's avatar Nature

Initial commit

parents
~$*
.DS_Store
Thumbs.db
Desktop.ini
build
.gitignore
.npmignore
bower.json
component.json
examples
Makefile
tests
Copyright (c) 2014 The Financial Times Ltd.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
SHELL := /bin/bash
QS=compilation_level=SIMPLE_OPTIMIZATIONS&output_format=text
URL=http://closure-compiler.appspot.com/compile
CODE=js_code@lib/fastclick.js
CHECK=\033[32m✔\033[39m
build/fastclick.min.js: lib/fastclick.js
@mkdir -p build
@echo -n "Building build/fastclick.min.js... "
@curl --silent --show-error --data-urlencode "${CODE}" --data "${QS}&output_info=compiled_code" ${URL} -o build/fastclick.min.js
@echo -e "${CHECK} Done"
@echo -n "Getting compression stats... "
@echo -e "${CHECK} Done\n\n" "`curl --silent --show-error --data-urlencode "${CODE}" --data "${QS}&output_info=statistics" ${URL}`"
@echo ${STATS}
test:
jshint -v lib/*.js
clean:
rm -rf build
.PHONY: clean test
# FastClick #
FastClick is a simple, easy-to-use library for eliminating the 300ms delay between a physical tap and the firing of a `click` event on mobile browsers. The aim is to make your application feel less laggy and more responsive while avoiding any interference with your current logic.
FastClick is developed by [FT Labs](http://labs.ft.com/), part of the Financial Times.
*Note: As of late 2015 most mobile browsers - notably Chrome and Safari - no longer have a 300ms touch delay, so fastclick offers no benefit on newer browsers, and risks introducing [bugs](https://github.com/ftlabs/fastclick/issues) into your application. Consider carefully whether you really need to use it.*
[Explication en français](http://maxime.sh/2013/02/supprimer-le-lag-des-clics-sur-mobile-avec-fastclick/).
[日本語で説明](https://developer.mozilla.org/ja/docs/Mozilla/Firefox_OS/Apps/Tips_and_techniques#Make_events_immediate)
## Why does the delay exist? ##
According to [Google](https://developers.google.com/mobile/articles/fast_buttons):
> ...mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap.
## Compatibility ##
The library has been deployed as part of the [FT Web App](http://app.ft.com/) and is tried and tested on the following mobile browsers:
* Mobile Safari on iOS 3 and upwards
* Chrome on iOS 5 and upwards
* Chrome on Android (ICS)
* Opera Mobile 11.5 and upwards
* Android Browser since Android 2
* PlayBook OS 1 and upwards
## When it isn't needed ##
FastClick doesn't attach any listeners on desktop browsers.
Chrome 32+ on Android with `width=device-width` in the [viewport meta tag](https://developer.mozilla.org/en-US/docs/Mobile/Viewport_meta_tag) doesn't have a 300ms delay, therefore listeners aren't attached.
```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```
Same goes for Chrome on Android (all versions) with `user-scalable=no` in the viewport meta tag. But be aware that `user-scalable=no` also disables pinch zooming, which may be an accessibility concern.
For IE11+, you can use `touch-action: manipulation;` to disable double-tap-to-zoom on certain elements (like links and buttons). For IE10 use `-ms-touch-action: manipulation`.
## Usage ##
Include fastclick.js in your JavaScript bundle or add it to your HTML page like this:
```html
<script type='application/javascript' src='/path/to/fastclick.js'></script>
```
The script must be loaded prior to instantiating FastClick on any element of the page.
To instantiate FastClick on the `body`, which is the recommended method of use:
```js
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
```
Or, if you're using jQuery:
```js
$(function() {
FastClick.attach(document.body);
});
```
If you're using Browserify or another CommonJS-style module system, the `FastClick.attach` function will be returned when you call `require('fastclick')`. As a result, the easiest way to use FastClick with these loaders is as follows:
```js
var attachFastClick = require('fastclick');
attachFastClick(document.body);
```
### Minified ###
Run `make` to build a minified version of FastClick using the Closure Compiler REST API. The minified file is saved to `build/fastclick.min.js` or you can [download a pre-minified version](https://origami-build.ft.com/bundles/js?modules=fastclick).
Note: the pre-minified version is built using [our build service](http://origami.ft.com/docs/developer-guide/build-service/) which exposes the `FastClick` object through `Origami.fastclick` and will have the Browserify/CommonJS API (see above).
```js
var attachFastClick = Origami.fastclick;
attachFastClick(document.body);
```
### AMD ###
FastClick has AMD (Asynchronous Module Definition) support. This allows it to be lazy-loaded with an AMD loader, such as [RequireJS](http://requirejs.org/). Note that when using the AMD style require, the full `FastClick` object will be returned, _not_ `FastClick.attach`
```js
var FastClick = require('fastclick');
FastClick.attach(document.body, options);
```
### Package managers ###
You can install FastClick using [Component](https://github.com/component/component), [npm](https://npmjs.org/package/fastclick) or [Bower](http://bower.io/).
For Ruby, there's a third-party gem called [fastclick-rails](http://rubygems.org/gems/fastclick-rails). For .NET there's a [NuGet package](http://nuget.org/packages/FastClick).
## Advanced ##
### Ignore certain elements with `needsclick` ###
Sometimes you need FastClick to ignore certain elements. You can do this easily by adding the `needsclick` class.
```html
<a class="needsclick">Ignored by FastClick</a>
```
#### Use case 1: non-synthetic click required ####
Internally, FastClick uses `document.createEvent` to fire a synthetic `click` event as soon as `touchend` is fired by the browser. It then suppresses the additional `click` event created by the browser after that. In some cases, the non-synthetic `click` event created by the browser is required, as described in the [triggering focus example](http://ftlabs.github.com/fastclick/examples/focus.html).
This is where the `needsclick` class comes in. Add the class to any element that requires a non-synthetic click.
#### Use case 2: Twitter Bootstrap 2.2.2 dropdowns ####
Another example of when to use the `needsclick` class is with dropdowns in Twitter Bootstrap 2.2.2. Bootstrap add its own `touchstart` listener for dropdowns, so you want to tell FastClick to ignore those. If you don't, touch devices will automatically close the dropdown as soon as it is clicked, because both FastClick and Bootstrap execute the synthetic click, one opens the dropdown, the second closes it immediately after.
```html
<a class="dropdown-toggle needsclick" data-toggle="dropdown">Dropdown</a>
```
## Examples ##
FastClick is designed to cope with many different browser oddities. Here are some examples to illustrate this:
* [basic use](http://ftlabs.github.com/fastclick/examples/layer.html) showing the increase in perceived responsiveness
* [triggering focus](http://ftlabs.github.com/fastclick/examples/focus.html) on an input element from a `click` handler
* [input element](http://ftlabs.github.com/fastclick/examples/input.html) which never receives clicks but gets fast focus
## Tests ##
There are no automated tests. The files in `tests/` are manual reduced test cases. We've had a think about how best to test these cases, but they tend to be very browser/device specific and sometimes subjective which means it's not so trivial to test.
## Credits and collaboration ##
FastClick is maintained by [Rowan Beentje](http://twitter.com/rowanbeentje), [Matthew Caruana Galizia](http://twitter.com/mcaruanagalizia) and [Matthew Andrews](http://twitter.com/andrewsmatt) at [FT Labs](http://labs.ft.com). All open source code released by FT Labs is licenced under the MIT licence. We welcome comments, feedback and suggestions. Please feel free to raise an issue or pull request.
{
"name": "fastclick",
"license": "MIT",
"main": "lib/fastclick.js",
"ignore": [
"**/.*",
"component.json",
"package.json",
"Makefile",
"tests",
"examples"
]
}
{
"name": "fastclick",
"repo": "ftlabs/fastclick",
"description": "Polyfill to remove click delays on browsers with touch UIs.",
"version": "1.0.3",
"main": "lib/fastclick.js",
"scripts": [
"lib/fastclick.js"
],
"ignore": [
"examples/",
"tests/"
],
"license": "MIT"
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
p, .test { font-family: sans-serif; }
.test { margin: 1em 4em; line-height: 4em; border: 1px solid black; font-size: 2em; text-align: center; }
input { height: 3em; width: 10em; margin: 1em auto; display: block; }
/* Disable certain interactions on touch devices */
body { -webkit-touch-callout: none; -webkit-text-size-adjust: none; -webkit-user-select: none; -webkit-highlight: none; -webkit-tap-highlight-color: rgba(0,0,0,0); }
</style>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
var textInput = document.querySelector('input');
FastClick.attach(document.body);
Array.prototype.forEach.call(document.getElementsByClassName('test'), function(testEl) {
testEl.addEventListener('click', function() {
textInput.focus();
}, false)
});
}, false);
</script>
</head>
<body>
<p>FastClick is instantiated on the body element, so all visible elements on this page will receive fast clicks - except one.</p>
<p>The layers marked <var>A</var> and <var>B</var> both have <code>click</code> handlers that will attempt to trigger focus on the <code>input</code> element programatically. However, <strong>on iOS before version 5.0</strong>, touch event handlers are not allowed to trigger focus on other elements.</p>
<p>On earlier versions of iOS, only <var>B</var> will succeed at triggering focus on the input element, because it has a <code>needsclick</code> class which will instruct FastClick not to trigger a programmatic click in the touch event handler and let the system click event go through instead.</p>
<div>
<input type="text">
<div class="test">A</div>
<div class="test needsclick">B</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
p, label { font-family: sans-serif; }
.test { text-align: center; }
input[type=text] { height: 3em; width: 10em; }
label { display: block; background: gray; line-height: 2em; display: inline-block; font-weight: bold; }
/* Disable certain interactions on touch devices */
body { -webkit-touch-callout: none; -webkit-text-size-adjust: none; -webkit-user-select: none; -webkit-highlight: none; -webkit-tap-highlight-color: rgba(0,0,0,0); }
</style>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function () {
FastClick.attach(document.body);
}, false);
</script>
</head>
<body>
<p>FastClick is instantiated on the body element, but the <code>input</code> element below will not receive fast clicks. Instead <code>focus()</code> will be called on the input element when <code>touchend</code> fires.</p>
<p>The keyboard will still appear after delay on iOS 4 or earlier, however.</p>
<div class="test">
<input type="text" id="tap-me" placeholder="Tap me">
</div>
<p>The same is true for the <code>select</code> element. It should open quickly on iOS > 4.</p>
<div class="test">
<select>
<option>Banana</option>
<option>Apple</option>
</select>
</div>
<p>The text below is a <code>label</code> for the text input element above. FastClick should automatically resolve the ID in the <code>for</code> attribute and trigger focus on the input element. This doesn't work on iOS 4, however (with or without FastClick).</p>
<label for="tap-me">I'm a label - tap me</label>
<p>Checkbox labels don't work on iOS 4, but with FastClick, they do!</p>
<input type="checkbox" id="check-me" /> <label for="check-me">I'm a label - tap me</label>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
p, .test { font-family: sans-serif; }
.test { margin: 1em auto; width: 6em; line-height: 4em; border: 1px solid black; font-size: 2em; text-align: center; }
.stats, .stats input { font-family: monospace; font-size: 0.9em; }
input { width: 10em; }
/* Disable certain interactions on touch devices */
body { -webkit-touch-callout: none; -webkit-text-size-adjust: none; -webkit-user-select: none; -webkit-highlight: none; -webkit-tap-highlight-color: rgba(0,0,0,0); }
</style>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
var testA, testB, teTime, cTime;
testA = document.getElementById('test-a');
testB = document.getElementById('test-b');
// Android 2.2 needs FastClick to be instantiated before the other listeners so that the stopImmediatePropagation hack can work.
FastClick.attach(testB);
testA.addEventListener('touchend', function(event) {
teTime = Date.now();
document.getElementById('te-time').value = teTime;
}, false);
testA.addEventListener('click', function(event) {
cTime = Date.now();
document.getElementById('c-time').value = cTime;
document.getElementById('d-time').value = cTime - teTime;
testA.style.backgroundColor = testA.style.backgroundColor ? '' : 'YellowGreen';
}, false);
testB.addEventListener('touchend', function(event) {
teTime = Date.now();
document.getElementById('te-time').value = teTime;
document.getElementById('d-time').value = cTime - teTime;
}, false);
testB.addEventListener('click', function(event) {
cTime = Date.now();
document.getElementById('c-time').value = cTime;
testB.style.backgroundColor = testB.style.backgroundColor ? '' : 'YellowGreen';
}, false);
}, false);
</script>
</head>
<body>
<p>Layer A responds to click events normally, which on iOS will introduce a 300ms delay.</p>
<p>Layer B is enhanced with FastClick, and will fire the click handler with no delay.</p>
<p>The layers will behave normally on platforms that don't support touch events.</p>
<p class="stats">Touch end time: <input id="te-time" value="0" /></p>
<p class="stats">Click event time: <input id="c-time" /></p>
<p class="stats">Difference: <input id="d-time" /></p>
<div>
<div class="test" id="test-a">A</div>
<div class="test" id="test-b">B</div>
</div>
</body>
</html>
;(function () {
'use strict';
/**
* @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.
*
* @codingstandard ftlabs-jsv2
* @copyright The Financial Times Limited [All Rights Reserved]
* @license MIT License (see LICENSE.txt)
*/
/*jslint browser:true, node:true*/
/*global define, Event, Node*/
/**
* Instantiate fast-clicking listeners on the specified layer.
*
* @constructor
* @param {Element} layer The layer to listen on
* @param {Object} [options={}] The options to override the defaults
*/
function FastClick(layer, options) {
var oldOnClick;
options = options || {};
/**
* Whether a click is currently being tracked.
*
* @type boolean
*/
this.trackingClick = false;
/**
* Timestamp for when click tracking started.
*
* @type number
*/
this.trackingClickStart = 0;
/**
* The element being tracked for a click.
*
* @type EventTarget
*/
this.targetElement = null;
/**
* X-coordinate of touch start event.
*
* @type number
*/
this.touchStartX = 0;
/**
* Y-coordinate of touch start event.
*
* @type number
*/
this.touchStartY = 0;
/**
* ID of the last touch, retrieved from Touch.identifier.
*
* @type number
*/
this.lastTouchIdentifier = 0;
/**
* Touchmove boundary, beyond which a click will be cancelled.
*
* @type number
*/
this.touchBoundary = options.touchBoundary || 10;
/**
* The FastClick layer.
*
* @type Element
*/
this.layer = layer;
/**
* The minimum time between tap(touchstart and touchend) events
*
* @type number
*/
this.tapDelay = options.tapDelay || 200;
/**
* The maximum time for a tap
*
* @type number
*/
this.tapTimeout = options.tapTimeout || 700;
if (FastClick.notNeeded(layer)) {
return;
}
// Some old versions of Android don't have Function.prototype.bind
function bind(method, context) {
return function() { return method.apply(context, arguments); };
}
var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];
var context = this;
for (var i = 0, l = methods.length; i < l; i++) {
context[methods[i]] = bind(context[methods[i]], context);
}
// Set up event handlers as required
if (deviceIsAndroid) {
layer.addEventListener('mouseover', this.onMouse, true);
layer.addEventListener('mousedown', this.onMouse, true);
layer.addEventListener('mouseup', this.onMouse, true);
}
layer.addEventListener('click', this.onClick, true);
layer.addEventListener('touchstart', this.onTouchStart, false);
layer.addEventListener('touchmove', this.onTouchMove, false);
layer.addEventListener('touchend', this.onTouchEnd, false);
layer.addEventListener('touchcancel', this.onTouchCancel, false);
// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick
// layer when they are cancelled.
if (!Event.prototype.stopImmediatePropagation) {
layer.removeEventListener = function(type, callback, capture) {
var rmv = Node.prototype.removeEventListener;
if (type === 'click') {
rmv.call(layer, type, callback.hijacked || callback, capture);
} else {
rmv.call(layer, type, callback, capture);
}
};
layer.addEventListener = function(type, callback, capture) {
var adv = Node.prototype.addEventListener;
if (type === 'click') {
adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
if (!event.propagationStopped) {
callback(event);
}
}), capture);
} else {
adv.call(layer, type, callback, capture);
}
};
}
// If a handler is already declared in the element's onclick attribute, it will be fired before
// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
// adding it as listener.
if (typeof layer.onclick === 'function') {
// Android browser on at least 3.2 requires a new reference to the function in layer.onclick
// - the old one won't work if passed to addEventListener directly.
oldOnClick = layer.onclick;
layer.addEventListener('click', function(event) {
oldOnClick(event);
}, false);
layer.onclick = null;
}
}
/**
* Windows Phone 8.1 fakes user agent string to look like Android and iPhone.
*
* @type boolean
*/
var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0;
/**
* Android requires exceptions.
*
* @type boolean
*/
var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone;
/**
* iOS requires exceptions.
*
* @type boolean
*/
var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;
/**
* iOS 4 requires an exception for select elements.
*
* @type boolean
*/
var deviceIsIOS4 = deviceIsIOS && (/OS 4_\d(_\d)?/).test(navigator.userAgent);
/**
* iOS 6.0-7.* requires the target element to be manually derived
*
* @type boolean
*/
var deviceIsIOSWithBadTarget = deviceIsIOS && (/OS [6-7]_\d/).test(navigator.userAgent);
/**
* BlackBerry requires exceptions.
*
* @type boolean
*/
var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;
/**
* Determine whether a given element requires a native click.
*
* @param {EventTarget|Element} target Target DOM element
* @returns {boolean} Returns true if the element needs a native click
*/
FastClick.prototype.needsClick = function(target) {
switch (target.nodeName.toLowerCase()) {
// Don't send a synthetic click to disabled inputs (issue #62)
case 'button':
case 'select':
case 'textarea':
if (target.disabled) {
return true;
}
break;
case 'input':
// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
if ((deviceIsIOS && target.type === 'file') || target.disabled) {
return true;
}
break;
case 'label':
case 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames
case 'video':
return true;
}
return (/\bneedsclick\b/).test(target.className);
};
/**
* Determine whether a given element requires a call to focus to simulate click into element.
*
* @param {EventTarget|Element} target Target DOM element
* @returns {boolean} Returns true if the element requires a call to focus to simulate native click.
*/
FastClick.prototype.needsFocus = function(target) {
switch (target.nodeName.toLowerCase()) {
case 'textarea':
return true;
case 'select':
return !deviceIsAndroid;
case 'input':
switch (target.type) {
case 'button':
case 'checkbox':
case 'file':
case 'image':
case 'radio':
case 'submit':
return false;
}
// No point in attempting to focus disabled inputs
return !target.disabled && !target.readOnly;
default:
return (/\bneedsfocus\b/).test(target.className);
}
};
/**
* Send a click event to the specified element.
*
* @param {EventTarget|Element} targetElement
* @param {Event} event
*/
FastClick.prototype.sendClick = function(targetElement, event) {
var clickEvent, touch;
// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
if (document.activeElement && document.activeElement !== targetElement) {
document.activeElement.blur();
}
touch = event.changedTouches[0];
// Synthesise a click event, with an extra attribute so it can be tracked
clickEvent = document.createEvent('MouseEvents');
clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
clickEvent.forwardedTouchEvent = true;
targetElement.dispatchEvent(clickEvent);
};
FastClick.prototype.determineEventType = function(targetElement) {
//Issue #159: Android Chrome Select Box does not open with a synthetic click event
if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {
return 'mousedown';
}
return 'click';
};
/**
* @param {EventTarget|Element} targetElement
*/
FastClick.prototype.focus = function(targetElement) {
var length;
// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
var disallowedTypes = ['time', 'month', 'email', 'number'];
if (deviceIsIOS &&
targetElement.setSelectionRange &&
targetElement.type.indexOf('date') !== 0 &&
disallowedTypes.indexOf(targetElement.type) === -1) {
length = targetElement.value.length;
targetElement.focus();
targetElement.setSelectionRange(length, length);
} else {
targetElement.focus();
}
};
/**
* Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.
*
* @param {EventTarget|Element} targetElement
*/
FastClick.prototype.updateScrollParent = function(targetElement) {
var scrollParent, parentElement;
scrollParent = targetElement.fastClickScrollParent;
// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the
// target element was moved to another parent.
if (!scrollParent || !scrollParent.contains(targetElement)) {
parentElement = targetElement;
do {
if (parentElement.scrollHeight > parentElement.offsetHeight) {
scrollParent = parentElement;
targetElement.fastClickScrollParent = parentElement;
break;
}
parentElement = parentElement.parentElement;
} while (parentElement);
}
// Always update the scroll top tracker if possible.
if (scrollParent) {
scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
}
};
/**
* @param {EventTarget} targetElement
* @returns {Element|EventTarget}
*/
FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {
// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.
if (eventTarget.nodeType === Node.TEXT_NODE) {
return eventTarget.parentNode;
}
return eventTarget;
};
/**
* On touch start, record the position and scroll offset.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onTouchStart = function(event) {
var targetElement, touch, selection;
// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).
if (event.targetTouches.length > 1) {
return true;
}
targetElement = this.getTargetElementFromEventTarget(event.target);
touch = event.targetTouches[0];
if (deviceIsIOS) {
// Only trusted events will deselect text on iOS (issue #49)
selection = window.getSelection();
if (selection.rangeCount && !selection.isCollapsed) {
return true;
}
if (!deviceIsIOS4) {
// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):
// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched
// with the same identifier as the touch event that previously triggered the click that triggered the alert.
// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an
// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.
// Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,
// which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,
// random integers, it's safe to to continue if the identifier is 0 here.
if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {
event.preventDefault();
return false;
}
this.lastTouchIdentifier = touch.identifier;
// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:
// 1) the user does a fling scroll on the scrollable layer
// 2) the user stops the fling scroll with another tap
// then the event.target of the last 'touchend' event will be the element that was under the user's finger
// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check
// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).
this.updateScrollParent(targetElement);
}
}
this.trackingClick = true;
this.trackingClickStart = event.timeStamp;
this.targetElement = targetElement;
this.touchStartX = touch.pageX;
this.touchStartY = touch.pageY;
// Prevent phantom clicks on fast double-tap (issue #36)
if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
event.preventDefault();
}
return true;
};
/**
* Based on a touchmove event object, check whether the touch has moved past a boundary since it started.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.touchHasMoved = function(event) {
var touch = event.changedTouches[0], boundary = this.touchBoundary;
if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {
return true;
}
return false;
};
/**
* Update the last position.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onTouchMove = function(event) {
if (!this.trackingClick) {
return true;
}
// If the touch has moved, cancel the click tracking
if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
this.trackingClick = false;
this.targetElement = null;
}
return true;
};
/**
* Attempt to find the labelled control for the given label element.
*
* @param {EventTarget|HTMLLabelElement} labelElement
* @returns {Element|null}
*/
FastClick.prototype.findControl = function(labelElement) {
// Fast path for newer browsers supporting the HTML5 control attribute
if (labelElement.control !== undefined) {
return labelElement.control;
}
// All browsers under test that support touch events also support the HTML5 htmlFor attribute
if (labelElement.htmlFor) {
return document.getElementById(labelElement.htmlFor);
}
// If no for attribute exists, attempt to retrieve the first labellable descendant element
// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label
return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');
};
/**
* On touch end, determine whether to send a click event at once.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onTouchEnd = function(event) {
var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
if (!this.trackingClick) {
return true;
}
// Prevent phantom clicks on fast double-tap (issue #36)
if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
this.cancelNextClick = true;
return true;
}
if ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) {
return true;
}
// Reset to prevent wrong click cancel on input (issue #156).
this.cancelNextClick = false;
this.lastClickTime = event.timeStamp;
trackingClickStart = this.trackingClickStart;
this.trackingClick = false;
this.trackingClickStart = 0;
// On some iOS devices, the targetElement supplied with the event is invalid if the layer
// is performing a transition or scroll, and has to be re-detected manually. Note that
// for this to function correctly, it must be called *after* the event target is checked!
// See issue #57; also filed as rdar://13048589 .
if (deviceIsIOSWithBadTarget) {
touch = event.changedTouches[0];
// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null
targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
}
targetTagName = targetElement.tagName.toLowerCase();
if (targetTagName === 'label') {
forElement = this.findControl(targetElement);
if (forElement) {
this.focus(targetElement);
if (deviceIsAndroid) {
return false;
}
targetElement = forElement;
}
} else if (this.needsFocus(targetElement)) {
// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).
if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
this.targetElement = null;
return false;
}
this.focus(targetElement);
this.sendClick(targetElement, event);
// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.
// Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)
if (!deviceIsIOS || targetTagName !== 'select') {
this.targetElement = null;
event.preventDefault();
}
return false;
}
if (deviceIsIOS && !deviceIsIOS4) {
// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled
// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).
scrollParent = targetElement.fastClickScrollParent;
if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
return true;
}
}
// Prevent the actual click from going though - unless the target node is marked as requiring
// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.
if (!this.needsClick(targetElement)) {
event.preventDefault();
this.sendClick(targetElement, event);
}
return false;
};
/**
* On touch cancel, stop tracking the click.
*
* @returns {void}
*/
FastClick.prototype.onTouchCancel = function() {
this.trackingClick = false;
this.targetElement = null;
};
/**
* Determine mouse events which should be permitted.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onMouse = function(event) {
// If a target element was never set (because a touch event was never fired) allow the event
if (!this.targetElement) {
return true;
}
if (event.forwardedTouchEvent) {
return true;
}
// Programmatically generated events targeting a specific element should be permitted
if (!event.cancelable) {
return true;
}
// Derive and check the target element to see whether the mouse event needs to be permitted;
// unless explicitly enabled, prevent non-touch click events from triggering actions,
// to prevent ghost/doubleclicks.
if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
// Prevent any user-added listeners declared on FastClick element from being fired.
if (event.stopImmediatePropagation) {
event.stopImmediatePropagation();
} else {
// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
event.propagationStopped = true;
}
// Cancel the event
event.stopPropagation();
event.preventDefault();
return false;
}
// If the mouse event is permitted, return true for the action to go through.
return true;
};
/**
* On actual clicks, determine whether this is a touch-generated click, a click action occurring
* naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or
* an actual click which should be permitted.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onClick = function(event) {
var permitted;
// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.
if (this.trackingClick) {
this.targetElement = null;
this.trackingClick = false;
return true;
}
// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.
if (event.target.type === 'submit' && event.detail === 0) {
return true;
}
permitted = this.onMouse(event);
// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.
if (!permitted) {
this.targetElement = null;
}
// If clicks are permitted, return true for the action to go through.
return permitted;
};
/**
* Remove all FastClick's event listeners.
*
* @returns {void}
*/
FastClick.prototype.destroy = function() {
var layer = this.layer;
if (deviceIsAndroid) {
layer.removeEventListener('mouseover', this.onMouse, true);
layer.removeEventListener('mousedown', this.onMouse, true);
layer.removeEventListener('mouseup', this.onMouse, true);
}
layer.removeEventListener('click', this.onClick, true);
layer.removeEventListener('touchstart', this.onTouchStart, false);
layer.removeEventListener('touchmove', this.onTouchMove, false);
layer.removeEventListener('touchend', this.onTouchEnd, false);
layer.removeEventListener('touchcancel', this.onTouchCancel, false);
};
/**
* Check whether FastClick is needed.
*
* @param {Element} layer The layer to listen on
*/
FastClick.notNeeded = function(layer) {
var metaViewport;
var chromeVersion;
var blackberryVersion;
var firefoxVersion;
// Devices that don't support touch don't need FastClick
if (typeof window.ontouchstart === 'undefined') {
return true;
}
// Chrome version - zero for other browsers
chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
if (chromeVersion) {
if (deviceIsAndroid) {
metaViewport = document.querySelector('meta[name=viewport]');
if (metaViewport) {
// Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
return true;
}
// Chrome 32 and above with width=device-width or less don't need FastClick
if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
return true;
}
}
// Chrome desktop doesn't need FastClick (issue #15)
} else {
return true;
}
}
if (deviceIsBlackBerry10) {
blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
// BlackBerry 10.3+ does not require Fastclick library.
// https://github.com/ftlabs/fastclick/issues/251
if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {
metaViewport = document.querySelector('meta[name=viewport]');
if (metaViewport) {
// user-scalable=no eliminates click delay.
if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
return true;
}
// width=device-width (or less than device-width) eliminates click delay.
if (document.documentElement.scrollWidth <= window.outerWidth) {
return true;
}
}
}
}
// IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97)
if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {
return true;
}
// Firefox version - zero for other browsers
firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
if (firefoxVersion >= 27) {
// Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896
metaViewport = document.querySelector('meta[name=viewport]');
if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {
return true;
}
}
// IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version
// http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx
if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {
return true;
}
return false;
};
/**
* Factory method for creating a FastClick object
*
* @param {Element} layer The layer to listen on
* @param {Object} [options={}] The options to override the defaults
*/
FastClick.attach = function(layer, options) {
return new FastClick(layer, options);
};
if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
// AMD. Register as an anonymous module.
define(function() {
return FastClick;
});
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = FastClick.attach;
module.exports.FastClick = FastClick;
} else {
window.FastClick = FastClick;
}
}());
{
"name": "fastclick",
"version": "1.0.6",
"description": "Polyfill to remove click delays on browsers with touch UIs.",
"maintainers": [
{
"name": "Matthew Caruana Galizia",
"email": "m@m.cg",
"url": "http://m.cg/"
}
],
"author": {
"name": "Rowan Beentje",
"email": "rowan.beentje@ft.com"
},
"contributors": [
{
"name": "Rowan Beentje",
"email": "rowan.beentje@ft.com"
},
{
"name": "Matthew Caruana Galizia",
"email": "m@m.cg"
}
],
"main": "lib/fastclick.js",
"repository": {
"type": "git",
"url": "git://github.com/ftlabs/fastclick.git"
},
"keywords": [
"fastclick",
"mobile",
"touch",
"tap",
"click",
"delay"
],
"licenses": [
{
"type": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
],
"implements": [
"CommonJS/Modules/1.0"
],
"homepage": "https://github.com/ftlabs/fastclick"
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
textarea { width: 25em; height: 5em; }
</style>
<title>#10</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
document.getElementById('select').addEventListener('focus', function(event) {
event.target.setSelectionRange(0, event.target.value.length);
}, false);
}, false);
</script>
</head>
<body>
<textarea>FastClick is instantiated on the document body. Try and select the text in this textarea.</textarea>
<br><br>
<textarea id="select">The text in this textarea should be selected automatically when focussed.</textarea>
<p>Now try and select the text in this paragraph.</p>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=3">
<style type="text/css">
p { font-family: sans-serif; }
.test { font-size: 2em; border-radius: 0.4em; padding: 1em 1.5em; line-height: 2em; width: 1em; color: white; display: inline-block; }
#test1 { background: rgb(253, 109, 109); margin-right: 0.2em; }
#test2 { background: rgb(173, 255, 47); margin-left: 0.2em; }
#testcontainer { text-align: center; }
</style>
<title>#111</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
var test1 = document.getElementById('test1');
FastClick.attach(test1);
test1.addEventListener('click', function(event) {
if (event.forwardedTouchEvent) {
setTimeout(function() {
test1.style.webkitTransform = test1.style.webkitTransform ? '' : 'rotate(20deg)';
}, 0);
}
}, false);
}, false);
</script>
</head>
<body>
<p>If you attempt a pinch zoom on iOS with both fingers on the same element, pinch zooming should work. If each finger is touching a different element, the pinch zooming should also work.</p>
<p>Only the red block below has FastClick enabled.</p>
<div id="testcontainer">
<div class="test" id="test1">&#9678;</div>
<div class="test" id="test2">&#9678;</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
</style>
<title>#160</title>
<script type="application/javascript">
function test(event) {
var selectionStart, selectionDirection, selectionEnd, target = event.target, out = '';
try {
selectionStart = target.selectionStart;
out += 'Success getting selectionStart: ' + selectionStart + '\n';
} catch (err) {
out += 'Error getting selectionStart: ' + err + '\n';
}
try {
selectionEnd = target.selectionEnd;
out += 'Success getting selectionEnd: ' + selectionEnd + '\n';
} catch (err) {
out += 'Error getting selectionEnd: ' + err + '\n';
}
try {
selectionDirection = target.selectionDirection;
out += 'Success getting selectionDirection: ' + selectionDirection + '\n';
} catch (err) {
out += 'Error getting selectionDirection: ' + err + '\n';
}
try {
target.setSelectionRange(0, 0);
out += 'Success setting setSelectionRange.\n';
} catch (err) {
out += 'Error setting selection range: ' + err + '\n';
}
alert(out);
}
window.addEventListener('load', function() {
Array.prototype.forEach.call(document.getElementsByClassName('test'), function(elem) {
elem.addEventListener('click', test, false);
});
}, false);
</script>
</head>
<body>
<p>Calling elem.setSelectionRange on inputs with type date or time, as well as getting the selectionStart or selectionEnd properties, throws a TypeError.</p>
<p>Filed as Apple bug #15122724.</p>
<form>
<p>Test (date):</p>
<input type="date" class="test">
<p>Test (datetime):</p>
<input type="datetime" class="test">
<p>Test (month):</p>
<input type="month" class="test">
<p>Test (time):</p>
<input type="time" class="test">
<p>Control (text):</p>
<input class="test">
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
</style>
<title>#160</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
FastClick.attach(document.body);
}, false);
</script>
</head>
<body>
<p>Calling elem.setSelectionRange on inputs with type date or time throws a TypeError.</p>
<p>Filed as Apple bug #15122724.</p>
<form>
<p>Test:</p>
<input type="date" name="test">
<p>Control:</p>
<input name="control">
</form>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,initial-scale=1,user-scalable=0">
<title>fastclick</title>
<script src="../lib/fastclick.js"></script>
<style>
.page
{
padding: 50px;
font-size: 20px;
font-family: monospace;
/* for clickable layer */
height: 500px;
}
.input
{
font-size: 20px;
width: 100%;
height: 30px;
}
.button
{
text-align: center;
color: white;
margin-bottom: 20px;
padding: 10px;
background: #4a4d51;
}
</style>
</head>
<body class="page">
<div class="button">first, dye to blue!</div>
<input class="input" placeholder="then – focus here" id="ok">
<script>
(function(doc) {
function paint(color) {
doc.querySelector('.page').style.background = color;
};
function dye(e) { e.stopPropagation(); paint('#333'); }
function clean(e) { e.stopPropagation(); paint('#fff'); }
doc.querySelector('.button').addEventListener('click', dye);
doc.addEventListener('click', clean);
// fastclick initialization
FastClick.attach(doc.body);
})(document);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p, label { font-family: sans-serif; }
.test { text-align: center; }
input[type=text] { height: 3em; width: 10em; }
label { display: block; background: gray; line-height: 2em; display: inline-block; font-weight: bold; }
/* Disable certain interactions on touch devices */
body { -webkit-touch-callout: none; -webkit-text-size-adjust: none; -webkit-user-select: none; -webkit-highlight: none; -webkit-tap-highlight-color: rgba(0,0,0,0); }
</style>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function () {
new FastClick(document.body);
document.getElementsByTagName('form')[0].addEventListener('submit', function(event) {
event.preventDefault();
console.log('Submit caught');
}, false);
}, false);
</script>
</head>
<body>
<p>On focusing on the input text element, hitting go in the device keyboard should submit the form. The actual submission will be prevented and instead 'Submit caught' will appear in the console.</p>
<div class="test">
<form action="http://google.com/search" method="GET">
<input type="text" id="query" name="q" placeholder="Tap me">
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
textarea { width: 25em; height: 10em; }
</style>
<title>#22</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<textarea>FastClick is instantiated on the document body. Tap this textarea to gain focus.</textarea>
<p>On Android 4, single pressing the textarea should produce a cursor. Long-pressing a word should bring up the double arrow indicator for selection. It should be possible to move the indicators.</p>
<p>Tapping on a word with a squiggly red underline should bring up the spelling suggestion box.</p>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
textarea { width: 25em; height: 5em; }
</style>
<title>#226</title>
<script type="application/javascript">
document.body.addEventListener('touchend', function(event) {
console.log('touchend event caught and default prevented', event.target);
event.target.focus();
event.preventDefault();
});
</script>
</head>
<body>
The follow select can be opened with VoiceOver off, but with VoiceOver on it will not open.
<select id="sel">
<option>First</option>
<option>Second</option>
</select>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
input, code { font-family: monospace; }
</style>
<title>#23</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
// This function is for sending a touch event to the button programatically
var sendTouchEnd = function() {
var event, button;
button = document.getElementById('alert-on-click');
event = document.createEvent('UIEvent');
event.initUIEvent('touchend', true, true);
event.changedTouches = [{
screenX: button.offsetLeft,
screenY: button.offsetTop,
clientX: button.offsetLeft,
clientY: button.offsetTop
}];
button.dispatchEvent(event);
};
window.addEventListener('load', function() {
var i = 0;
var log = function(event) {
console.log(event.type, event);
};
document.body.addEventListener('touchend', function(event) {
var clickEvent, touch = event.changedTouches[0];
log(event);
// Synthesise a click event, with an extra attribute so it can be tracked
clickEvent = document.createEvent('MouseEvents');
clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
clickEvent.synthesized = true;
event.target.dispatchEvent(clickEvent);
}, false);
document.getElementById('alert-on-click').addEventListener('click', function(event) {
i++;
alert('Alert #' + i + ', on element with ID \'' + event.target.id + '\'.');
}, false);
}, false);
</script>
</head>
<body>
<p>At the start of this test, <code>i = 0</code>. Tapping the first button will increment <code>i</code> and trigger an alert with the text <code>'Alert #' + i</code>.</p>
<p>Tapping on the second button should have absolutely no effect, but in iOS6 it will re-trigger the alert.</p>
<input type="button" id="alert-on-click" value="Button #1">
<br><br>
<input type="button" id="no-alert-on-click" value="Button #2">
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
input, code { font-family: monospace; }
</style>
<title>#23</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
var i = 0, fastClick;
fastClick = new FastClick(document.body);
document.getElementById('alert-on-click').addEventListener('click', function(event) {
i++;
alert('Alert #' + i + ', on element with ID \'' + event.target.id + '\'.');
}, false);
}, false);
</script>
</head>
<body>
<p>At the start of this test, <code>i = 0</code>. Tapping the first button will increment <code>i</code> and trigger an alert with the text <code>'Alert #' + i</code>.</p>
<p>Tapping on the second button should have absolutely no effect, but in iOS 4-6 it will re-trigger the alert.</p>
<input type="button" id="alert-on-click" value="Button #1">
<br><br>
<input type="button" id="no-alert-on-click" value="Button #2">
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="../lib/fastclick.js"></script>
<style type="text/css">
p, label { font-family: sans-serif; }
input[type=text] { height: 3em; width: 10em; }
label { display: block; background: gray; margin-left: 2em; line-height: 2em; display: inline-block; font-weight: bold; }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<script>
$(function() {
$('#test-me').focus();
new FastClick(document.body);
});
/*
window.addEventListener('load', function() {
document.getElementById('test-me').focus();
new FastClick(document.body);
}, false);
*/
</script>
<title>#24</title>
</head>
<body>
<form action='fake'>
<input id="test-me" name="text" />
<div style='padding: 50px 0'>
<input type="radio" name="radio" id="x" checked />
<label for="x">This Is X</label>
<br>
<input type="radio" name="radio" id="y" />
<label for="y">This Is Y</label>
</div>
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script src="../lib/fastclick.js"></script>
<style type="text/css">
p { font-family: sans-serif; }
.test { background: pink; }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<script>
var f;
function create() {
f = new FastClick(document.body);
}
function destroy() {
if (f) {
f.destroy();
}
}
function add() {
document.getElementById('test-area').insertAdjacentHTML('beforeend', '<p class="test">Click me</p>');
}
window.addEventListener('load', function() {
document.body.addEventListener('click', function(event) {
var clicksEl = document.getElementById('clicks');
clicks.value = parseInt(clicks.value, 10) + 1;
if (event.target.classList.contains('test')) {
event.target.style.backgroundColor = event.target.style.backgroundColor ? '' : 'YellowGreen';
}
}, false);
document.getElementById('create').addEventListener('click', create, false);
document.getElementById('destroy').addEventListener('click', destroy, false);
document.getElementById('add').addEventListener('click', add, false);
}, false);
</script>
<title>#26</title>
</head>
<body>
<input type="button" id="create" value="Create new FastClick instance" /><br />
<input type="button" id="destroy" value="Destroy last FastClick instance" /><br />
<hr />
<p>Clicks: <input type="text" id="clicks" value="0" /></p>
<hr />
<input type="button" id="add" value="Add element" />
<hr />
<div id="test-area"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
.page { position: absolute; width: 200px; height: 150px; background-color:#eee; }
.page.next { background-color:#ccc; }
#btn { background-color:#ff00ff; }
#text {width: 100%; padding: 0; margin: 0; border: none; font-size: 22px; }
.animate { -webkit-transition: all .3s ease-out; }
</style>
<title>#27</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript" src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script type="application/javascript">
$(window).load(function() {
$(function() {
new FastClick(document.body);
$nextpage = $('.page.next');
$nextpage.css('-webkit-transform', 'translate(200px, 0) translateZ(0)');
$('#btn').click(function(e){
$('.page.next').addClass('animate').css('-webkit-transform', 'translate(0, 0) translateZ(0)');
});
});
});
</script>
</head>
<body>
<p>Clicking or tapping the <code>div</code> that says 'click me' should <em>not</em> trigger focus on the adjacent <code>input</code> element as or after it slides in.</p>
<div class="pages">
<div class="page">
<div id="btn">Click Me</div>
</div>
<div class="next page">
<input id="text" type="text" value="textbox 1">
<input id="text" type="text" value="textbox 2">
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p, label { font-family: sans-serif; }
label { display: inline-block; background: silver; padding: 0 1em; line-height: 2em; }
.test { margin: 2em 0; }
</style>
<title>#30</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<p>FastClick is instantiated on the document body. Tap a label for the associated input control to gain focus. Focus should be equally fast in all tests.</p>
<div class="test">
<label><input type="text"> Descendant association</label>
</div>
<div class="test">
<input type="text" id="test-text"> <label for="test-text">Attribute association</label>
</div>
<div class="test">
<label><input type="checkbox"> Descendant association</label>
</div>
<div class="test">
<input type="checkbox" id="test-checkbox"> <label for="test-checkbox">Attribute association</label>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
textarea { width: 25em; height: 15em; }
</style>
<title>#32</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
Array.prototype.forEach.call(document.getElementsByClassName('button'), function(button) {
button.addEventListener('click', function(event) {
console.log(event.target.nodeName + ' was tapped (forwarded: ' + (event.forwardedTouchEvent ? 'yes' : 'no') + ')');
}, false);
});
}, false);
</script>
</head>
<body>
<div class="appt-search-form no-height">
<div class="fancy">
<input type="hidden" class="apptPatient" name="patient" value="5004" data-shadow="false">
<div class="ui-hide-label">
<label for="apptType" class="ui-select">Appointment Type</label>
<div class="ui-select">
<div data-corners="true" data-shadow="false" data-iconshadow="true" data-wrapperels="span" data-icon="th-list" data-iconpos="right" data-theme="a" class="ui-btn ui-btn-corner-all ui-btn-icon-right ui-btn-up-a">
<span class="ui-btn-inner ui-btn-corner-all">
<span class="ui-btn-text">
<span class="apptType">Appointment Type *</span>
</span>
<span class="ui-icon ui-icon-th-list ui-icon-shadow">&nbsp;</span>
</span>
<select class="apptType" name="apptType" id="apptType" data-shadow="false" data-icon="th-list">
<option value="-1" data-placeholder="true">Appointment Type</option>
<option value="5000">Sick Visit</option>
<option value="5509">9 months Well Visit</option>
<option value="5512">1 year Well Visit</option>
<option value="5515">15 months Well Visit</option>
<option value="5518">18 months Well Visit</option>
</select>
</div>
</div>
<label for="apptCalendar" class="ui-select">Physician</label>
<div class="ui-select">
<div data-corners="true" data-shadow="false" data-iconshadow="true" data-wrapperels="span" data-icon="user-md" data-iconpos="right" data-theme="a" class="ui-btn ui-btn-up-a ui-btn-corner-all ui-btn-icon-right">
<span class="ui-btn-inner ui-btn-corner-all">
<span class="ui-btn-text">
<span class="apptCalendar">Physician</span>
</span>
<span class="ui-icon ui-icon-user-md ui-icon-shadow">&nbsp;</span>
</span>
<select class="apptCalendar" id="apptCalendar" data-shadow="false" data-icon="user-md">
<option value="-1" data-placeholder="true">Physician</option>
<option value="-1">Any</option>
<option value="5000">Dr. Jim</option>
<option value="5001">Dr. Wixler</option>
<option value="5002">Anya</option>
<option value="5003">Jada</option>
</select>
</div>
</div>
<label for="dateAfter" class="ui-input-text">Date</label>
<input class="dateAfter ui-input-text ui-body-a ui-corner-all ui-shadow-inset" id="dateAfter" type="date" data-icon="calendar">
<label for="apptTimeWindow" class="ui-select">Time of Day</label>
<div class="ui-select">
<div data-corners="true" data-shadow="false" data-iconshadow="true" data-wrapperels="span" data-icon="time" data-iconpos="right" data-theme="a" class="ui-btn ui-btn-up-a ui-btn-corner-all ui-btn-icon-right">
<span class="ui-btn-inner ui-btn-corner-all">
<span class="ui-btn-text">
<span class="apptTimeWindow">Time of Day</span>
</span>
<span class="ui-icon ui-icon-time ui-icon-shadow">&nbsp;</span>
</span>
<select class="apptTimeWindow" id="apptTimeWindow" data-shadow="false" data-icon="time">
<option value="0" data-placeholder="true">Time of Day</option>
<option value="0">Any</option>
<option value="1">Morning</option>
<option value="2">Afternoon</option>
<option value="3">Evening</option>
</select>
</div>
</div>
</div>
</div>
<span class="search btn-success">
<div data-corners="true" data-shadow="true" data-iconshadow="true" data-wrapperels="span" data-icon="null" data-iconpos="null" data-theme="a" class="ui-btn ui-shadow ui-btn-corner-all ui-btn-up-a" aria-disabled="false">
<span class="ui-btn-inner ui-btn-corner-all">
<span class="ui-btn-text">Find Appointments</span>
</span>
<button class="btn-success ui-btn-hidden" aria-disabled="false">Find Appointments</button>
</div>
</span>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>#36</title>
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="telephone=no" name="format-detection" />
<style type="text/css">
p { font-family: sans-serif; }
input { height: 30px; }
p, input { margin: 0; padding: 0; }
</style>
<script src="../lib/fastclick.js" type="application/javascript"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<p>A tap and long hold, then release on input #1 will sometimes trigger focus on #2.</p>
<hr />
<form>
<p><input placeholder="1" name="i1" /></p>
<p><input placeholder="2" name="i2" /></p>
<p><input placeholder="3" name="i3" /></p>
<p><input placeholder="4" name="i4" /></p>
<p><input placeholder="5" name="i5" /></p>
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
</style>
<title>#37-reduced</title>
<script>
window.addEventListener('load', function() {
document.getElementById('frame').contentDocument.body.innerHTML = '<input type="text" id="text" ontouchend="this.focus();" />';
}, false);
</script>
</head>
<body>
<p>On tapping the text input in the iframe and enter text, the entered text will not appear until the text input is tapped again. After that, tapping the text input a third time while it is still focus it will seem to disable text entry completely.</p>
<iframe id="frame"></iframe>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="robots" content="NOINDEX, NOFOLLOW">
<style type="text/css">
p { font-family: sans-serif; }
* { box-sizing: border-box; }
*:focus { border: 5px solid blue; }
</style>
<title>#37</title>
</head>
<body>
<p>On touching/clicking the input field within the iframe, you should be able to input text normally.</p>
<iframe src="37b.html"></iframe>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="robots" content="NOINDEX, NOFOLLOW">
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
<style type="text/css">
p { font-family: sans-serif; }
* { box-sizing: border-box; }
*:focus { border: 5px solid red; }
</style>
<title>IFrame Page</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<input type="text" id="mytext" name="mytext" />
</body>
</html>
<!doctype html>
<html>
<head>
<title>#42</title>
<meta charset='utf-8' />
<meta name="viewport" content="initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<meta name='apple-mobile-web-app-capable' content='yes' />
<!--
MUST be viewed on an iOS 5+ device
This is a layout for iOS 5+.
The basic idea is to have a navigation bar that always pins to the top.
The lower part is a scrollable content wrapper (with momemtum scrolling).
Here, we apply FastClick to the content wrapper.
Now when you scroll the content really fast, and click the link before the scrolling stops.
Chances are what you have clicked is not what see under your finger, but rather the link which lay at that position sometime during your scroll.
-->
<style>
#everything {
position: absolute;
display: -webkit-box;
-webkit-box-orient: vertical;
height: 100%;
}
#content {
-webkit-box-flex: 1;
}
#content {
overflow: scroll;
position: relative;
-webkit-overflow-scrolling: touch;
}
#content > * {
-webkit-transform: translate3d(0,0,0);
}
a {
display: block;
background: #aaa;
padding: 10px 0;
margin: 5px 0;
height: 200px;
font-size: 22px;
line-height: 200px;
vertical-align: center;
text-align: center;
}
#everything {
width: 100%;
margin: 0 auto;
}
#content {
width: 100%;
}
</style>
<script src="../lib/fastclick.js"></script>
<script>
window.addEventListener('load', function() {
new FastClick(document.getElementById('content'))
document.addEventListener('touchstart', function(event) {
console.log('start @ ' + event.pageY);
}, false);
document.addEventListener('touchmove', function(event) {
console.log('move @ ' + event.pageY);
}, false);
document.addEventListener('touchend', function(event) {
console.log('end @ ' + event.pageY);
}, false);
document.addEventListener('click', function(event) {
if (event.target.tagName.toLowerCase() === 'a') {
console.log('clicked ' + event.target.textContent);
}
}, false);
}, false);
</script>
</head>
<body>
<div id="everything">
<div id="content" class="ios5">
<a>1</a>
<a>2</a>
<a>3</a>
<a>4</a>
<a>5</a>
<a>6</a>
<a>7</a>
<a>8</a>
<a>9</a>
<a>10</a>
<a>11</a>
<a>12</a>
<a>13</a>
<a>14</a>
<a>15</a>
<a>16</a>
<a>17</a>
<a>18</a>
<a>19</a>
<a>20</a>
<a>21</a>
<a>22</a>
<a>23</a>
<a>24</a>
<a>25</a>
<a>26</a>
<a>27</a>
<a>28</a>
<a>29</a>
<a>30</a>
<a>31</a>
<a>32</a>
<a>33</a>
<a>34</a>
<a>35</a>
<a>36</a>
<a>37</a>
<a>38</a>
<a>39</a>
<a>40</a>
<a>41</a>
<a>42</a>
<a>43</a>
<a>44</a>
<a>45</a>
<a>46</a>
<a>47</a>
<a>48</a>
<a>49</a>
<a>50</a>
<a>51</a>
<a>52</a>
<a>53</a>
<a>54</a>
<a>55</a>
<a>56</a>
<a>57</a>
<a>58</a>
<a>59</a>
<a>60</a>
<a>61</a>
<a>62</a>
<a>63</a>
<a>64</a>
<a>65</a>
<a>66</a>
<a>67</a>
<a>68</a>
<a>69</a>
<a>70</a>
<a>71</a>
<a>72</a>
<a>73</a>
<a>74</a>
<a>75</a>
<a>76</a>
<a>77</a>
<a>78</a>
<a>79</a>
<a>80</a>
<a>81</a>
<a>82</a>
<a>83</a>
<a>84</a>
<a>85</a>
<a>86</a>
<a>87</a>
<a>88</a>
<a>89</a>
<a>90</a>
<a>91</a>
<a>92</a>
<a>93</a>
<a>94</a>
<a>95</a>
<a>96</a>
<a>97</a>
<a>98</a>
<a>99</a>
<a>100</a>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>#36</title>
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="telephone=no" name="format-detection" />
<style type="text/css">
p { font-family: sans-serif; }
input { height: 30px; }
p, input { margin: 0; padding: 0; }
#map {width: 450px; height: 400px; }
</style>
<script src="http://maps.google.com/maps/api/js?sensor=false&.js" type="application/javascript"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/tags/infobox/1.1.9/src/infobox.js" type="application/javascript"></script>
<script src="../lib/fastclick.js" type="application/javascript"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
var map;
var elevator;
var myOptions = {
zoom: 6,
center: new google.maps.LatLng(46.87916, -3.32910),
mapTypeId: 'terrain'
};
map = new google.maps.Map(document.getElementById('map'), myOptions);
var markers = [];
// Add a listener for idle event and call getElevation on a random set of marker in the bound
google.maps.event.addListener(map, 'idle', function()
{
var marker = new google.maps.Marker({
position: new google.maps.LatLng(46.87916, -3.32910),
map: map,
title:"Hello World!"
});
var infowindow = new InfoBox({
content: "Touch me on your iDevice"
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
});
}, false);
</script>
</head>
<body>
<p>Tap the map marker.</p>
<hr />
<div id="map"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="robots" content="NOINDEX, NOFOLLOW">
<meta name="viewport">
<style type="text/css">
p { font-family: sans-serif; }
body { margin: 10em; }
</style>
<title>#45</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
//new FastClick(document.body);
}, false);
</script>
</head>
<body>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum at bibendum urna. Sed pellentesque felis eget massa luctus convallis. Duis posuere imperdiet velit, a vulputate elit pulvinar nec. Quisque eleifend sollicitudin quam, ac sodales turpis tincidunt sed. Donec ac hendrerit dui. Vestibulum vel tortor purus, a tempus purus. Nam dictum urna a lectus dapibus porttitor. <a href="#">Integer lobortis</a>, massa sit amet consequat rhoncus, purus justo lacinia ante, vitae suscipit lectus dui eu augue. Nulla ut imperdiet arcu. Morbi sapien dui, condimentum sed iaculis eu, accumsan pellentesque risus. Ut interdum mollis feugiat.</p>
<p>Nullam aliquet adipiscing sagittis. Duis adipiscing pellentesque semper. Maecenas sollicitudin porttitor ipsum, ac blandit sapien tristique eget. Donec sit amet nulla elit. In hac habitasse platea dictumst. Duis cursus mollis nulla, a sagittis lectus convallis vitae. Suspendisse vestibulum arcu sem. Ut eleifend nisi ac sapien iaculis sed tempor felis accumsan. Integer quis sapien massa, sed ullamcorper mi.</p>
<p>Aenean rutrum vehicula lobortis. Maecenas eleifend, augue quis elementum tincidunt, metus eros pulvinar odio, eget faucibus erat magna lacinia sapien. Pellentesque ullamcorper dolor ut <a href="#">ipsum fringilla</a> cursus. Integer gravida augue ac elit placerat hendrerit. Sed eget nisl justo, nec bibendum nunc. Aenean non nunc felis. Nullam semper, felis at venenatis bibendum, justo mauris laoreet ipsum, at tristique risus dui id eros. Aliquam erat volutpat.</p>
<p>Aliquam nunc enim, cursus id malesuada sed, vestibulum quis libero. Vivamus accumsan lacus sit amet libero tempor laoreet. Donec convallis, enim ac mattis luctus, nunc dolor rutrum neque, non auctor sem est nec lorem. Cras bibendum dui nec ante semper fermentum. Sed sollicitudin porttitor lorem vitae fermentum. Morbi vitae massa et diam gravida consequat. Nulla semper, leo vitae pharetra commodo, justo eros luctus velit, eget molestie neque mi nec turpis.</p>
<p>Fusce urna orci, molestie vitae blandit et, pellentesque in ante. Etiam mattis ultricies ligula, et scelerisque diam venenatis id. In dignissim molestie interdum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis vehicula eros non tortor tristique non euismod urna laoreet. Curabitur mauris tellus, dapibus non blandit a, ultrices vitae purus. Morbi at diam lectus. Donec et purus a diam rutrum aliquam nec ac dolor. Donec quis dolor molestie quam lacinia mattis. Sed euismod condimentum quam sit amet accumsan.</p>
<p>Etiam accumsan ipsum vel nulla vulputate eleifend. Nullam vestibulum pulvinar consectetur. Aliquam erat volutpat. Curabitur nunc nisl, ultrices posuere accumsan sed, bibendum a nulla. Donec ac justo vitae orci fermentum euismod. Sed elit risus, <a href="#">rhoncus</a> et egestas vitae, feugiat eu sapien. Nam tempus, dolor quis venenatis pellentesque, lacus quam fringilla enim, non tristique dolor nulla vel eros. Quisque luctus, dolor id consectetur pharetra, mauris leo congue felis, at vehicula augue lacus id quam. Donec euismod laoreet hendrerit.</p>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html ng-app="strap">
<head>
<title>#48</title>
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="telephone=no" name="format-detection" />
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/css/bootstrap.min.css" rel="stylesheet">
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/css/bootstrap-responsive.min.css" rel="stylesheet">
<style type="text/css">
body { margin: 2em; }
p { font-family: sans-serif; }
input { height: 30px; }
.container { position: absolute; }
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script src="https://raw.github.com/mgcrea/angular-strap/master/dist/angular-strap.min.js"></script>
<script src="../lib/fastclick.js"></script>
<script>
var app = angular.module('strap', ['$strap.directives']);
app.controller('StrapCtrl', function($scope) {
$scope.dropdown = [
{text: 'Another action', href: '#anotherAction'},
{text: 'Something else here', href: '#', click: 'modal.saved=true'},
{divider: true},
{text: 'Separated link', href: '#', submenu: [
{text: 'Second level link', href: '#'},
{text: 'Second level link 2', href: '#'}
]
}
];
});
window.addEventListener('load', function() {
new FastClick(document);
}, false);
</script>
</head>
<body>
<p>The dropdown should stay open after tapping the button once.</p>
<hr>
<div class="container" ng-controller="StrapCtrl">
<!-- Button to trigger dropdown -->
<button type="button" class="btn" bs-dropdown="dropdown">Dropdown</button>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
</style>
<title>#51-reduced</title>
<script>
document.addEventListener('touchstart', function() {}, false);
window.addEventListener('load', function() {
document.getElementById('frame').contentDocument.body.innerHTML = '<input type="text" />';
}, false);
</script>
</head>
<body>
<p>Tap the input twice in succession and try to type.</p>
<iframe id="frame"></iframe>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
textarea { width: 25em; height: 15em; }
</style>
<title>#6</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
Array.prototype.forEach.call(document.getElementsByClassName('button'), function(button) {
button.addEventListener('click', function(event) {
console.log(event.target.nodeName + ' was tapped (forwarded: ' + (event.forwardedTouchEvent ? 'yes' : 'no') + ')');
}, false);
});
}, false);
</script>
</head>
<body>
<textarea>FastClick is instantiated on the document body. Tap this textarea to gain focus.</textarea>
<p>Open the browser console to see debug info.</p>
<input type="button" class="button" value="Now tap this <input> button">
<br><br>
<button class="button">Now tap this &lt;button&gt; button</button>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p, label { font-family: sans-serif; }
label > a { display: inline-block; background: silver; padding: 0 1em; line-height: 2em; pointer-events: none; }
.test { margin: 2em 0; }
</style>
<title>#60</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<p>FastClick is instantiated on the document body. A <code>label</code> element is wrapped around an anchor element. Tapping the anchor element should cause the label's the associated input control to gain focus.</p>
<p>This works because the CSS rule <code>label > a { pointer-events: none; }</code> is being used.</p>
<div class="test">
<input type="text" id="test-input"> <label for="test-input"><a href="#">Tap here</a></label>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p, label { font-family: sans-serif; }
</style>
<title>#62</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<p>Tapping a disabled checkbox should not change its value.</p>
<input type="checkbox" id="cb" disabled>
<label for="cb">Label for a disabled checkbox</label>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
input { display: inline; }
</style>
<title>#68</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<p>On iOS, tapping either of the inputs should open the media selection dialog normally.</p>
<hr>
<input type="file" multiple="true">
<input type="file">
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<meta charset=utf-8 />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<style type="text/css">
body {
font-size: 16px;
}
#form {
width: 400px;
border: 1px solid black;
border-radius: 14px;
padding: 20px;
box-sizing: border-box;
}
#form textarea {
width: 200px;
height: 100px;
}
#form .buttons {
margin-top: 20px;
text-align: right;
}
</style>
<title>#6b</title>
<script type="application/javascript">
$(function() {
var clicks = 0;
$('body').on('click', 'button', function() {
$('#report').text("click " + (++clicks));
});
new FastClick(document.body);
});
</script>
</head>
<body>
<p>This test case is designed for Chrome on Android 4.1 on the Nexus 7.</p>
<p>Tap the <code>textarea</code> so that it gains focus. The browser should zoom the page. Once that happens the coordinates for every tap will be off until the page is zoomed back to the normal level.</p>
<div id="form">
<div id="report">&nbsp;</div>
<textarea></textarea>
<div class="buttons">
<button>Hello World</button>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sed mauris in nisi dignissim ultricies sit amet id sapien. Curabitur venenatis, justo sed iaculis molestie, velit nisl consectetur metus, at vulputate nulla nisl et urna. Ut et urna a mauris malesuada mollis non vel ante. Nulla volutpat tellus sed elit varius ultricies. Nam euismod pellentesque felis sed adipiscing. Morbi ultricies risus a diam blandit a tincidunt tellus rhoncus. Cras facilisis pulvinar ante vitae pretium. Ut non orci sem. Integer fringilla est in tortor consectetur porta. Mauris ullamcorper neque sed arcu ultrices accumsan. Morbi condimentum metus eu sem volutpat auctor. Nam posuere fermentum est sed aliquet. Maecenas mauris mauris, auctor hendrerit pellentesque eget, fringilla et nibh. Pellentesque euismod urna sed eros feugiat egestas. Pellentesque volutpat viverra sapien, in tincidunt ipsum tempor pharetra. Suspendisse fermentum posuere luctus.</p>
<p>Duis sed accumsan est. Etiam augue odio, vulputate a sollicitudin et, ornare ultricies massa. Nullam non lectus velit. Morbi consectetur pretium elit sed mollis. Sed id sem risus, vitae dapibus diam. Proin arcu metus, interdum nec pulvinar sed, auctor nec turpis. Aenean tempus, turpis sit amet pulvinar dapibus, erat arcu ornare enim, sit amet ornare lacus enim ut mauris. Pellentesque hendrerit fermentum massa vitae hendrerit. Morbi et velit libero. Nulla a fermentum nibh.</p>
<p>Aliquam orci turpis, dictum et rhoncus ac, imperdiet in enim. Nullam at nunc neque, a mollis urna. Phasellus gravida metus vitae turpis tempus vitae dictum ante sodales. Etiam lobortis vulputate ipsum, nec tincidunt velit volutpat nec. Pellentesque odio nibh, mattis vitae ultricies a, porta quis sapien. Curabitur rhoncus, erat ac bibendum porta, ante turpis semper nibh, porta dapibus urna ligula eu lorem. Cras lectus mi, volutpat a rhoncus et, faucibus non nibh. Ut non leo vitae tellus malesuada pharetra eget vitae lorem. Maecenas semper laoreet elit, non pulvinar leo mollis at. Mauris at rhoncus augue. Pellentesque ornare sodales nulla vitae pretium. Vivamus tempus suscipit neque vel auctor.</p>
<p>Maecenas blandit facilisis nulla a dignissim. In sem nulla, tincidunt id congue nec, volutpat a magna. Cras eleifend porta sodales. Suspendisse felis eros, aliquet sed faucibus sed, lacinia pretium magna. Vestibulum consequat neque non dui malesuada tempus. Quisque pharetra tristique elit consectetur tincidunt. Aenean justo ipsum, lacinia vitae fringilla nec, pulvinar at massa. Integer a mauris ligula, in adipiscing nisl. Curabitur urna massa, luctus non ullamcorper ut, auctor ac mauris. Curabitur malesuada sem ut ipsum pellentesque eu consectetur magna egestas. Vestibulum lorem nibh, iaculis id iaculis eget, imperdiet eget lorem. Nunc quis lorem lorem.</p>
<p>Quisque vel molestie nibh. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec ornare luctus sapien, vel scelerisque augue adipiscing in. Donec faucibus lobortis sollicitudin. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi rutrum sapien ut eros consequat dapibus. Etiam enim ligula, accumsan nec vestibulum sit amet, fermentum scelerisque est. Nunc in tincidunt quam. Praesent vitae sagittis odio. Aliquam malesuada, eros at adipiscing auctor, felis enim elementum magna, eget gravida arcu nisi ac enim. Pellentesque id vehicula velit. Aliquam dignissim, risus a adipiscing dapibus, nunc turpis adipiscing ligula, dictum sagittis augue ipsum non lacus. Curabitur felis elit, ullamcorper et gravida eget, elementum sed mauris. Maecenas luctus interdum molestie.</p>
<div class="buttons">
<button>Hello again</button>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="robots" content="NOINDEX, NOFOLLOW">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p { font-family: sans-serif; }
</style>
<title>#7</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<h1><a name="click">Click</a></h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum at bibendum urna. Sed pellentesque felis eget massa luctus convallis. Duis posuere imperdiet velit, a vulputate elit pulvinar nec. Quisque eleifend sollicitudin quam, ac sodales turpis tincidunt sed. Donec ac hendrerit dui. Vestibulum vel tortor purus, a tempus purus. Nam dictum urna a lectus dapibus porttitor. <a href="#click">Integer lobortis</a>, massa sit amet consequat rhoncus, purus justo lacinia ante, vitae suscipit lectus dui eu augue. Nulla ut imperdiet arcu. Morbi sapien dui, condimentum sed iaculis eu, accumsan pellentesque risus. Ut interdum mollis feugiat.</p>
<p>Nullam aliquet adipiscing sagittis. Duis adipiscing pellentesque semper. Maecenas sollicitudin porttitor ipsum, ac blandit sapien tristique eget. <a href="#click">Donec sit amet</a> nulla elit. In hac habitasse platea dictumst. Duis cursus mollis nulla, a sagittis lectus convallis vitae. Suspendisse vestibulum arcu sem. <a href="#click">Ut eleifend nisi ac sapien</a> iaculis sed tempor felis accumsan. Integer quis sapien massa, sed ullamcorper mi.</p>
<p>Aenean rutrum vehicula lobortis. Maecenas eleifend, augue quis elementum tincidunt, metus eros pulvinar odio, eget faucibus erat magna lacinia sapien. Pellentesque ullamcorper dolor ut <a href="#click">ipsum fringilla</a> cursus. Integer gravida augue ac elit placerat <a href="#click">hendrerit</a>. Sed eget nisl justo, nec bibendum nunc. Aenean non nunc felis. Nullam semper, felis at venenatis bibendum, justo mauris laoreet ipsum, at tristique risus dui id eros. Aliquam erat volutpat.</p>
<p>Aliquam nunc enim, cursus id malesuada sed, vestibulum quis libero. Vivamus accumsan lacus sit amet libero tempor laoreet. Donec convallis, enim ac <a href="#click">mattis luctus</a>, nunc dolor rutrum neque, non auctor sem est nec lorem. Cras bibendum dui nec ante semper fermentum. Sed sollicitudin porttitor lorem vitae fermentum. Morbi vitae massa et diam gravida consequat. Nulla semper, leo vitae pharetra commodo, justo eros <a href="#click">luctus velit</a>, eget molestie neque mi nec turpis.</p>
<p>Fusce urna orci, molestie vitae blandit et, pellentesque in ante. Etiam mattis ultricies ligula, et scelerisque diam venenatis id. In dignissim molestie interdum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis vehicula <a href="#click">eros non tortor</a> tristique non euismod urna laoreet. Curabitur mauris tellus, dapibus non blandit a, ultrices vitae purus. Morbi at diam lectus. Donec <a href="#click">et purus a diam rutrum aliquam nec</a> ac dolor. Donec quis dolor molestie quam lacinia mattis. Sed euismod condimentum quam sit amet accumsan.</p>
<p>Etiam accumsan ipsum vel nulla vulputate eleifend. Nullam vestibulum pulvinar consectetur. Aliquam erat volutpat. Curabitur nunc nisl, ultrices posuere accumsan sed, bibendum a nulla. Donec ac justo vitae orci fermentum euismod. Sed elit risus, <a href="#click">rhoncus</a> et egestas vitae, feugiat eu sapien. Nam tempus, dolor quis venenatis pellentesque, lacus quam fringilla enim, non tristique dolor nulla vel eros. <a href="#click">Quisque luctus</a>, dolor id consectetur pharetra, mauris leo congue felis, at vehicula augue lacus id quam. Donec euismod laoreet hendrerit.</p>
<p>Phasellus eget sem tellus, id pulvinar nulla. Ut metus metus, mattis a adipiscing eget, elementum sit amet diam. Aliquam augue mi, tristique vel vestibulum eget, volutpat consectetur libero. Proin lacinia molestie tellus, nec tincidunt justo venenatis vitae. Vestibulum <a href="#click">laoreet lacus in lacus</a> hendrerit eleifend. Quisque metus sem, consequat scelerisque gravida nec, dapibus et diam. Praesent scelerisque arcu eu dolor lacinia non imperdiet metus pretium. Nunc consequat urna id sem rutrum id ultrices felis lacinia. Morbi varius porta neque at adipiscing. Praesent quis rutrum mi. Aenean a <a href="#click">libero erat</a>, quis fermentum velit.</p>
<p>Donec quis dui a tortor sagittis faucibus nec nec turpis. Suspendisse dictum adipiscing augue, id sodales lectus rutrum varius. Donec a dolor tellus, non aliquet lacus. Cras tempor scelerisque mattis. Suspendisse potenti. Nam elit nulla, <a href="#click">adipiscing eget</a> hendrerit eu, dignissim a ante. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse felis urna, porta non <a href="#click">fermentum in</a>, fermentum sed lacus. Morbi ac leo augue. In quis <a href="#click">ligula lacus</a>. Duis nunc libero, laoreet eu consequat at, blandit ullamcorper enim.</p>
<p>Proin id lacus ac dui lobortis vehicula eu vulputate leo. Sed bibendum tempor luctus. Mauris tincidunt orci viverra lacus varius sodales <a href="#click">rutrum ante tempor</a>. Aliquam a ipsum at urna fringilla pulvinar sit amet non neque. Nulla quis aliquam risus. Nunc dui diam, vulputate eu hendrerit malesuada, bibendum fringilla purus. Nunc vitae elit ligula. Cum sociis natoque penatibus et magnis dis parturient montes, <a href="#click">nascetur ridiculus mus</a>.</p>
<p>Quisque interdum consequat nulla ac facilisis. Sed <a href="#click">aliquam egestas risus</a> at laoreet. Aenean a adipiscing enim. Sed varius, metus non ultrices dignissim, justo felis molestie nunc, in porta orci odio et lacus. Donec semper lorem feugiat dui pharetra sit amet <a href="#click">faucibus</a> felis pretium. Etiam aliquet convallis nibh, sed viverra dolor tempus id. Fusce eget nunc vitae odio pretium eleifend. Maecenas diam ligula, euismod at rhoncus vel, dictum eget lorem. Maecenas et metus odio, <a href="#click">iaculis suscipit nulla</a>.</p>
<p>Duis feugiat consectetur quam porttitor sodales. Mauris ornare sem sit amet lorem imperdiet posuere. Integer et consequat ante. Maecenas hendrerit pretium vulputate. <a href="#click">Nullam dictum</a>, mi vitae molestie molestie, lectus dolor gravida turpis, vel bibendum nisl eros ut massa. Aliquam egestas velit non arcu volutpat pretium molestie ipsum sollicitudin. Sed fermentum, neque eget lacinia varius, tellus felis ornare nibh, in placerat lectus ligula sed sapien. <a href="#click">Nulla tincidunt eleifend</a> leo ut commodo. Integer id ante sit amet nunc <a href="#click">scelerisque sodales</a>. Donec tincidunt, sem blandit accumsan venenatis, odio sem sagittis nunc, eget semper mauris diam vitae arcu. Aliquam rutrum ante ut lorem iaculis interdum.</p>
<p>Proin consectetur ligula sed enim cursus viverra. Curabitur posuere augue ac enim dictum ullamcorper. Etiam eu quam tellus, id ultrices velit. Duis malesuada pharetra orci eu aliquam. Curabitur interdum <a href="#click">adipiscing nibh</a> ut pellentesque. Integer vulputate lorem vitae lacus dictum a laoreet ipsum semper. Etiam eget ante at nunc imperdiet consequat et vitae nisl. <a href="#click">Nulla ornare risus ac</a> ante sollicitudin ut egestas libero pellentesque. Ut imperdiet erat a massa pulvinar vel dictum erat interdum. Donec ut orci tempus nibh elementum lobortis id in sapien. Etiam vitae turpis mauris. Nam sit amet ipsum at arcu auctor varius. Suspendisse <a href="#click">venenatis nisi at nisl</a> tempus eget pretium massa interdum.</p>
<p>Pellentesque dignissim ante elit. Quisque eget justo ante. Quisque semper dictum lorem, eget feugiat lacus tristique vel. Duis metus lacus, malesuada sed viverra ac, <a href="#click">mollis nec lacus</a>. Curabitur vitae neque vel mi varius fermentum eget sed tortor. Praesent id nisi vitae purus ultrices viverra. Nulla felis purus, pharetra et semper ac, adipiscing et sapien. Morbi ornare accumsan nulla vel accumsan. <a href="#click">Fusce id nisl a risus</a> dignissim scelerisque.
<p>Mauris ornare consectetur feugiat. <a href="#click">Aliquam eu leo sit amet</a> augue rhoncus lobortis. Vivamus in dui eget risus aliquam fermentum. Nullam egestas enim non odio venenatis commodo. Curabitur sapien enim, pulvinar dignissim scelerisque a, fringilla sed ante. Phasellus venenatis, libero et mollis ornare, tellus eros accumsan quam, lobortis consequat nulla est ac mauris. Ut purus mauris, <a href="#click">blandit</a> sit amet semper at, consectetur sit amet enim. Nam rhoncus eros ac enim pretium sit amet porttitor quam aliquam. Donec mollis nibh at nisi accumsan sodales rhoncus purus vulputate. Donec egestas lacinia eros vitae iaculis. Proin at lectus velit. Praesent leo justo, ultrices ut pellentesque ac, porta a neque.</p>
<p>Quisque <a href="#click">bibendum auctor orci</a>, eu placerat nibh accumsan quis. Phasellus et nisi lorem, et eleifend magna. Quisque nibh eros, volutpat ut congue nec, laoreet sit amet est. Aliquam metus tellus, porta ac tempus nec, consectetur luctus ligula. Quisque dapibus massa quis ligula vestibulum mollis. <a href="#click">Pellentesque sit amet</a> molestie est. Nullam eget purus nec ipsum volutpat eleifend eu at justo. Aenean pretium ullamcorper ipsum, fringilla pulvinar ante dignissim id. Fusce viverra, nisl vitae ultricies luctus, lectus magna pulvinar magna, ac fringilla tortor purus vitae lacus. <a href="#click">Mauris vestibulum pretium</a> leo, ut rutrum felis ornare ac.</p>
<p>Praesent nec dui at <a href="#click">turpis pulvinar lacinia</a>. Mauris ut sem justo, at accumsan sapien. Sed vitae ante lectus, in suscipit nisi. In mattis turpis quis arcu dapibus in ornare enim vestibulum. Fusce interdum <a href="#click">laoreet nulla</a>, lacinia hendrerit libero eleifend ac. Ut et <a href="#click">tellus a ipsum</a> facilisis consectetur. Nulla pretium, nulla sed tristique elementum, arcu quam feugiat nunc, vitae dictum urna magna vitae nibh. Vivamus porta, lectus in <a href="#click">ultricies facilisis</a>, felis velit commodo libero, nec tempor urna arcu ac ligula. Nunc gravida, urna ut commodo gravida, mi nisl malesuada diam, aliquam fringilla turpis tellus id nibh. Vestibulum et arcu ut enim elementum imperdiet vel sed mauris. <a href="#click">Vivamus euismod elit</a> in purus lobortis tincidunt.</p>
<p>Donec facilisis ullamcorper eros id euismod. <a href="#click">Cras fermentum augue</a> ac purus dictum sit amet vulputate ipsum lacinia. Donec dignissim diam quis orci semper rhoncus. Integer in nisl leo. Nam a quam sed erat tempus hendrerit quis vel nibh. In hac habitasse platea dictumst. Vivamus eu nunc consectetur sem vestibulum malesuada in sit amet lacus. Proin a nulla sed est varius facilisis sed ut diam. <a href="#click">Curabitur cursus faucibus</a> rutrum. Nunc malesuada tempor arcu facilisis posuere. Nullam vitae sem erat. Morbi hendrerit nulla eu justo rutrum porttitor. Quisque congue tincidunt <a href="#click">metus in aliquam</a>. Duis non enim non metus rutrum posuere ac sit amet urna.</p>
<p>Vestibulum nisi urna, <a href="#click">gravida ac porta</a> rutrum, cursus quis magna. <a href="#click">Donec condimentum congue convallis</a>. Ut semper pellentesque nibh ac ullamcorper. Nunc rutrum purus ac purus imperdiet gravida tempor nunc lobortis. Duis at diam vitae arcu dignissim scelerisque quis quis elit. Proin adipiscing ipsum id risus pellentesque eu feugiat velit tincidunt. <a href="#click">Aliquam feugiat lacus</a> vel ipsum aliquam venenatis. Sed laoreet laoreet molestie. Integer feugiat dictum ipsum, eu dictum elit convallis nec. Nulla aliquet vulputate mattis. Suspendisse quam nulla, ultricies hendrerit <a href="#click">pretium euismod</a>, fringilla id felis.</p>
<p>Mauris quis posuere eros. <a href="#click">Mauris dapibus</a> lacinia interdum. Aenean feugiat eleifend ultricies. Phasellus faucibus, urna non vestibulum lobortis, mi leo pulvinar velit, at placerat arcu tortor a lectus. Sed varius porta enim ut faucibus. Suspendisse sit amet condimentum nunc. <a href="#click">Aenean fermentum</a> enim vel augue gravida quis eleifend enim rutrum. Nunc posuere, <a href="#click">dolor</a> ac bibendum tempor, sapien elit aliquet nibh, sit amet tincidunt nibh nunc ut libero. Donec elit tortor, pretium et lobortis et, dapibus sed nunc. Sed non velit dui. Proin vestibulum sapien eget neque congue eget elementum diam convallis. Ut erat sapien, gravida vitae rutrum non, aliquet at ipsum. Vestibulum nisi lacus, pharetra cursus dapibus at, <a href="#click">volutpat in est</a>. In elit justo, tristique sit amet ullamcorper vitae, fringilla et augue. Nam sit amet aliquam orci.</p>
<p>Aenean rutrum malesuada purus. <a href="#click">Nullam et tempor magna</a>. In imperdiet tempor magna, in dignissim felis tempus nec. Pellentesque consectetur felis nec eros venenatis nec adipiscing est vehicula. Aliquam volutpat luctus erat, id bibendum sem <a href="#click">fermentum elementum</a>. Fusce dignissim nisi a orci porta a pretium erat tincidunt. Curabitur consequat elementum volutpat. Vestibulum aliquet mattis <a href="#click">libero vitae tincidunt</a>.</p>
<p>Nam est odio, iaculis in semper sit amet, <a href="#click">faucibus vitae lorem</a>. Pellentesque ut augue risus, quis sagittis dolor. Vivamus accumsan fermentum libero in adipiscing. Nullam in fringilla lorem. <a href="#click">Mauris ac sapien</a> in diam vehicula porta. Cras mauris urna, pretium nec iaculis sodales, sollicitudin vitae odio. Phasellus gravida nunc egestas eros feugiat rhoncus. <a href="#click">Vestibulum pretium</a>, ligula at mattis venenatis, odio leo feugiat ante, vitae rutrum nisi ante sit amet nulla. Mauris eget pharetra enim. Praesent venenatis, libero ut imperdiet sollicitudin, <a href="#click">neque odio</a> dictum urna, nec gravida nunc ligula euismod mi. Nulla molestie nunc id diam venenatis lobortis. Nulla consequat, justo eget gravida luctus, dolor ipsum faucibus eros, eget <a href="#click">eleifend justo nulla vel massa</a>.</p>
<p>Sed tempus, odio sed elementum aliquet, eros augue <a href="#click">adipiscing nisl</a>, a vehicula lacus dui non elit. In hac habitasse platea dictumst. Duis faucibus adipiscing volutpat. Phasellus justo enim, rutrum adipiscing egestas eu, vulputate ut quam. Duis pharetra erat quis massa ultricies commodo. Integer accumsan pharetra dolor in condimentum. Vestibulum nisl mi, placerat et lacinia ac, <a href="#click">convallis ac sapien</a>. Duis luctus leo ligula. Aliquam rhoncus lacus id quam congue malesuada. Suspendisse scelerisque porttitor ultrices. Nam hendrerit luctus augue. Nam sit amet nisl enim, nec fringilla dui. <a href="#click">Fusce in purus mauris</a>. Mauris facilisis malesuada neque in porttitor. Nam in ante justo, ultrices pulvinar orci. Class aptent taciti sociosqu ad litora torquent per conubia nostra, <a href="#click">per inceptos himenaeos</a>.</p>
<p>Nulla et luctus urna. <a href="#click">Fusce rhoncus ipsum</a> ac magna dictum eleifend. Duis pretium orci nec quam lobortis a varius urna fermentum. Donec scelerisque imperdiet mauris, ut fringilla diam commodo in. Fusce tincidunt tincidunt quam, <a href="#click">ut rhoncus tellus</a> tincidunt vitae. Mauris interdum iaculis magna et ultricies. Nam blandit diam eu neque fermentum malesuada euismod augue blandit. Fusce a magna et ante <a href="#click">posuere viverra non eu sem</a>. Praesent sodales lectus vel dolor convallis ornare. Nunc quam erat, accumsan a mollis sit amet, tincidunt interdum nisl.</p>
<p>Praesent <a href="#click">pellentesque ultrices</a> nisl, sit amet mattis felis rhoncus in. Nam id urna non dolor molestie viverra non hendrerit tortor. Donec placerat tellus eget diam egestas in aliquam nibh vulputate. Nulla iaculis libero nec erat vehicula luctus malesuada ut arcu. Suspendisse eget ipsum ipsum. <a href="#click">Proin augue dui</a>, posuere non auctor sed, convallis eget massa. Praesent tristique, massa in tempor blandit, augue mi volutpat leo, id vestibulum leo erat vitae metus. <a href="#click">Etiam tortor mauris</a>, ultrices a tristique eget, semper non dui. Fusce est arcu, egestas nec volutpat a, mollis id eros.</p>
<p><a href="#click">Curabitur ut urna</a> felis, vitae egestas eros. Etiam luctus, ante in auctor tincidunt, ipsum nisi sollicitudin ligula, vel tempus ipsum nibh ac velit. Ut commodo purus nec quam aliquet gravida. Phasellus cursus, urna sit amet tincidunt elementum, massa dui venenatis turpis, <a href="#click">consectetur eleifend</a> justo lectus suscipit felis. Suspendisse neque nulla, pellentesque volutpat malesuada at, dignissim at augue. Integer in sagittis odio. Fusce mi erat, ultrices quis condimentum eget, rhoncus at enim. Nam porttitor ante sed purus iaculis vel suscipit metus ornare. Aenean enim nulla, rhoncus sed varius ut, pretium eget augue. <a href="#click">Cras non laoreet odio</a>. Proin egestas, urna quis ultrices facilisis, nisl velit pulvinar quam, sed varius lacus erat eu nisi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices <a href="#click">posuere cubilia Curae</a>; In fringilla lobortis ornare.</p>
<p>Cras faucibus mollis erat, sed <a href="#click">vestibulum metus</a> feugiat in. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed nec cursus tortor. Suspendisse sit amet nunc felis, nec imperdiet neque. Vestibulum ante ipsum primis in faucibus orci luctus et <a href="#click">ultrices posuere</a> cubilia Curae; Nulla at nisi ut nisl vestibulum volutpat. Donec sit amet sem et ante consectetur bibendum. Cum sociis natoque penatibus et magnis <a href="#click">dis parturient montes</a>, nascetur ridiculus mus. Praesent varius molestie ligula, quis fringilla felis consectetur sed. Aliquam aliquam accumsan vehicula. Nam nec libero at <a href="#click">nisl aliquet iaculis</a>. Vestibulum viverra risus non arcu laoreet scelerisque. Ut sit amet ipsum ac enim varius ultricies.</p>
<p>Sed facilisis lobortis <a href="#click">urna vitae fringilla</a>. Morbi eu felis tincidunt nisi elementum bibendum sed vel lorem. Phasellus semper eleifend enim, eget tincidunt justo lobortis quis. Maecenas sit amet metus ligula. Sed vehicula nunc et justo commodo commodo. Nullam sodales <a href="#click">risus eu est eleifend</a> blandit. Maecenas ultrices interdum sagittis.</p>
<p>Etiam ultrices, diam ut <a href="#click">sagittis ullamcorper</a>, magna orci tempus augue, a ultrices nisi odio vel quam. Quisque sed purus sit amet erat lacinia placerat. Nunc eu libero felis, non cursus metus. Ut sodales euismod imperdiet. Cras imperdiet nulla nisl. Mauris dignissim adipiscing justo eu venenatis. <a href="#click">Etiam pellentesque nibh metus</a>, in porta leo. <a href="#click">Nulla at tortor nunc</a>, ut sagittis neque. Vivamus eu augue dui, nec scelerisque sem. Praesent ac felis turpis, id viverra purus.</p>
<p>Nulla leo nisl, <a href="#click">porttitor bibendum convallis</a> ac, vulputate id nisl. Morbi et dapibus nunc. Aliquam erat volutpat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur aliquet nisi ac nulla scelerisque volutpat. <a href="#click">Mauris nec sem id</a> enim imperdiet semper. Suspendisse eget felis mauris, a hendrerit nibh. Cras blandit velit quis lacus aliquet placerat. In hac habitasse platea dictumst. Morbi sollicitudin, magna vitae convallis ultricies, <a href="#click">urna metus faucibus nisi</a>, sed placerat turpis lorem nec metus. <a href="#click">Duis non risus</a> ac diam tempus ultrices quis sit amet ante. Vivamus condimentum imperdiet turpis et fringilla. Suspendisse arcu enim, pretium id imperdiet eget, lacinia sed ipsum. Mauris pretium rhoncus orci sit amet porttitor.</p>
<p>Nulla lorem massa, dapibus a rutrum eget, tempor id diam. Aenean pellentesque dictum risus, eget egestas enim varius a. In interdum faucibus nibh tempor sollicitudin. Phasellus ac metus non odio lacinia ultricies. Cras malesuada pulvinar lorem quis commodo. Fusce massa <a href="#click">purus</a>, placerat a fermentum a, commodo vitae magna. Donec sed magna urna. Proin adipiscing molestie lacinia. Integer tellus est, cursus ut rhoncus non, <a href="#click">pretium sed neque</a>. Nullam aliquet tempor ligula et scelerisque.</p>
<p>Morbi accumsan tellus justo. <a href="#click">Donec elementum</a>, turpis luctus malesuada rhoncus, eros justo tempor lectus, viverra vulputate lectus nulla in purus. Sed id porttitor ipsum. Vestibulum rhoncus, lectus sed dapibus porttitor, sapien felis luctus enim, eu tempor ligula felis nec leo. Vestibulum leo quam, fringilla quis blandit eget, convallis eget orci. Cras a mi velit, vitae molestie turpis. <a href="#click">Ut nisi est</a>, malesuada faucibus egestas eget, fermentum a mi. Sed porta vehicula sem, at laoreet erat vulputate nec. Sed dapibus tincidunt venenatis. <a href="#click">Nulla facilisis consequat</a> ante, a euismod leo interdum vel. Morbi facilisis velit leo, non aliquam neque. Pellentesque vestibulum, sem id auctor euismod, nisl nisl posuere nisi, <a href="#click">ut sodales nisl</a> lorem nec mi.</p>
<p>Sed libero purus, <a href="#click">malesuada vitae accumsan</a> sit amet, dignissim sed justo. Ut varius urna aliquam ante euismod vitae egestas nisi consectetur. Aliquam neque eros, molestie eget rutrum eget, faucibus eget tortor. Nullam porta, tortor eget sagittis interdum, velit lacus varius risus, vitae lobortis purus dui pretium purus. In id mauris neque, vitae tincidunt dui. Ut vel justo nisi, at hendrerit dolor. <a href="#click">Aenean ac nibh nec</a> est blandit feugiat. Fusce lorem leo, vehicula in tristique vitae, consectetur nec nulla.</p>
<p>Vivamus felis lorem, laoreet vel mattis eget, aliquet eu neque. Morbi sed tortor sit amet nunc <a href="#click">ornare</a> elementum. Nunc arcu quam, fringilla eget tincidunt sit amet, gravida suscipit metus. Suspendisse venenatis erat vitae massa posuere lobortis. Nullam a mattis nisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam at rutrum lacus. <a href="#click">Morbi id tellus mi</a>, a venenatis nibh. Sed egestas, lectus vitae scelerisque euismod, velit dui malesuada ligula, et laoreet urna lectus quis tellus. Morbi diam urna, molestie in auctor quis, dapibus id massa. Praesent consequat, quam vel mollis tempus, nulla orci vehicula mi, non pharetra sapien elit ut magna. Etiam mi magna, porta quis hendrerit vitae, c<a href="#click">onvallis bibendum risus</a>. Integer quis nulla velit. Duis consectetur consectetur turpis. Pellentesque a porttitor eros. Quisque blandit sem eget odio varius pellentesque.</p>
<p>Ut gravida ultrices nulla, non congue nisi gravida ut. Donec neque dolor, pharetra nec elementum laoreet, <a href="#click">dictum</a> sit amet tellus. Nulla id blandit mi. Nullam ipsum justo, pellentesque a hendrerit ac, cursus ac arcu. Proin feugiat tempus adipiscing. Aliquam erat volutpat. Suspendisse mauris neque, aliquet a <a href="#click">tempor lacinia</a>, pretium eget mauris.</p>
<p>Vivamus <a href="#click">facilisis erat vel</a> sem tempor tincidunt. Fusce tortor enim, tempus eu fermentum vitae, ultrices sollicitudin diam. Phasellus luctus interdum tempus. Sed facilisis laoreet quam ac luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris arcu mauris, vestibulum vel condimentum eget, faucibus vel magna. Curabitur posuere vestibulum tortor. Vivamus quis mollis turpis. <a href="#click">Donec congue</a>, enim in interdum tincidunt, quam enim varius enim, eu aliquet sapien orci quis nulla. Nulla aliquam libero convallis urna interdum scelerisque a in massa. Nunc volutpat, nulla non tincidunt lacinia, nibh turpis congue arcu, et ornare lectus ligula at risus. Etiam adipiscing, nisl nec tempor convallis, elit erat sollicitudin mi, eget adipiscing erat eros nec nulla. Praesent lorem felis, <a href="#click">pretium a pretium eu</a>, varius sit amet nibh.</p>
<p>Morbi in tellus quis <a href="#click">sapien condimentum</a> pretium nec quis tellus. Duis at turpis mi. Donec ornare feugiat tortor consequat ultricies. Quisque iaculis, dui bibendum volutpat gravida, nibh velit tincidunt justo, ornare <a href="#click">imperdiet libero nunc</a> sed elit. Vivamus dapibus nunc nec purus scelerisque id rhoncus mauris laoreet. Donec ac diam non mauris tincidunt pharetra at vitae ante. Aliquam erat volutpat. <a href="#click">Cum sociis natoque penatibus</a> et magnis dis parturient montes, nascetur ridiculus mus.</p>
<p>Ut et lectus justo. Nunc rhoncus, justo nec porta varius, enim elit molestie tortor, in sagittis ipsum diam at tellus. Suspendisse sit amet lorem diam, vel venenatis orci. Nulla pharetra condimentum blandit. Donec rutrum vestibulum mauris. Nunc sit amet nibh id orci <a href="#click">convallis</a> ornare sit amet id leo. Sed eros nulla, malesuada nec mattis commodo, rhoncus ut urna. Mauris justo leo, dignissim non sodales ac, ullamcorper mollis felis. Sed turpis erat, dapibus sit amet gravida quis, ultricies tincidunt ligula. Praesent vitae massa non urna tempor commodo. Quisque eget iaculis magna. Fusce ut ligula eget libero luctus fermentum dapibus vitae nisi.</p>
<p>Quisque ultricies <a href="#click">suscipit lorem et blandit</a>. Quisque elit sem, suscipit eu lacinia nec, mollis in nulla. Curabitur auctor ipsum turpis, a tempor neque. Sed at justo ac turpis venenatis lacinia. <a href="#click">Sed rhoncus</a>, nibh eu porta tincidunt, odio nulla condimentum est, eget adipiscing turpis felis sed mauris. Fusce tincidunt nisl eget purus viverra vel congue nunc tristique. Duis at ornare risus. Proin pharetra lobortis turpis quis vulputate. Suspendisse potenti. <a href="#click">Proin non neque augue</a>. Suspendisse eu luctus ipsum. <a href="#click">Vivamus viverra</a> pellentesque quam a fringilla. Vivamus bibendum, urna sed scelerisque scelerisque, sapien velit blandit ipsum, sed feugiat elit enim vel quam. Phasellus eleifend commodo elit, et blandit eros faucibus nec.</p>
<p>Sed viverra magna eu <a href="#click">enim euismod sagittis</a>. Cras urna est, adipiscing sed feugiat quis, auctor in sapien. Mauris id magna tincidunt nisl imperdiet viverra. Quisque at suscipit lectus. Nam et cursus augue. Phasellus id dolor lacus, non vestibulum purus. Ut feugiat ante at velit euismod vel lacinia magna iaculis. Nulla sit amet nibh diam. Proin <a href="#click">consequat feugiat</a> sollicitudin. Nam urna neque, mattis non tincidunt et, <a href="#click">elementum vel nisi</a>. Curabitur sit amet justo id magna porta pharetra eget a libero. Morbi sollicitudin, dolor a laoreet venenatis, augue sem sollicitudin purus, eu iaculis odio elit nec sem. Mauris laoreet est nec lectus vulputate euismod. Vestibulum accumsan faucibus tortor non semper. <a href="#click">Nunc ullamcorper eros</a> vitae leo fermentum et ullamcorper magna tincidunt.</p>
<p>Sed molestie luctus elit at cursus. <a href="#click">Mauris eget massa dolor</a>, ac hendrerit ante. Nam vulputate consectetur blandit. Praesent porttitor suscipit diam, in volutpat magna rhoncus tempus. Vestibulum ac diam et mi adipiscing tempus. Aenean et tempus tortor. Mauris non erat et elit venenatis congue a id lorem. Integer leo tortor, vehicula id fringilla eget, volutpat ut eros. <a href="#click">Mauris in augue</a> eget felis rutrum congue.</p>
<p>In aliquet nisl vel libero molestie sed iaculis metus sollicitudin. Nam suscipit augue <a href="#click">laoreet lectus vulputate</a> a dictum tellus tristique. <a href="#click">Cras vitae magna ac</a> tortor scelerisque ultrices eget pulvinar ligula. Aenean viverra imperdiet ipsum vitae pulvinar. Morbi eu ante nec lorem <a href="#click">euismod scelerisque</a>. Class aptent taciti sociosqu ad litora <a href="#click">torquent per conubia</a> nostra, per inceptos himenaeos. Nunc et elit metus, at ornare risus. Cras sit amet ligula scelerisque arcu viverra ultricies sed iaculis nunc. Nulla sodales sem ut magna semper tincidunt. Morbi aliquam scelerisque arcu, at ultricies quam adipiscing non. Phasellus eu pretium magna. <a href="#click">Aliquam ut sem</a> sit amet dolor rutrum feugiat. Nullam vehicula ultrices mattis. Phasellus dapibus tristique bibendum. Class aptent taciti sociosqu ad litora torquent per <a href="#click">conubia nostra</a>, per inceptos himenaeos. Vestibulum euismod imperdiet malesuada.</p>
<p>Donec <a href="#click">tincidunt scelerisque elit</a>, vitae convallis nisl viverra a. Sed a vehicula nisl. Nullam et ipsum sed ligula posuere consequat. Suspendisse id tellus velit. Quisque nec mi urna. Nulla neque mauris, bibendum a faucibus at, tincidunt at erat. Nulla diam mi, <a href="#click">luctus eget adipiscing</a> sagittis, commodo in tellus. Donec ante massa, vestibulum quis hendrerit eget, sagittis in augue. Ut vehicula, risus vulputate aliquet lobortis, lectus enim tincidunt risus, quis porttitor magna sem vel lacus. Curabitur ornare scelerisque libero, adipiscing pulvinar libero accumsan et. Duis rutrum <a href="#click">dignissim orci quis</a> tincidunt. Maecenas scelerisque, sapien porttitor consequat auctor, felis lacus adipiscing odio, sit amet lacinia <a href="#click">ipsum nulla eget</a> tellus.</p>
<p>Curabitur <a href="#click">sollicitudin nisl quis</a> odio euismod mollis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Nulla facilisi. Aenean convallis vulputate leo, vel interdum <a href="#click">orci placerat eu</a>. Vestibulum hendrerit pretium ipsum, eu <a href="#click">aliquet</a> nisl accumsan condimentum. Duis elementum porttitor consequat. Morbi imperdiet vehicula massa, id pellentesque ligula venenatis vel. Donec non felis suscipit <a href="#click">sem ornare mollis</a>. Nulla elit quam, posuere vel tincidunt vitae, porttitor quis felis.</p>
<p>Nam tempus lectus <a href="#click">a est ornare ac aliquet</a> felis placerat. Ut vel dolor ut turpis auctor imperdiet id non velit. Vestibulum sodales commodo dui. Aenean posuere dolor nec lorem malesuada ut ornare quam feugiat. Donec ut neque nec odio <a href="#click">ullamcorper vestibulum</a>. Nulla pulvinar leo consectetur ante ullamcorper pellentesque. Sed sed porttitor lacus. Pellentesque a nisl ut tortor sollicitudin dictum. Cum sociis <a href="#click">natoque penatibus et</a> magnis dis parturient montes, nascetur ridiculus mus. Etiam in ligula leo. Vivamus vel quam velit, laoreet dictum quam. Praesent congue, <a href="#click">diam nec volutpat pharetra</a>, nulla erat consequat lorem, quis condimentum risus nisl sit amet tellus. Sed ullamcorper, risus a consectetur dignissim, ligula augue pharetra nulla, <a href="#click">eget feugiat metus lacus</a> quis lectus. Praesent malesuada dictum nulla, nec malesuada erat ullamcorper vel.</p>
<p>Morbi <a href="#click">suscipit facilisis leo</a>, vitae eleifend nunc placerat sit amet. Suspendisse elit sem, bibendum vitae hendrerit nec, dictum sed sapien. Praesent fermentum mollis dapibus. Donec tempus risus ac odio dictum vel <a href="#click">ultrices eros convallis</a>. Aliquam a ipsum id lacus mollis dapibus. <a href="#click">Quisque at felis</a> purus, id tristique erat. In vel nisi at mi adipiscing tempor. Ut rhoncus semper ultricies. Sed ut urna quam, mollis cursus nisl.</p>
<p>Praesent nec diam a <a href="#click">mauris pellentesque mollis</a>. Integer tempor metus nec enim ultricies vehicula. Maecenas luctus tincidunt dui, quis feugiat ipsum lacinia a. Morbi non nulla sit amet mi accumsan venenatis sed ut elit. Aenean interdum est vitae justo sollicitudin sed dignissim lectus iaculis. <a href="#click">Integer magna lacus</a>, sollicitudin eu porta eget, condimentum id mauris. Praesent id facilisis lacus. Donec interdum nunc nulla. Cras sit amet purus est. <a href="#click">Ut mauris elit</a>, hendrerit nec vehicula nec, rhoncus ut lorem.</p>
<p>Etiam in tristique nisl. <a href="#click">Nam sed vehicula dui</a>. Vestibulum in purus ultrices nisl iaculis pretium. In vitae purus a <a href="#click">lectus elementum sodales</a> quis nec leo. Aliquam faucibus imperdiet tortor viverra iaculis. Mauris eu ipsum non turpis sollicitudin pretium sit amet vel dui. <a href="#click">Vestibulum ante ipsum</a> primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
<p>Vestibulum et arcu magna, <a href="#click">a tristique risus</a>. Donec luctus erat eget magna sodales rutrum. Praesent justo nunc, commodo eu pretium eget, consequat id augue. Cras sed blandit elit. Integer id eros nec diam facilisis dapibus. Aenean scelerisque sodales dolor sit amet posuere. <a href="#click">Donec viverra nibh</a> ut lorem egestas eget dignissim nunc consequat. <a href="#click">Curabitur facilisis</a>, lectus ac varius vestibulum, tortor dui tincidunt lectus, id elementum augue lacus ut dui.</p>
<p><a href="#click">Nam viverra ante nec eros</a> ullamcorper egestas. Mauris porta scelerisque leo in ullamcorper. Ut sit amet egestas augue. Sed at massa turpis. Mauris non tortor quis lorem vehicula interdum. Morbi tortor mauris, tristique quis rutrum ac, suscipit quis metus. Duis ante turpis, <a href="#click">malesuada in posuere ut</a>, cursus et massa. <a href="#click">Curabitur mi erat</a>, tincidunt laoreet molestie non, sollicitudin in libero. Curabitur at dui nunc. Donec consequat aliquet tristique.</p>
<p>Proin quis blandit magna. <a href="#click">In consectetur vehicula ante</a>, nec sodales elit hendrerit quis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas eleifend fermentum egestas. Quisque semper ornare blandit. Aliquam malesuada convallis placerat. <a href="#click">Nam lobortis</a>, sapien in pulvinar egestas, orci ante fermentum felis, et lobortis mauris justo condimentum odio. Pellentesque habitant morbi tristique senectus et <a href="#click">netus et malesuada fames</a> ac turpis egestas. Donec tristique, quam sodales auctor venenatis, sapien nisi aliquet dolor, eu feugiat tortor massa non nisl. Quisque interdum lacus ac massa consectetur interdum.</p>
</body>
</html>
\ No newline at end of file
<!doctype html>
<html>
<head>
<title>Fastclick test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
<script>
document.addEventListener('touchend', function() {}, false);
</script>
<style>
html {
font-size: 32px;
font-family: Helvetica, sans-serif;
}
body {
padding: 1em;
}
div {
margin-top: 50%;
height: 900px;
}
.button {
width: 100%;
color: #fff;
text-align: center;
text-decoration: none;
font-weight: 600;
background: #ff3b46;
padding: 1em;
}
.button:hover,
.button:active {
color: #fff;
background: #5091d2;
}
</style>
</head>
<body>
<div>
<a class="button" href="http://www.apple.com/">Test button</a>
</div>
</body>
</html>
\ No newline at end of file
<!doctype html>
<html>
<head>
<!-- Copied from: http://fastclick-issue83.aws.af.cm/ -->
<title>Fastclick test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type='application/javascript' src='../lib/fastclick.js'></script>
<script>
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
<style>
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html {
font-size: 32px;
font-family: Helvetica, sans-serif;
}
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
padding: 1em;
}
div {
margin-top: 50%;
height: 900px;
}
.button {
width: 100%;
color: #fff;
text-align: center;
text-decoration: none;
font-weight: 600;
background: #ff3b46;
padding: 1em;
display: inline-block;
position: relative;
border: 0;
cursor: pointer;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
-webkit-box-shadow: 0 0.18em 0 #931517;
-moz-box-shadow: 0 0.18em 0 #931517;
box-shadow: 0 0.18em 0 #931517;
}
.button:hover,
.button:active {
color: #fff;
text-decoration: none;
background: #5091d2;
-webkit-box-shadow: 0 0.18em 0 #36628d;
-moz-box-shadow: 0 0.18em 0 #36628d;
box-shadow: 0 0.18em 0 #36628d;
}
</style>
</head>
<body>
<div>
<a class="button" href="https://github.com/ftlabs/fastclick">Test button</a>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style type="text/css">
p, label { font-family: sans-serif; }
</style>
<title>#84</title>
<script type="application/javascript" src="../lib/fastclick.js"></script>
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
</script>
</head>
<body>
<p>Tapping the following read-only input field should show the alert message.</p>
<input type="text" id="readOnlyText" onclick="alert('read-only input tapped')" readonly>
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment