vuikit
Version:
A responsive Vue UI library for web site interfaces based on UIkit
97 lines (92 loc) • 2.7 kB
JavaScript
/**
* Vuikit 0.8.10
* (c) 2018 Miljan Aleksic
* @license MIT
**/
/* Substantial part of the code is adapted from UIkit,
Copyright (c) 2013-2018 YOOtheme GmbH, getuikit.com */
import { $, $$ } from './util/core';
import { escape } from './util/selector';
import { on, trigger } from './util/event';
import { height, offset } from './util/dimensions';
import { clamp, isString, assign } from './util/lang';
var NAMESPACE = '__vkScroll';
var index = {
bind: function bind (el, binding, vnode) {
el[NAMESPACE] = {};
},
inserted: function inserted (el, binding, vnode) {
el[NAMESPACE].options = getOptions({ binding: binding, vnode: vnode });
el[NAMESPACE].unbind = on(el, 'click', function (e) {
var opts = el[NAMESPACE].options;
var isAnchor = e.target.nodeName === 'A';
if (!isAnchor || (e.defaultPrevented && !opts.force)) {
return
}
if (e.target === el || matches(el, e.target, opts.target)) {
e.preventDefault();
scrollTo(el, e.target, escape(e.target.hash).substr(1), opts);
}
});
},
componentUpdated: function componentUpdated (el, binding, vnode) {
el[NAMESPACE].options = getOptions({ binding: binding, vnode: vnode });
},
unbind: function unbind (el) {
if (!el[NAMESPACE]) {
return
}
el[NAMESPACE].unbind();
delete el[NAMESPACE];
}
}
function scrollTo (el, fromEl, toEl, options) {
toEl = (toEl && $(toEl)) || document.body;
var docHeight = height(document);
var winHeight = height(window);
var target = offset(toEl).top - options.offset;
if (target + winHeight > docHeight) {
target = docHeight - winHeight;
}
if (!trigger(el, 'beforeScroll', { from: fromEl, to: toEl })) {
return
}
var start = Date.now();
var startY = window.pageYOffset;
var step = function () {
var currentY = startY + (target - startY) * ease(
clamp((Date.now() - start) / options.duration)
);
window.scrollTo(window.pageXOffset, currentY);
if (currentY !== target) {
requestAnimationFrame(step);
} else {
trigger(el, 'afterScroll', { from: fromEl, to: toEl });
}
};
step();
}
function ease (k) {
return 0.5 * (1 - Math.cos(Math.PI * k))
}
function getOptions (ctx) {
var ref = ctx.binding;
var value = ref.value;
var modifiers = ref.modifiers;
if (isString(value)) {
value = { target: value };
}
return assign({
offset: 0,
target: 'a',
force: false,
duration: 1000
}, modifiers, value)
}
function matches (el, target, selector) {
var matches = $$(("" + selector), el);
var i = matches.length;
while (--i >= 0 && matches[i] !== target) {}
return i > -1
}
export default index;