- touchable RengeSlider.js and RangeSlider.css

- addition utility methods
- domEvent.js: add multiple handler with one initialization
This commit is contained in:
Arno Kaimbacher 2021-01-08 16:35:26 +01:00
parent e62d4908f0
commit 7c50b75099
5 changed files with 168 additions and 149 deletions

View File

@ -1,7 +1,6 @@
import { Control } from "./Control";
import * as dom from '../core/domUtil';
import * as util from '../core/utilities';
import * as domEvent from '../core/domEvent';
import { RangeSlider } from '../core/RangeSlider';
import './SliderControl.css';
@ -79,13 +78,14 @@ export class SliderControl extends Control {
// this.slider.setAttribute("step", this.options.step);
// this.slider.setAttribute("value", this.options.value);
this.slider = new RangeSlider(this._sliderContainer, {
this.slider = new RangeSlider({
orientation: "vertical",
value: 1,
max: 5, min: 1,
inverse: true,
id: "z-slider"
});
this.slider.addTo(this._sliderContainer);
//if (this.options.syncSlider) {
// L.DomEvent.on(this.slider, "input", function (e) {

View File

@ -7,7 +7,8 @@
.slider.slider-vertical {
height: 160px;
width: 30px;
width: 35px;
z-index: 9;
}
.slider.slider-vertical .range-slider-track {

View File

@ -1,7 +1,8 @@
import { EventEmitter } from './EventEmitter';
import * as dom from '../core/domUtil';
import * as util from '../core/utilities';
import * as domEvent from '../core/domEvent';
import * as dom from './domUtil';
import * as util from './utilities';
import * as domEvent from './domEvent';
import * as browser from './browser';
import './RangeSlider.css';
@ -9,6 +10,7 @@ class RangeSlider extends EventEmitter {
over = false;
inDrag = false;
touchCapable = false;
options = {
value: 0, // set default value on initiation from `0` to `100` (percentage based)
@ -22,16 +24,21 @@ class RangeSlider extends EventEmitter {
stepSize: 1
};
constructor(elem, options) {
constructor(options) {
super();
util.setOptions(this, options);
this.value = this.options.value;
this.element = elem;
if (browser.touch && browser.mobile) {
this.touchCapable = true;
}
}
addTo(parentDiv) {
//this._initLayout();
this.picker = dom.createDom("div", {
this.element = parentDiv;
this.template = dom.createDom("div", {
"class": 'slider', innerHTML:
'<div class="range-slider-track">' +
'<div class="slider-selection"></div>' +
@ -41,24 +48,23 @@ class RangeSlider extends EventEmitter {
'<div class="slider-ticks"></div>' +
'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
}, this.element);
}, parentDiv);
this.id = this.options.id;
// var tooltip = this.options.tooltip;
this.tooltip = this.picker.getElementsByClassName('tooltip')[0];
this.tooltip = this.template.getElementsByClassName('tooltip')[0];
this.tooltipInner = this.tooltip.getElementsByClassName('tooltip-inner')[0];
this.sliderTrack = this.picker.getElementsByClassName('range-slider-track')[0];
this.sliderTicks = this.picker.getElementsByClassName('slider-ticks')[0];
this.sliderTrack = this.template.getElementsByClassName('range-slider-track')[0];
this.sliderTicks = this.template.getElementsByClassName('slider-ticks')[0];
this.orientation = this.options.orientation;
if (this.orientation === "horizontal") {
dom.addClass(this.picker, "slider-horizontal");
//.addClass('slider-horizontal')
dom.addClass(this.template, "slider-horizontal");
//.css('width', this.element.outerWidth());
//$(this.picker).css('width', $(this.element).outerWidth());
//this.picker.style.width = this.element['offsetWidth'] + 'px';
//$(this.template).css('width', $(this.element).outerWidth());
//this.template.style.width = this.element['offsetWidth'] + 'px';
this.orientation = 'horizontal';
this.stylePos = 'left';
this.mousePos = 'pageX';
@ -67,11 +73,10 @@ class RangeSlider extends EventEmitter {
dom.addClass(this.tooltip, "top");
this.tooltip.style.top = -this.tooltip['offsetHeight'] - 14 + 'px';
} else {
dom.addClass(this.picker, "slider-vertical");
dom.addClass(this.template, "slider-vertical");
this.stylePos = 'top';
this.mousePos = 'pageY';
this.sizePos = 'offsetHeight';
// this.tooltip.addClass('right')[0].style.left = '100%';
dom.addClass(this.tooltip, "right");
this.tooltip.style.left = "100%";
}
@ -95,16 +100,15 @@ class RangeSlider extends EventEmitter {
}
this.selection = this.options.selection;
this.selectionEl = this.picker.getElementsByClassName('slider-selection')[0];
this.selectionEl = this.template.getElementsByClassName('slider-selection')[0];
if (this.selection === 'none') {
//this.selectionEl.addClass('hide');
dom.addClass(this.selectionEl, "hide");
}
this.selectionElStyle = this.selectionEl.style;
this.handle1 = this.picker.getElementsByClassName('slider-handle')[0];
this.handle1 = this.template.getElementsByClassName('slider-handle')[0];
this.handle1Stype = this.handle1.style;
this.handle2 = this.picker.getElementsByClassName('slider-handle')[1];
this.handle2 = this.template.getElementsByClassName('slider-handle')[1];
this.handle2Stype = this.handle2.style;
var handle = this.options.handle;
@ -141,17 +145,39 @@ class RangeSlider extends EventEmitter {
this.stepSize * 100 / this.diff
];
//this.offset = this.picker.offset();
// this.offset = $(this.picker).offset();
this.offset = this._getOffset(this.picker);
this.size = this.picker[this.sizePos];
//this.offset = this.template.offset();
// this.offset = $(this.template).offset();
this.offset = this._getOffset(this.template);
this.size = this.template[this.sizePos];
//this.formater = options.formater;
this.layout();
domEvent.on(this.picker, "mousedown", this.mousedown, this);
// domEvent
// .on(this.template, 'mousedown touchstart', domEvent.stopPropagation)
// .on(this.template, 'click', domEvent.stopPropagation)
// .on(this.template, 'dblclick', domEvent.stopPropagation)
// .on(this.template, 'mousedown touchstart', domEvent.preventDefault)
// .on(this.template, 'mousedown touchstart', this.mousedown, this);
if (this.touchCapable) {
// Touch: Bind touch events:
domEvent.on(this.template, 'touchstart', domEvent.stopPropagation)
domEvent.on(this.template, 'touchstart', domEvent.preventDefault);
domEvent.on(this.template, 'touchstart', this.mousedown, this);
} else {
domEvent.on(this.template, 'mousedown', domEvent.stopPropagation);
domEvent.on(this.template, 'click', domEvent.stopPropagation);
domEvent.on(this.template, 'dblclick', domEvent.stopPropagation);
domEvent.on(this.template, 'mousedown', domEvent.preventDefault);
domEvent.on(this.template, 'mousedown', this.mousedown, this);
}
// domEvent.on(this.template, "mousedown touchstart", this.mousedown, this);
dom.addClass(this.tooltip, "hide");
}
@ -197,17 +223,16 @@ class RangeSlider extends EventEmitter {
}
mousedown(ev) {
// Touch: Get the original event:
if (this.touchCapable && ev.type === 'touchstart') {
ev = ev.originalEvent;
}
// if (this.touchCapable && ev.type === 'touchstart') {
// ev = ev.originalEvent;
// }
//this.offset = this.picker.offset();
// this.offset = $(this.picker).offset();
this.offset = this._getOffset(this.picker);
//this.offset = this.template.offset();
// this.offset = $(this.template).offset();
this.offset = this._getOffset(this.template);
this.size = this.picker[this.sizePos];
this.size = this.template[this.sizePos];
let percentage = this.getPercentage(ev);
@ -223,12 +248,19 @@ class RangeSlider extends EventEmitter {
// this.percentage[this.dragged] = percentage;
// this.layout();
domEvent.on(this.picker, "mousemove", this.mousemove, this);
domEvent.on(this.picker, 'mouseup', this.mouseup, this);
domEvent.on(this.picker, 'mouseleave', this.onMouseLeave, this);
if (this.touchCapable) {
// Touch: Bind touch events:
domEvent.on(this.template, 'touchmove', this.mousemove, this);
domEvent.on(this.template, 'touchend', this.mouseup, this);
// domEvent.on(this.template, 'touchcancel', this.onMouseLeave, this);
} else {
domEvent.on(this.template, 'mousemove', this.mousemove, this);
domEvent.on(this.template, 'mouseup', this.mouseup, this);
domEvent.on(this.template, 'mouseleave', this.onMouseLeave, this);
}
this.inDrag = true;
let value = this.calculateValue();
// let value = this.calculateValue();
//if (this.options.inverse === true) {
// val = val * -1;
//}
@ -250,9 +282,9 @@ class RangeSlider extends EventEmitter {
this.sliderTrack.style.cursor = "grab";
// Touch: Get the original event:
if (this.touchCapable && ev.type === 'touchmove') {
ev = ev.originalEvent;
}
// if (this.touchCapable && ev.type === 'touchmove') {
// ev = ev.originalEvent;
// }
let percentage = this.getPercentage(ev);
// if (this.range) {
@ -286,9 +318,18 @@ class RangeSlider extends EventEmitter {
this.handle1.style.cursor = "pointer";
this.sliderTrack.style.cursor = "pointer";
domEvent.off(this.picker, "mousemove", this.mousemove, this);
domEvent.off(this.picker, 'mouseup', this.mouseup, this);
domEvent.off(this.picker, 'mouseleave', this.onMouseLeave, this);
if (this.touchCapable) {
// Touch: Bind touch events:
domEvent.off(this.template, "touchmove", this.mousemove, this);
domEvent.off(this.template, 'touchend', this.mouseup, this);
// domEvent.off(this.template, 'touchcancel', this.onMouseLeave, this);
} else {
domEvent.off(this.template, "mousemove", this.mousemove, this);
domEvent.off(this.template, 'mouseup', this.mouseup, this);
domEvent.off(this.template, 'mouseleave', this.onMouseLeave, this);
}
this.inDrag = false;
//if (this.over == false) {
@ -304,9 +345,17 @@ class RangeSlider extends EventEmitter {
this.handle1.style.cursor = "pointer";
this.sliderTrack.style.cursor = "pointer";
domEvent.off(this.picker, "mousemove", this.mousemove, this);
domEvent.off(this.picker, 'mouseup', this.mouseup, this);
domEvent.off(this.picker, 'mouseleave', this.onMouseLeave, this);
if (this.touchCapable) {
// Touch: Bind touch events:
domEvent.off(this.template, "touchmove", this.mousemove, this);
domEvent.off(this.template, 'touchend', this.mouseup, this);
// domEvent.off(this.template, 'touchcancel', this.onMouseLeave, this);
} else {
domEvent.off(this.template, "mousemove", this.mousemove, this);
domEvent.off(this.template, 'mouseup', this.mouseup, this);
domEvent.off(this.template, 'mouseleave', this.onMouseLeave, this);
}
this.inDrag = false;
@ -324,14 +373,15 @@ class RangeSlider extends EventEmitter {
];
this.value = val;
} else {
val = (this.min + Math.round((this.diff * this.percentage[0] / 100) / this.stepSize) * this.stepSize);
val = (this.
min + Math.round((this.diff * this.percentage[0] / 100) / this.stepSize) * this.stepSize);
this.value = [val, this.value[1]];
}
return val;
}
getPercentage(ev) {
if (this.touchCapable) {
if (this.touchCapable && ev.touches) {
ev = ev.touches[0];
}
let percentage = (ev[this.mousePos] - this.offset[this.stylePos]) * 100 / this.size;

View File

@ -1,19 +1,32 @@
import * as browser from '../core/browser';
import * as util from '../core/utilities';
//static function
var stampForFn = (function () {
var lastId = 0,
key = '_id';
return function (obj) {
obj[key] = obj[key] || ++lastId;
return obj[key];
var mouseSubst = {
mouseenter: 'mouseover',
mouseleave: 'mouseout',
wheel: !('onwheel' in window) && 'mousewheel'
};
}());
export function addListener(obj, type, fn, context) { // (HTMLElement, String, Function[, Object])
export function addListener(obj, types, fn, context) {
if (typeof types === 'object') {
for (let type in types) {
addaddOneListenerne(obj, type, types[type], fn);
}
} else {
types = util.splitWords(types);
var id = stampForFn(fn);
for (let i = 0, len = types.length; i < len; i++) {
addOneListener(obj, types[i], fn, context);
}
}
return this;
}
export function addOneListener(obj, type, fn, context) { // (HTMLElement, String, Function[, Object])
var id = util.stamp(fn);
var key = '_gba_' + type + id;
var handler, originalHandler, newType;
@ -23,19 +36,15 @@ export function addListener(obj, type, fn, context) { // (HTMLElement, String, F
return fn.call(context || obj, e || domEvent._getEvent());
};
//if (L.Browser.pointer && type.indexOf('touch') === 0) {
// return this.addPointerListener(obj, type, handler, id);
//}
//if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) {
// this.addDoubleTapListener(obj, handler, id);
//}
if ('addEventListener' in obj) {
if (type === 'mousewheel') {
obj.addEventListener('DOMMouseScroll', handler, false);
obj.addEventListener(type, handler, false);
// if (type === 'mousewheel') {
// obj.addEventListener('DOMMouseScroll', handler, false);
// obj.addEventListener(type, handler, false);
// }
if (type === 'touchstart' || type === 'touchmove' || type === 'wheel' || type === 'mousewheel') {
obj.addEventListener(mouseSubst[type] || type, handler, false);
}
else if ((type === 'mouseenter') || (type === 'mouseleave')) {
@ -49,25 +58,15 @@ export function addListener(obj, type, fn, context) { // (HTMLElement, String, F
obj.addEventListener(newType, handler, false);
}
//else if (type === 'click' && L.Browser.android) {
// originalHandler = handler;
// handler = function (e) {
// return L.DomEvent._filterClick(e, originalHandler);
// };
// obj.addEventListener(type, handler, false);
//}
else {
} else {
obj.addEventListener(type, handler, false);
}
}
else if ('attachEvent' in obj) {
} else if ('attachEvent' in obj) {
obj.attachEvent('on' + type, handler);
}
obj[key] = obj[key] || {};
obj[key] = handler;
return this;
@ -77,57 +76,9 @@ export function addListener(obj, type, fn, context) { // (HTMLElement, String, F
// Alias to [`L.DomEvent.on`](#domevent-on)
export { addListener as on };
function addOne(obj, type, fn, context) {
var id = type + util.stamp(fn) + (context ? '_' + util.stamp(context) : '');
var eventsKey = '_gba_' + type + id;
if (obj[eventsKey] && obj[eventsKey][id]) { return this; }
var handler = function (e) {
return fn.call(context || obj, e || window.event);
};
var originalHandler = handler;
if (browser.pointer && type.indexOf('touch') === 0) {
// Needs DomEvent.Pointer.js
addPointerListener(obj, type, handler, id);
} else if (browser.touch && (type === 'dblclick') && !browserFiresNativeDblClick()) {
addDoubleTapListener(obj, handler, id);
} else if ('addEventListener' in obj) {
if (type === 'touchstart' || type === 'touchmove' || type === 'wheel' || type === 'mousewheel') {
obj.addEventListener(mouseSubst[type] || type, handler, Browser.passiveEvents ? {passive: false} : false);
} else if (type === 'mouseenter' || type === 'mouseleave') {
handler = function (e) {
e = e || window.event;
if (isExternalTarget(obj, e)) {
originalHandler(e);
}
};
obj.addEventListener(mouseSubst[type], handler, false);
} else {
obj.addEventListener(type, originalHandler, false);
}
} else if ('attachEvent' in obj) {
obj.attachEvent('on' + type, handler);
}
obj[eventsKey] = obj[eventsKey] || {};
obj[eventsKey][id] = handler;
}
export function removeListener(obj, type, fn) { // (HTMLElement, String, Function)
var id = stampForFn(fn);
var id = util.stamp(fn);
var key = '_gba_' + type + id;
var handler = obj[key];
@ -188,7 +139,7 @@ export function stopPropagation(e) {
// `'mousedown'` and `'touchstart'` events (plus browser variants).
export function disableClickPropagation(el) {
addListener(el, 'mousedown touchstart dblclick', stopPropagation);
addOne(el, 'click', fakeStop);
addOneListener(el, 'click', fakeStop);
return this;
}

View File

@ -147,7 +147,7 @@ export function setOptions(obj, options) {
// Last unique ID used by [`stamp()`](#util-stamp)
export var lastId = 0;
// @function stamp(obj: Object): Number
// @function stampForFn(obj: Object): Number
// Returns the unique ID of an object, assigning it one if it doesn't have it.
export function stamp(obj) {
let key = '_gba_id';
@ -156,6 +156,17 @@ export function stamp(obj) {
}
// //static function
// var stamp = (function () {
// //var lastId = 0,
// let key = '_gba_id';
// return function (obj) {
// obj[key] = obj[key] || ++lastId;
// return obj[key];
// };
// }());
// export { stamp };
export function hasTouch() {
let phantomjs = navigator.userAgent.toLowerCase().indexOf('phantom') !== -1;
@ -172,3 +183,9 @@ export function hasTouch() {
export function trim(str) {
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
}
// @function splitWords(str: String): String[]
// Trims and splits the string on whitespace and returns the array of parts.
export function splitWords(str) {
return trim(str).split(/\s+/);
}