Extras Module
Install
npm install --save @ribajs/extras
Regist
To regist the module include import extrasModule from '@ribajs/extras';
in your main.ts
file and regist the module with riba.module.regist(extrasModule);
:
import { Riba, coreModule } from '@ribajs/core';
import { extrasModule } from '@ribajs/extras';
import { ready } from '@ribajs/utils/src/dom';
const riba = new Riba();
const model = {};
riba.module.regist(coreModule);
riba.module.regist(extrasModule);
ready(() => {
riba.bind(document.body, model);
});
Binders
data-scroll-position-y
Sets the scroll position ("top"
, "scrolled"
, "bottom"
) to the element as a data attribute, useful if you want to define styles depending on the scroll position.
Options can be passed via data attributes, e.g data-placement="right"
Name | Default | Description |
---|---|---|
data-offset-top |
10 |
Top offset, the scroll position is "top" as long as the scroll position is smaller than the top offset or 0 |
data-offset-bottom |
10 |
Bottom offset, the scroll position is "bottom" as long as the scroll position is on the end or just before according to the offset |
The binders value is a selector to the element you want to watch the scroll event for
Default | Description |
---|---|
'window' |
Can be 'window' for the Window object, 'this' for the current element or any selector like '#page-wrapper' |
An example style could be look like this
body:not([[data-scroll-position-y='top']) {
padding-top: 3em;
}
touch-events
Add this binder to an element to trigger additional touch events.
Then you can react to the events with the on-[event]
binder like this:
<div rv-touch-events rv-on-swiperight="nextPage">
...
</div>
This binder uses TouchEventsService
to trigger the additional events, check out the TouchEventsService to find out what additional events are available.
import { coreModule, Riba } from '@ribajs/core';
import { extrasModule } from '@ribajs/extras';
import { touchEventsModule } from './touch-events.module';
const riba = new Riba();
const model = {};
// Register modules
riba.module.regist(coreModule);
riba.module.regist(extrasModule);
riba.module.regist(touchEventsModule);
riba.bind(document.body, model);
<div class="row flex-column flex-md-row d-flex flex-nowrap h-100">
<!--rv-on-tapmove="log | args 'tapmove'"-->
<div
class="col-md-7 col-lg-8 col-xl-9 bg-light text-dark py-3 d-flex justify-content-center align-items-center touch-zone"
rv-touch-events
rv-on-tapstart="log | args 'tapstart'"
rv-on-tapend="log | args 'tapend'"
rv-on-tap="log | args 'tap'"
rv-on-tap2="log | args 'tap2'"
rv-on-tap3="log | args 'tap3'"
rv-on-singletap="log | args 'singletap'"
rv-on-doubletap="log | args 'doubletap'"
rv-on-taphold="log | args 'taphold'"
rv-on-swipe="log | args 'swipe'"
rv-on-swipeup="log | args 'swipeup'"
rv-on-swiperight="log | args 'swiperight'"
rv-on-swipedown="log | args 'swipedown'"
rv-on-swipeleft="log | args 'swipeleft'"
rv-on-swipeend="log | args 'swipeend'"
>
<span>Touch here</span>
</div>
<div class="col-md-5 col-lg-4 col-xl-3 bg-dark text-light py-3 h-100 console">
<p class="log">
<span class="no-data">Start touching to send data to this console.</span>
</p>
</div>
</div>
import { Component } from "@ribajs/core";
import { hasChildNodesTrim } from "@ribajs/utils/src/dom";
import template from "./touch-events-example.component.html";
export class TouchEventsExampleComponent extends Component {
public static tagName = "rv-touch-events-example";
protected autobind = true;
protected consoleElement: HTMLDivElement | null = null;
protected touchZoneElement: HTMLDivElement | null = null;
protected scope: any = {
log: this.log,
};
constructor(element?: HTMLElement) {
super(element);
}
public log(eventName: string, event: Event) {
// console.debug(eventName + ' called', event.type, (event as any), (event as any).detail);
if (this.consoleElement) {
let html = `<p class="log"><span class="name">${eventName}</span>`;
if ((event as any).detail && (event as any).detail.offset) {
html += `<span class="detail">(X: ${
(event as any).detail.offset.x
} Y: ${(event as any).detail.offset.y})</span>`;
}
html +=
'<span class="time">' + new Date().toLocaleTimeString() + "</span></p>";
this.consoleElement.insertAdjacentHTML("afterbegin", html);
}
}
protected connectedCallback() {
super.connectedCallback();
this.init([]);
}
protected async beforeBind() {
return super.beforeBind().then(() => {
this.consoleElement = this.el.querySelector(".console");
this.touchZoneElement = this.el.querySelector(".touch-zone");
});
}
protected template() {
// Only set the component template if there no childs already
if (hasChildNodesTrim(this.el)) {
return null;
} else {
return template;
}
}
}
scroll-events
Add this binder to an element to trigger additional scroll events.
Then you can react to the events with the on-[event]
binder like this:
<div rv-scroll-events rv-on-scrollended="showPopup">
...
</div>
This binder uses ScrollEventsService
to trigger additional scroll events on the element, check out the ScrollEventsService to find out what additional events are available.
import { coreModule, Riba } from '@ribajs/core';
import { extrasModule } from '@ribajs/extras';
import { extrasScrollEventsModule } from './extras-scroll-events.module';
const riba = new Riba();
const model = {};
// Register modules
riba.module.regist(coreModule);
riba.module.regist(extrasModule);
riba.module.regist(extrasScrollEventsModule);
riba.bind(document.body, model);
<div class="row flex-column flex-md-row d-flex flex-nowrap h-100">
<div
class="col-md-7 col-lg-8 col-xl-8 bg-light text-dark touch-zone"
rv-scroll-events
rv-scrollbar-draggable
rv-on-scrollstart="log | args 'scrollstart'"
rv-on-scrollended="log | args 'scrollended'"
rv-on-scrollend="log | args '(native scrollend)'"
rv-on-scroll="log | args '(native scroll)'"
>
<div class="touch-zone-background d-flex justify-content-center align-items-center h-100 w-100">Scroll here</div>
<div class="touch-space"></div>
</div>
<div class="col-md-6 col-lg-4 col-xl-4 bg-dark text-light py-3 h-100 console">
<p class="log">
<span class="no-data">Start touching to send data to this console.</span>
</p>
</div>
</div>
import { Component } from "@ribajs/core";
import { hasChildNodesTrim } from "@ribajs/utils/src/dom";
import template from "./extras-scroll-events-example.component.html";
export class ExtrasScrollEventsExampleComponent extends Component {
public static tagName = "rv-extras-scroll-events-example";
protected autobind = true;
protected consoleElement: HTMLDivElement | null = null;
protected touchZoneElement: HTMLDivElement | null = null;
protected scope: any = {
log: this.log,
};
constructor(element?: HTMLElement) {
super(element);
}
public log(eventName: string, event: Event) {
// console.debug(eventName + ' called', event.type, (event as any), (event as any).detail);
if (this.consoleElement) {
let html = `<p class="log"><span class="name">${eventName}</span>`;
const detail = (event as CustomEvent).detail;
if (detail && detail.position) {
html += `<span class="detail">(x: ${detail.position.x} y: ${detail.position.y} maxX: ${detail.position.maxX} maxY: ${detail.position.maxY})</span>`;
}
html +=
'<span class="time">' + new Date().toLocaleTimeString() + "</span></p>";
this.consoleElement.insertAdjacentHTML("afterbegin", html);
}
}
protected connectedCallback() {
super.connectedCallback();
this.init([]);
}
protected async beforeBind() {
return super.beforeBind().then(() => {
this.consoleElement = this.el.querySelector(".console");
this.touchZoneElement = this.el.querySelector(".touch-zone");
});
}
protected template() {
// Only set the component template if there no childs already
if (hasChildNodesTrim(this.el)) {
return null;
} else {
return template;
}
}
}
Services
TouchEventsService
The TouchEventsService
is a re-implementation of the beautiful jQuery Touch Events module in vanilla JavaScript (JQuery free).
Usage
Create a new instance of the TouchEventsService
with an Element as argument to trigger the touch events on this element:
import { TouchEventsService } from '@ribajs/extras';
const element = document.querySelector('.trigger-touch-events');
const touchEventService = new TouchEventsService(element);
element.addEventListener('swiperight' as any, (swipeEvent: CustomEvent) => {
console.debug('swiperight x amount', swipeEvent.detail.xAmount);
});
The Events
tapstart
Fired as soon as the user begins touching an element (or clicking, for desktop environments).tapend
Fired after the user releases their finger from the target element (or releases their mouse button on desktops).tapmove
Fired as soon as the user begins moving their finger on an element (or moving their mouse, for desktop environments).tap
This event is fired whenever the user taps and releases their finger on the target element. Caution should be observed when using this event in conjunction with tap events, especiallydoubletap
. This event will be fired twice whendoubletap
is used, so it is recommended to usesingletap
in this case.singletap
Unliketap
this event is only triggered once we are certain the user has only tapped the target element a single time. This will not be triggered bydoubletap
ortaphold
, unliketap
. Since we need to run some tests to make sure the user isn't double tapping or holding a tap on the target element, this event is fired with a short delay (currently of 500 milliseconds).doubletap
Triggered whenever the user double taps on the target element. The threshold (time between taps) is currently set at 500 milliseconds.taphold
This event is triggered whenever the user taps on the target element and leaves their finger on the element for at least 750 milliseconds.swipe
This is called whenever the user swipes their finger on the target element. It is not direction-dependent, and is fired regardless of the direction the user swiped.swipeup
Similar toswipe
, except only called when the user swipes their finger in an upward direction on the target element (i.e. bottom to top)swiperight
Similar toswipe
, but triggered only when the user swipes their finger left to right on the target element.swipedown
Similar toswipe
, but triggered only when the user swipes their finger top to bottom on the target element.swipeleft
Similar toswipe
, but triggered only when the user swipes their finger from right to left.swipeend
Theswipeend
event is trigged whenever a swipe event ends (i.e. the user finished moving their finger / cursor and released it). This event should be used to handle custom functions, since it will be triggered only when the swipe ends, rather than triggering immediately when the threshold has been met.
Event detail properties
Each event now features detail properties that can be accessed via the detail property. The detail property includes some basic data relating specifically to the event, and can be accessed as a standard JavaScript object. To hook into this properties, you should use the following code:
element.addEventListener('swipeend' as any, (event: CustomEvent) => {
console.debug('swipeend extra data', event.detail);
});
Given the example above, the detail object will now contain some basic data that can be accessed through event.detail
.. The event.detail.originalEvent
will represent the last native event that occurred.
Each event provides different extra data. The following shows the numerous data that has been assigned to the detail object:
tapstart
, tapend
, tapmove
, singletap
offset
- object containing the X and Y positions of the event relative to the element to which is was bound. Accessed through offset.x
and offset.y
respectively.
position
- object containing the X and Y positions of the event relative to the screen. Accessed through position.x
and position.y
respectively.
time
- JavaScript timestamp the event occurred (milliseconds since the Unix Epoch)
target
- the element from which the event was triggered.
originalEvent
- the the last native event that occurred.
tap
touches
- Array of object containing position
and offset
.
touches[i].offset
- object containing the X and Y positions of the event relative to the element to which is was bound. Accessed through offset.x
and offset.y
respectively.
touches[i].position
- object containing the X and Y positions of the event relative to the screen. Accessed through position.x
and position.y
respectively.
time
- JavaScript timestamp the event occurred (milliseconds since the Unix Epoch)
target
- the element from which the event was triggered.
originalEvent
- the the last native event that occurred.
taphold
touches
- Array of object containing position
and offset
.
touches[i].offset
- object containing the X and Y positions of the event relative to the element to which is was bound. Accessed through offset.x
and offset.y
respectively.
touches[i].position
- object containing the X and Y positions of the event relative to the screen. Accessed through position.x
and position.y
respectively.
duration
: the time in milliseconds that the user tapped for.
time
- JavaScript timestamp the event occurred (milliseconds since the Unix Epoch)
target
- the element from which the event was triggered.
originalEvent
- the the last native event that occurred.
doubletap
firstTap
- Object containing the same data as a tap
event, but for the first tap to occur.
secondTap
- Object containing the same data as a tap
event, but for the second (i.e. final) tap to occur.
interval
- the time in milliseconds between the two tap.
target
- the element from which the event was triggered.
originalEvent
- the the last native event that occurred.
swipe
, swipeup
, swiperight
, swipedown
, swipeleft
, swipeend
direction
- string representing the swipe direction (either up
, right
, down
or left
).
duration
- the time in milliseconds over which the swipe took place (for best results, use with swipeend
only, as this will typically be equal to the defined swipe-threshold
.
xAmount
- number of pixels the swipe occupied on the X-axis (returned regardless of direction).
yAmount
- number of pixels the swipe occupied on the Y-axis (returned regardless of direction).
startEvnt
- Object containing the same data as a tap
event, but captured when swiping begins.
endEvnt
- Object containing the same data as a tap
event, but captured when swiping is complete.
target
- the element from which the event was triggered.
originalEvent
- the the last native event that occurred.
Properties
isTouchCapable
:
true
orfalse
depending upon whether touch events are supported.startEvent
:
touchstart
for touch-enabled devices, ormousedown
for standard environments.endEvent
:
touchend
for touch-enabled devices, ormouseup
for standard environments.moveEvent
:
touchmove
for touch-enabled devices, ormousemove
for standard environments.tapEvent
:
tap
for touch-enabled devices, orclick
for standard environments.
ScrollEventsService
The ScrollEventsService
adds additional scroll events to your element.
Usage
Create a new instance of the ScrollEventsService
with an Element as argument to trigger the touch events on this element:
import { ScrollEventsService } from '@ribajs/extras';
const element = document.querySelector('.trigger-touch-events');
const ScrollEventsService = new ScrollEventsService(element);
element.addEventListener('scrollended' as any, (scrollEvent: CustomEvent) => {
console.debug('the user has stopped scrolling', scrollEvent);
});
The Events
scrollstart
Triggered as soon as scrolling begins on the target element.scrollended
Triggered as soon as scrolling is stopped on the target element.