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 whendoubletapis used, so it is recommended to usesingletapin this case.singletap
Unliketapthis event is only triggered once we are certain the user has only tapped the target element a single time. This will not be triggered bydoubletaportaphold, 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
Theswipeendevent 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:
trueorfalsedepending upon whether touch events are supported.startEvent:
touchstartfor touch-enabled devices, ormousedownfor standard environments.endEvent:
touchendfor touch-enabled devices, ormouseupfor standard environments.moveEvent:
touchmovefor touch-enabled devices, ormousemovefor standard environments.tapEvent:
tapfor touch-enabled devices, orclickfor 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.