Class: SC.Touch
SC.Touch
Represents a touch. Single touch objects are passed to touchStart
, touchEnd
and touchCancelled
event handlers;
a specialized multitouch event object is sent to touchesDragged
, which include access to all in-flight touches
(see "The touchesDragged
Multitouch Event Object" below).
SC.Touch
exposes a number of properties, including pageX/Y, clientX/Y, screenX/Y, and startX/Y (the values that
pageX/Y had when the touch began, useful for calculating how far the touch has moved). It also exposes the touch's
target element at target
, its target SC.View
at targetView
, and the touch's unique identifier at identifier
,
which may be relied upon to identify a particular touch for the duration of its lifecycle.
A touch object exists for the duration of the touch – literally for as long as your finger is on the screen – and
is sent to a number of touch events on your views. Touch events are sent to the touch's current responder, set initially
by checking the responder chain for views which implement touchStart
(or captureTouch
, see "Touch Events" below),
and can be passed to other views as needed (see "Touch Responders" below).
Touch Events
You can use the following methods on your views to capture and handle touch events:
captureTouch
-- Sometimes, a touch responder part way up the chain may need to capture the touch and prevent it from being made available to itschildViews
. The canonical use case for this behavior isSC.ScrollView
, which by default captures touches and holds onto them for 150ms to see if the user is scrolling, only passing them on to children if not. (SeeSC.ScrollView
#delaysContentTouches for more.) In order to support this use case,captureTouch
bubbles the opposite way as usual: beginning with the target's pane and bubbling down towards the target itself.captureTouch
is passed a single instance ofSC.Touch
, and must returnYES
if it wishes to capture the touch and become its responder. (If your view doesn't want to immediately capture the touch, but instead wants to suggest itself as a fallback handler in case the child view resigns respondership, it can do so by passing itself to the touch'sstackCandidateTouchResponder
method.) -touchStart
-- When a touch begins, or when a new view responder is first given access to it (see "Touch Responders" below), the touch is passed to this method.touchesDragged
-- Whenever any touches move, thetouchesDragged
method is called on the current view responder for any touches that have changed. The method is provided two arguments: a special multitouch event object (see "ThetouchesDragged
Multitouch Event Object" below), and an array containing all of the touches on that view. (This is the same as callingtouch.touchesForView(this)
.)touchEnd
-- When a touch is complete, its current responder'stouchEnd
handler is invoked, if present, and passed the touch object which is ending.touchCancelled
-- This method is generally only called if you have changed the touch's responder. See "Touch Responders" below; in brief, if you pass the touch to another responder viamakeTouchResponder
, fully resigning your touch respondership, you will receive atouchCancelled
call for the next event; if you pass the touch to another responder viastackNextTouchResponder
, and never receive it back, you will receive atouchCancelled
call when the touch finishes. (Note that because RootResponder must calltouchStart
to determine if a view will accept respondership,touchStart
is called on a new responder beforetouchCancelled
is called on the outgoing one.)
The touchesDragged
Multitouch Event Object
The specialized event object sent to touchesDragged
includes access to all touches currently in flight. You can
access the touches for a specific view from the touchesForView
method, or get an average position of the touches
on a view from the convenient averagedTouchesForView
method. For your convenience when dealing with the common
single-touch view, the touchesDragged
event object also exposes the positional page, client, screen and start X/Y
values from the first touch. If you are interested in handling more than one touch, or in handling an average of
in-flight touches, you should ignore these values. (Note that this event object exposes an array of touch events at
touches
. These are the browser's raw touch events, and should be avoided or used with care.)
Touch Responders: Passing Touches Around
The touch responder is the view which is currently handling events for that touch. A touch may only have one responder
at a time, though a view with acceptsMultitouch: YES
may respond to more than one touch at a time.
A view becomes a touch responder by implementing touchStart
(and not returning NO). (Out-of-order views can capture
touch responder status by implementing captureTouch
and returning YES.)
Once a view is a touch responder, only that
view will receive subsequent touchesDragged
and touchEnd
events; these events do not bubble like mouse events, and
they do not automatically switch to other views if the touch moves outside of its initial responder.
In some situations, you will want to pass control on to another view during the course of a touch, for example if it goes over another view. To permanently pass respondership to another view:
if (shouldPassTouch) {
touch.makeTouchResponder(nextView);
}
This will trigger touchStart
on the new responder, and touchCancel
on the outgoing one. The new responder will begin
receiving touchesDragged
events in place of the outgoing one.
If you want to pass respondership to another view, but are likely to want it back – for example, when a ScrollView passes respondership to a child view but expects that the child view will pass it back if it moves more than a certain amount:
if (shouldTemporarlyPassTouch) { touch.stackNextTouchResponder(nextView); }
This will trigger touchStart
on the new responder, and it will start receiving touchesDragged
and touchEnd
events.
Note that the previous responder will not receive touchCancelled
immediately, since the touch may return to it before
the end; instead, it will only receive touchCancelled
when the touch is ended.
(If you would like to add a view as a fallback responder without triggering unnecessary calls to its touchStart
and
touchCancelled
events, for example as an alternative to returning YES
from captureTouch
, you can call
stackCandidateTouchResponder
instead.)
When the child view decides that the touch has moved enough to be a scroll, it should pass touch respondership back to the scroll view with:
if (Math.abs(touch.pageX - touch.startX) > 4) { touch.restoreLastTouchResponder(); }
This will trigger touchCancelled
on the second responder, and the first one will begin receiving touchDragged
events
again.
Defined in: touch.js
Field Summary
- ariaRole
- attributes
- body
- className
- classNames
- clientX
- clientY
- designer
- displayProperties
- encodeMethodName
- escapeHTML
- extendMethodName
- fileName
- hasEnded
- href
- identifier
- language
- pageX
- pageY
- ping
- rel
- screenX
- screenY
- startX
- startY
- tagName
- target
- targetView
- timeStamp
- touchResponder
- type
- velocityX
- velocityY
- view
- wantsAcceleratedLayer
Instance Methods
- allowDefault()
- array(key, val, func)
- averagedTouchesForView(view, addSelf)
- begin(object)
- bool(key, val)
- captureTouch(startingPoint, shouldStack)
- destroy()
- didCreateObject(object, attrs)
- didLoadDesign(designedObject, sourceObject, attrs)
- didLoadLocalization(designedObject, attrs)
- displayBody()
- emit()
- encode(key, val, func)
- end()
- fetch(store, query)
- fetchTargets(store, query)
- fetchTargetsDidComplete(request, opts)
- fetchTests(store, query)
- fetchTestsDidComplete(request, opts)
- find(nameOrUrl)
- hasAcceleratedLayer()
- hash(key, val, func)
- hreflang()
- includeSlices(dataSource, context, slices)
- init()
- js(key, val, transform)
- makeTouchResponder(responder, shouldStack, bubblesTo)
- mouseDown(evt)
- mouseDragged(evt)
- mouseMoved(evt)
- mouseUp(evt)
- number(key, val)
- object(key, val)
- preventDefault()
- render(context, firstTime)
- restoreLastTouchResponder()
- spaces()
- stackCandidateTouchResponder(responder)
- stackNextTouchResponder(view, upChain)
- stop()
- stopPropagation()
- string(key, val)
- toString()
- touchesForResponder(responder)
- touchesForView(view)
- transform(val, func)
Field Detail
ariaRole String- Default value:
- 'link'
The attributes that will be emitted. The values all must be strings. Use one of the encoding methods defined below to actually encode attributes.
Defined in: object.js.
The content of the anchor, such as text or an image.
Note that this will be escaped by default, so any HTML tags will appear
as text. To render the body as HTML, set escapeHTML
to false
and
remember to NEVER allow user generated content unescaped in your app.
If you are using text, you may also want to provide localized versions and
should set the localize
property to true.
Defined in: link_view.js.
- Default value:
- ""
The class names for the view.
Note: this is not an observed display property and as such must be predefined on the
view (You can update class names using classNameBindings
).
Note: this is a concatenated property and as such all subclasses will inherit the current class names.
Defined in: link_view.js.
- Default value:
- ['sc-view', 'sc-link-view']
The observed properties that will cause the view to be rerendered if they change.
Note: this is a concatenated property and as such all subclasses will inherit the current display properties.
Defined in: link_view.js.
- Default value:
- ['displayBody', 'displayToolTip', 'fileName', 'href', 'hreflang']
The default encoding method. If an object defines this method, then a new coder will be created to encode that object.
Defined in: object.js.
Whether the body and toolTip
will be escaped to avoid HTML injection attacks
or not.
You should only disable this option if you are sure you are displaying non-user generated text.
Note: this is not an observed display property. If you change it after
rendering, you should call displayDidChange
on the view to update the layer.
Defined in: link_view.js.
- Default value:
- true
The default file name to use for the linked resource if it will be downloaded.
For example,
//...
// The linked resource (/students/2013/list-copy.xml) will be downloaded
// with the name 'Student List.xml' by default.
fileName: 'Student List.xml',
href: '/students/2013/list-copy.xml'
//...
This property is observed, allowing you to programmatically set the download file name.
For example as a computed property,
//...
// The download file name is computed from the linked resource URL.
fileName: function () {
var href = this.get('href'),
linkedYear,
ret;
if (href) {
// ex. href == "/reports/2012/annual-report.pdf"
linkedYear = href.match(/\/(\d*)\//)[1];
ret = "Annual Report " + linkedYear + '.pdf';
}
return ret;
}.property('href').cacheable(),
hrefBinding: SC.Binding.oneWay('MyApp.reportController.hardlink'),
//...
Note: There are no restrictions on allowed values, but authors are cautioned that most file systems have limitations with regard to what punctuation is supported in file names, and user agents are likely to adjust file names accordingly. Also, support for this attribute varies widely between browsers.
Defined in: link_view.js.
- See:
- http://caniuse.com/#feat=download
- http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download
Whether the touch has ended yet. If you are caching touches outside of the RootResponder, it is your responsibility to check this property and handle ended touches appropriately.
- Default value:
- '#'
This touch's unique identifier. Provided by the browser and used to track touches through their lifetime. You will not usually need to use this, as SproutCore's touch objects themselves persist throughout the lifetime of a touch.
The alternate language for the linked resource.
Set this value to modify the 'hreflang' attribute for the linked resource, which would otherwise be the current locale's language.
Defined in: link_view.js.
- Default value:
- null
- See:
- http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-hreflang
An array of URLs to ping when the link is clicked.
For example, this can be used for tracking the use of off-site links without JavaScript or page redirects,
//...
// Whenever anyone downloads this resource, we ping our analytics site.
ping: ['http://tracker.my-app.com/?action="Downloaded PDF Version"'],
//...
Note: this is not an updateable display property. It must be defined before creating the layer.
Defined in: link_view.js.
- Default value:
- null
- See:
- http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#ping
A list of space separated non-case sensitive link type tokens.
For example,
//...
// This link is to the author of the article and the result should be loaded in the browser's sidebar if it has one.
rel: ['author', 'sidebar'],
//...
Note: this is not an updateable display property. It must be defined before creating the layer.
Defined in: link_view.js.
- Default value:
- null
- See:
- http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-rel
- http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#linkTypes
The tag type to use.
Note: this is not an updateable display property. It must be defined before creating the layer.
Defined in: link_view.js.
- Default value:
- 'a'
The timestamp of the touch's most recent event. This is the time as of when all of the touch's positional values are accurate.
The touch's current responder, i.e. the view that is currently receiving events for this touch.
You can use the following methods to pass respondership for this touch between views as needed:
makeTouchResponder
, stackNextTouchResponder
, restoreLastTouchResponder
, and stackCandidateTouchResponder
.
See each method's documentation, and "Touch Responders: Passing Touches Around" above, for more.
The touch's latest browser event's type, for example 'touchstart', 'touchmove', or 'touchend'.
Note that SproutCore's event model differs from that of the browser, so it is not recommended that you use this property unless you know what you're doing.
The touch's horizontal velocity, in pixels per millisecond, at the time of its last event. (Positive velocities indicate movement leftward, negative velocities indicate movement rightward.)
The touch's vertical velocity, in pixels per millisecond, at the time of its last event. (Positive velocities indicate movement downward, negative velocities indicate movement upward.)
Setting wantsAcceleratedLayer
to YES
will use transforms to move the
layer when available. On some platforms transforms are hardware accelerated.
Defined in: acceleration.js.
Instance Method Detail
Indicates that you want to allow the normal default behavior. Sets
the hasCustomEventHandling
property to YES
but does not cancel the event.
Encodes a array of objects. The object values must be simple objects for
this method to work. You can also optionally pass a processing function
that will be invoked for each value, giving you a chance to convert the
value first. The signature must be (index, value,
rootObject)
.
Defined in: object.js.
- Parameters:
- key
- {String} the key to set
- val
- {Object} the value
- func
- {Function} optional transform func
- Returns:
- SC.ObjectCoder
- receiver
Returns average data--x, y, and d (distance)--for the touches owned by the supplied view.
See notes on the addSelf
argument for an important consideration when calling from touchStart
.
- Parameters:
- view SC.Responder
- addSelf Boolean
- Includes the receiver in calculations. Pass YES for this if calling from touchStart, as the touch will not yet be included by default.
Begins encoding with a particular object, setting the className
to the
object's className
. This is used internally by the encode()
method.
Defined in: object.js.
- Parameters:
- object
Defined in: object.js.
- Parameters:
- key
- {String} the key to set
- val
- {Boolean} the value
- Returns:
- SC.ObjectCoder
- receiver
Captures, or recaptures, this touch. This works from the startingPoint
's first child up to the
touch's target view to find a view which implements captureTouch
and returns YES
. If the touch
is captured, then this method will perform a standard touchStart
event bubbling beginning with
the view which captured the touch. If no view captures the touch, then this method returns NO,
and you should call the makeTouchResponder
method to trigger a standard touchStart
bubbling
from the initial target on down.
You will generally not call this method yourself, instead exposing on
your view either a touchStart
event handler method, or a captureTouch
method which is passed a touch object and returns YES
. This method
is used in situations where touches need to be juggled between views,
such as when being handled by a descendent of a ScrollView.
- Parameters:
- startingPoint ?SC.Responder
- The view whose children should be given an opportunity to capture the event. (The starting point itself is not asked.)
- shouldStack Boolean
- Whether any capturing responder should stack with existing responders. Stacked responders are easy to revert via `SC.Touch#restoreLastTouchResponder`.
- Returns:
- Boolean
Whether the touch was captured. If it was not, you should pass it to
makeTouchResponder
for standard event bubbling.
Defined in: object.js.
Invoked whenver a object is created. This will create a peer designer if needed.
Defined in: object_designer.js.
- Parameters:
- object
- attrs
Invoked whenever a designed object is loaded. This will save the design attributes for later use by a designer.
Defined in: object_designer.js.
- Parameters:
- designedObject
- sourceObject
- attrs
Invoked whenever a location is applied to a designed object. Saves the attributes separately for use by the design object.
Defined in: object_designer.js.
- Parameters:
- designedObject
- attrs
Defined in: link_view.js.
Emits the final JavaScript output for this coder based on the current attributes.
Defined in: object.js.
Encodes an object. This will do its best to autodetect the type of the object. You can pass an optional processing function that will be used on object members before processing to allow you to normalize. The method signature must be:
function convert(value, rootObject, key);
The rootObject
and key will be set to give you the context in the
hierarchy.
Generally this method will work for encoding simple value only. If your object graph may contain SproutCore objects, you will need to encode it yourself.
Defined in: object.js.
- Parameters:
- key
- {String} the key to set
- val
- {Object} the value
- func
- {Function} optional transform func
- Returns:
- SC.ObjectCoder
- receiver
Fetch a group of records from the data source. Knows how to fetch a list of targets and tests.
Defined in: data_source.js.
- Parameters:
- store
- query
Defined in: data_source.js.
- Parameters:
- store
- query
Defined in: data_source.js.
- Parameters:
- request
- opts
Load tests for a particular URL. Only understands local querys with a URL.
Defined in: data_source.js.
- Parameters:
- store
- query
Defined in: data_source.js.
- Parameters:
- request
- opts
Find a stylesheet object by name or href. If by name, .css
will be
appended automatically.
var ss = SC.CSSStyleSheet.find('style.css') ;
var ss2 = SC.CSSStyleSheet.find('style') ; // same thing
sc_assert(ss === ss2) ; // SC.CSSStyleSheet objects are stable
Defined in: css_style_sheet.js.
- Parameters:
- nameOrUrl String
- a stylesheet name or href to find
- Returns:
- SC.CSSStyleSheet
- null if not found
Defined in: acceleration.js.
Encodes a hash of objects. The object values must be simple objects for
this method to work. You can also optionally pass a processing function
that will be invoked for each value, giving you a chance to convert the
value first. The signature must be (key, value,
rootObject)
.
Defined in: object.js.
- Parameters:
- key
- {String} the key to set
- val
- {Object} the value
- func
- {Function} optional transform func
- Returns:
- SC.ObjectCoder
- receiver
The language attribute of the linked resource.
This is the current locale's language by default, but may be overridden to
a specific other language by setting the language
property.
Defined in: link_view.js.
- See:
- http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-hreflang
Use this to render slices that you can match in CSS. This matches with the Chance @include slices directive, so that you can automatically do multi-slice images for controls.
Defined in: slicing.js.
- Parameters:
- dataSource SC.Object
- The data source for rendering information.
- context SC.RenderContext
- the render context instance
- slices Slice Configuration
- Instructions on how to slice. Can be a constant like SC.THREE_SLICE or SC.NINE_SLICE, or an array of slice names.
Defined in: object.js.
Encodes a string of raw JavaScript. This is the most primitive method. You are expected to prep the value yourself. You can pass an array to this or any other method and it will be encoded as a full array.
This method also automatically handles null and undefined values. Null values are included in the output. Undefined values are ignored.
Defined in: object.js.
- Parameters:
- key
- {String} the key to set
- val
- {String} the JavaScript
- transform
- {Function} optional transform function to apply to val
- Returns:
- SC.ObjectCoder
- receiver
Changes the touch responder for the touch. If shouldStack
is YES
,
the current responder will be saved so that the next responder may
return to it.
You will generally not call this method yourself, instead exposing on
your view either a touchStart
event handler method, or a captureTouch
method which is passed a touch object and returns YES
. This method
is used in situations where touches need to be juggled between views,
such as when being handled by a descendent of a ScrollView.
When returning control of a touch to a previous handler, you should call
restoreLastTouchResponder
instead.
- Parameters:
- responder SC.Responder
- The view to assign to the touch. (It, or if bubbling then an ancestor, must implement touchStart.)
- shouldStack Boolean
- Whether the new responder should replace the old one, or stack with it. Stacked responders are easy to revert via `SC.Touch#restoreLastTouchResponder`.
- bubblesTo Boolean|SC.Responder
- If YES, will attempt to find a `touchStart` responder up the responder chain. If NO or undefined, will only check the passed responder. If you pass a responder for this argument, the attempt will bubble until it reaches the passed responder, allowing you to restrict the bubbling to a portion of the responder chain. (Note that this responder will not be given an opportunity to respond to the event.)
- Returns:
- Boolean
- Whether a valid touch responder was found and assigned.
Defined in: selection_handles.js.
- Parameters:
- evt
Defined in: selection_handles.js.
- Parameters:
- evt
Defined in: selection_handles.js.
- Parameters:
- evt
Defined in: selection_handles.js.
- Parameters:
- evt
Defined in: object.js.
- Parameters:
- key
- {String} the key to set
- val
- {Number} the value
- Returns:
- SC.ObjectCoder
- receiver
Attempts to encode an object. The object must implement the
encodeMethodName
for this encoder, or else an exception will be raised.
Defined in: object.js.
- Parameters:
- key
- {String} the key to set
- val
- {Object} the object to encode
- Returns:
- SC.ObjectCoder
- receiver
If the touch is associated with an event, prevents default action on the event. This is the default behavior in SproutCore, which handles events through the RootResponder instead of allowing native handling.
Defined in: selection_handles.js.
- Parameters:
- context
- firstTime
A convenience method for returning touch respondership to the previous touch responder.
For example, if your view is in a ScrollView and has captured the touch from it, your view will prevent scrolling until you return control of the touch to the ScrollView with:
touchesDragged: function(evt, viewTouches) {
if (Math.abs(evt.pageY - evt.startY) > this.MAX_SWIPE) {
viewTouches.invoke('restoreLastTouchResponder');
}
}
Defined in: object.js.
You may want your view to insert itself into the responder chain as a fallback, but without
having touchStart
etc. called if it doesn't end up coming into play. For example, SC.ScrollView
adds itself as a candidate responder (when delaysTouchResponder
is NO) so that views can easily
give it control, but without receiving unnecessary events if not.
- Parameters:
- responder
A convenience method for making the passed view the touch's new responder, retaining the current responder for possible use later in the touch's lifecycle.
For example, if the touch moves over a childView
which implements its own touch handling,
you may pass the touch to it with:
touchesDragged
: function(evt, viewTouches
) {
if ([touches should be passed to childView
]) {
this.viewTouches.forEach(function(touch) {
touch.stackNextTouchResponder(this.someChildView);
}, this);
}
}
The child view may easily pass the touch back to this view with touch.restoreLastTouchResponder
. In the
mean time, this view will no longer receive touchesDragged
events; if the touch is not returned to this
view before ending, it will receive a touchCancelled
event rather than touchEnd
.
- Parameters:
- view SC.Responder
- The view which should become this touch's new responder.
- upChain Boolean
- Whether or not a fallback responder should be sought up the responder chain if responder doesn't capture or handle the touch.
Calls the native event's stopPropagation
method, which prevents the method from continuing to
bubble. Usually, SproutCore will be handling the event via delegation at the document
level,
so this method will have no effect.
Defined in: object.js.
- Parameters:
- key
- {String} the key to set
- val
- {String} the value
- Returns:
- SC.ObjectCoder
- receiver
- Parameters:
- responder
Returns all touches for a specified view. Put as a convenience on the touch itself; this method is also available on the event.
For example, to retrieve the list of touches impacting the current event handler:
touchesDragged: function(evt) {
var myTouches = evt.touchesForView(this);
}
- Parameters:
- view SC.Responder
Utility method transforms the passed value with the passed function.
Handles both Arrays and individual items.
Defined in: object.js.
- Parameters:
- val
- func