535 lines
18 KiB
JavaScript
535 lines
18 KiB
JavaScript
/*! UIkit 2.27.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
|
|
(function(UI) {
|
|
|
|
"use strict";
|
|
|
|
var active = false, hoverIdle, flips = {
|
|
x: {
|
|
'bottom-left' : 'bottom-right',
|
|
'bottom-right' : 'bottom-left',
|
|
'bottom-center' : 'bottom-center',
|
|
'top-left' : 'top-right',
|
|
'top-right' : 'top-left',
|
|
'top-center' : 'top-center',
|
|
'left-top' : 'right-top',
|
|
'left-bottom' : 'right-bottom',
|
|
'left-center' : 'right-center',
|
|
'right-top' : 'left-top',
|
|
'right-bottom' : 'left-bottom',
|
|
'right-center' : 'left-center'
|
|
},
|
|
y: {
|
|
'bottom-left' : 'top-left',
|
|
'bottom-right' : 'top-right',
|
|
'bottom-center' : 'top-center',
|
|
'top-left' : 'bottom-left',
|
|
'top-right' : 'bottom-right',
|
|
'top-center' : 'bottom-center',
|
|
'left-top' : 'left-bottom',
|
|
'left-bottom' : 'left-top',
|
|
'left-center' : 'left-center',
|
|
'right-top' : 'right-bottom',
|
|
'right-bottom' : 'right-top',
|
|
'right-center' : 'right-center'
|
|
},
|
|
xy: {
|
|
'bottom-left' : 'top-right',
|
|
'bottom-right' : 'top-left',
|
|
'bottom-center' : 'top-center',
|
|
'top-left' : 'bottom-right',
|
|
'top-right' : 'bottom-left',
|
|
'top-center' : 'bottom-center',
|
|
'left-top' : 'right-bottom',
|
|
'left-bottom' : 'right-top',
|
|
'left-center' : 'right-center',
|
|
'right-top' : 'left-bottom',
|
|
'right-bottom' : 'left-top',
|
|
'right-center' : 'left-center'
|
|
}
|
|
};
|
|
|
|
UI.component('dropdown', {
|
|
|
|
defaults: {
|
|
mode : 'hover',
|
|
pos : 'bottom-left',
|
|
offset : 0,
|
|
remaintime : 800,
|
|
justify : false,
|
|
boundary : UI.$win,
|
|
delay : 0,
|
|
dropdownSelector: '.uk-dropdown,.uk-dropdown-blank',
|
|
hoverDelayIdle : 250,
|
|
preventflip : false
|
|
},
|
|
|
|
remainIdle: false,
|
|
|
|
boot: function() {
|
|
|
|
var triggerevent = UI.support.touch ? 'click' : 'mouseenter';
|
|
|
|
// init code
|
|
UI.$html.on(triggerevent+'.dropdown.uikit focus pointerdown', '[data-uk-dropdown]', function(e) {
|
|
|
|
var ele = UI.$(this);
|
|
|
|
if (!ele.data('dropdown')) {
|
|
|
|
var dropdown = UI.dropdown(ele, UI.Utils.options(ele.attr('data-uk-dropdown')));
|
|
|
|
if (e.type=='click' || (e.type=='mouseenter' && dropdown.options.mode=='hover')) {
|
|
dropdown.element.trigger(triggerevent);
|
|
}
|
|
|
|
if (dropdown.dropdown.length) {
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
init: function() {
|
|
|
|
var $this = this;
|
|
|
|
this.dropdown = this.find(this.options.dropdownSelector);
|
|
this.offsetParent = this.dropdown.parents().filter(function() {
|
|
return UI.$.inArray(UI.$(this).css('position'), ['relative', 'fixed', 'absolute']) !== -1;
|
|
}).slice(0,1);
|
|
|
|
if (!this.offsetParent.length) {
|
|
this.offsetParent = this.element;
|
|
}
|
|
|
|
this.centered = this.dropdown.hasClass('uk-dropdown-center');
|
|
this.justified = this.options.justify ? UI.$(this.options.justify) : false;
|
|
|
|
this.boundary = UI.$(this.options.boundary);
|
|
|
|
if (!this.boundary.length) {
|
|
this.boundary = UI.$win;
|
|
}
|
|
|
|
// legacy DEPRECATED!
|
|
if (this.dropdown.hasClass('uk-dropdown-up')) {
|
|
this.options.pos = 'top-left';
|
|
}
|
|
if (this.dropdown.hasClass('uk-dropdown-flip')) {
|
|
this.options.pos = this.options.pos.replace('left','right');
|
|
}
|
|
if (this.dropdown.hasClass('uk-dropdown-center')) {
|
|
this.options.pos = this.options.pos.replace(/(left|right)/,'center');
|
|
}
|
|
//-- end legacy
|
|
|
|
// Init ARIA
|
|
this.element.attr('aria-haspopup', 'true');
|
|
this.element.attr('aria-expanded', this.element.hasClass('uk-open'));
|
|
this.dropdown.attr('aria-hidden', 'true');
|
|
|
|
if (this.options.mode == 'click' || UI.support.touch) {
|
|
|
|
this.on('click.uk.dropdown', function(e) {
|
|
|
|
var $target = UI.$(e.target);
|
|
|
|
if (!$target.parents($this.options.dropdownSelector).length) {
|
|
|
|
if ($target.is("a[href='#']") || $target.parent().is("a[href='#']") || ($this.dropdown.length && !$this.dropdown.is(':visible')) ){
|
|
e.preventDefault();
|
|
}
|
|
|
|
$target.blur();
|
|
}
|
|
|
|
if (!$this.element.hasClass('uk-open')) {
|
|
|
|
$this.show();
|
|
|
|
} else {
|
|
|
|
if (!$this.dropdown.find(e.target).length || $target.is('.uk-dropdown-close') || $target.parents('.uk-dropdown-close').length) {
|
|
$this.hide();
|
|
}
|
|
}
|
|
});
|
|
|
|
} else {
|
|
|
|
this.on('mouseenter', function(e) {
|
|
|
|
$this.trigger('pointerenter.uk.dropdown', [$this]);
|
|
|
|
if ($this.remainIdle) {
|
|
clearTimeout($this.remainIdle);
|
|
}
|
|
|
|
if (hoverIdle) {
|
|
clearTimeout(hoverIdle);
|
|
}
|
|
|
|
if (active && active == $this) {
|
|
return;
|
|
}
|
|
|
|
// pseudo manuAim
|
|
if (active && active != $this) {
|
|
|
|
hoverIdle = setTimeout(function() {
|
|
hoverIdle = setTimeout($this.show.bind($this), $this.options.delay);
|
|
}, $this.options.hoverDelayIdle);
|
|
|
|
} else {
|
|
|
|
hoverIdle = setTimeout($this.show.bind($this), $this.options.delay);
|
|
}
|
|
|
|
}).on('mouseleave', function() {
|
|
|
|
if (hoverIdle) {
|
|
clearTimeout(hoverIdle);
|
|
}
|
|
|
|
$this.remainIdle = setTimeout(function() {
|
|
if (active && active == $this) $this.hide();
|
|
}, $this.options.remaintime);
|
|
|
|
$this.trigger('pointerleave.uk.dropdown', [$this]);
|
|
|
|
}).on('click', function(e){
|
|
|
|
var $target = UI.$(e.target);
|
|
|
|
if ($this.remainIdle) {
|
|
clearTimeout($this.remainIdle);
|
|
}
|
|
|
|
if (active && active == $this) {
|
|
if (!$this.dropdown.find(e.target).length || $target.is('.uk-dropdown-close') || $target.parents('.uk-dropdown-close').length) {
|
|
$this.hide();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ($target.is("a[href='#']") || $target.parent().is("a[href='#']")){
|
|
e.preventDefault();
|
|
}
|
|
|
|
$this.show();
|
|
});
|
|
}
|
|
},
|
|
|
|
show: function(){
|
|
|
|
UI.$html.off('click.outer.dropdown');
|
|
|
|
if (active && active != this) {
|
|
active.hide(true);
|
|
}
|
|
|
|
if (hoverIdle) {
|
|
clearTimeout(hoverIdle);
|
|
}
|
|
|
|
this.trigger('beforeshow.uk.dropdown', [this]);
|
|
|
|
this.checkDimensions();
|
|
this.element.addClass('uk-open');
|
|
|
|
// Update ARIA
|
|
this.element.attr('aria-expanded', 'true');
|
|
this.dropdown.attr('aria-hidden', 'false');
|
|
|
|
this.trigger('show.uk.dropdown', [this]);
|
|
|
|
UI.Utils.checkDisplay(this.dropdown, true);
|
|
UI.Utils.focus(this.dropdown);
|
|
active = this;
|
|
|
|
this.registerOuterClick();
|
|
},
|
|
|
|
hide: function(force) {
|
|
|
|
this.trigger('beforehide.uk.dropdown', [this, force]);
|
|
|
|
this.element.removeClass('uk-open');
|
|
|
|
if (this.remainIdle) {
|
|
clearTimeout(this.remainIdle);
|
|
}
|
|
|
|
this.remainIdle = false;
|
|
|
|
// Update ARIA
|
|
this.element.attr('aria-expanded', 'false');
|
|
this.dropdown.attr('aria-hidden', 'true');
|
|
|
|
this.trigger('hide.uk.dropdown', [this, force]);
|
|
|
|
if (active == this) active = false;
|
|
},
|
|
|
|
registerOuterClick: function(){
|
|
|
|
var $this = this;
|
|
|
|
UI.$html.off('click.outer.dropdown');
|
|
|
|
setTimeout(function() {
|
|
|
|
UI.$html.on('click.outer.dropdown', function(e) {
|
|
|
|
if (hoverIdle) {
|
|
clearTimeout(hoverIdle);
|
|
}
|
|
|
|
var $target = UI.$(e.target);
|
|
|
|
if (active == $this && !$this.element.find(e.target).length) {
|
|
$this.hide(true);
|
|
UI.$html.off('click.outer.dropdown');
|
|
}
|
|
});
|
|
}, 10);
|
|
},
|
|
|
|
checkDimensions: function() {
|
|
|
|
if (!this.dropdown.length) return;
|
|
|
|
// reset
|
|
this.dropdown.removeClass('uk-dropdown-top uk-dropdown-bottom uk-dropdown-left uk-dropdown-right uk-dropdown-stack uk-dropdown-autoflip').css({
|
|
topLeft :'',
|
|
left :'',
|
|
marginLeft :'',
|
|
marginRight :''
|
|
});
|
|
|
|
if (this.justified && this.justified.length) {
|
|
this.dropdown.css('min-width', '');
|
|
}
|
|
|
|
var $this = this,
|
|
pos = UI.$.extend({}, this.offsetParent.offset(), {width: this.offsetParent[0].offsetWidth, height: this.offsetParent[0].offsetHeight}),
|
|
posoffset = this.options.offset,
|
|
dropdown = this.dropdown,
|
|
offset = dropdown.show().offset() || {left: 0, top: 0},
|
|
width = dropdown.outerWidth(),
|
|
height = dropdown.outerHeight(),
|
|
boundarywidth = this.boundary.width(),
|
|
boundaryoffset = this.boundary[0] !== window && this.boundary.offset() ? this.boundary.offset(): {top:0, left:0},
|
|
dpos = this.options.pos;
|
|
|
|
var variants = {
|
|
'bottom-left' : {top: 0 + pos.height + posoffset, left: 0},
|
|
'bottom-right' : {top: 0 + pos.height + posoffset, left: 0 + pos.width - width},
|
|
'bottom-center' : {top: 0 + pos.height + posoffset, left: 0 + pos.width / 2 - width / 2},
|
|
'top-left' : {top: 0 - height - posoffset, left: 0},
|
|
'top-right' : {top: 0 - height - posoffset, left: 0 + pos.width - width},
|
|
'top-center' : {top: 0 - height - posoffset, left: 0 + pos.width / 2 - width / 2},
|
|
'left-top' : {top: 0, left: 0 - width - posoffset},
|
|
'left-bottom' : {top: 0 + pos.height - height, left: 0 - width - posoffset},
|
|
'left-center' : {top: 0 + pos.height / 2 - height / 2, left: 0 - width - posoffset},
|
|
'right-top' : {top: 0, left: 0 + pos.width + posoffset},
|
|
'right-bottom' : {top: 0 + pos.height - height, left: 0 + pos.width + posoffset},
|
|
'right-center' : {top: 0 + pos.height / 2 - height / 2, left: 0 + pos.width + posoffset}
|
|
},
|
|
css = {},
|
|
pp;
|
|
|
|
pp = dpos.split('-');
|
|
css = variants[dpos] ? variants[dpos] : variants['bottom-left'];
|
|
|
|
// justify dropdown
|
|
if (this.justified && this.justified.length) {
|
|
justify(dropdown.css({left:0}), this.justified, boundarywidth);
|
|
} else {
|
|
|
|
if (this.options.preventflip !== true) {
|
|
|
|
var fdpos;
|
|
|
|
switch(this.checkBoundary(pos.left + css.left, pos.top + css.top, width, height, boundarywidth)) {
|
|
case "x":
|
|
if(this.options.preventflip !=='x') fdpos = flips['x'][dpos] || 'right-top';
|
|
break;
|
|
case "y":
|
|
if(this.options.preventflip !=='y') fdpos = flips['y'][dpos] || 'top-left';
|
|
break;
|
|
case "xy":
|
|
if(!this.options.preventflip) fdpos = flips['xy'][dpos] || 'right-bottom';
|
|
break;
|
|
}
|
|
|
|
if (fdpos) {
|
|
|
|
pp = fdpos.split('-');
|
|
css = variants[fdpos] ? variants[fdpos] : variants['bottom-left'];
|
|
dropdown.addClass('uk-dropdown-autoflip');
|
|
|
|
// check flipped
|
|
if (this.checkBoundary(pos.left + css.left, pos.top + css.top, width, height, boundarywidth)) {
|
|
pp = dpos.split('-');
|
|
css = variants[dpos] ? variants[dpos] : variants['bottom-left'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (width > boundarywidth) {
|
|
dropdown.addClass('uk-dropdown-stack');
|
|
this.trigger('stack.uk.dropdown', [this]);
|
|
}
|
|
|
|
dropdown.css(css).css('display', '').addClass('uk-dropdown-'+pp[0]);
|
|
},
|
|
|
|
checkBoundary: function(left, top, width, height, boundarywidth) {
|
|
|
|
var axis = "";
|
|
|
|
if (left < 0 || ((left - UI.$win.scrollLeft())+width) > boundarywidth) {
|
|
axis += "x";
|
|
}
|
|
|
|
if ((top - UI.$win.scrollTop()) < 0 || ((top - UI.$win.scrollTop())+height) > window.innerHeight) {
|
|
axis += "y";
|
|
}
|
|
|
|
return axis;
|
|
}
|
|
});
|
|
|
|
|
|
UI.component('dropdownOverlay', {
|
|
|
|
defaults: {
|
|
justify : false,
|
|
cls : '',
|
|
duration: 200
|
|
},
|
|
|
|
boot: function() {
|
|
|
|
// init code
|
|
UI.ready(function(context) {
|
|
|
|
UI.$('[data-uk-dropdown-overlay]', context).each(function() {
|
|
var ele = UI.$(this);
|
|
|
|
if (!ele.data('dropdownOverlay')) {
|
|
UI.dropdownOverlay(ele, UI.Utils.options(ele.attr('data-uk-dropdown-overlay')));
|
|
}
|
|
});
|
|
});
|
|
},
|
|
|
|
init: function() {
|
|
|
|
var $this = this;
|
|
|
|
this.justified = this.options.justify ? UI.$(this.options.justify) : false;
|
|
this.overlay = this.element.find('uk-dropdown-overlay');
|
|
|
|
if (!this.overlay.length) {
|
|
this.overlay = UI.$('<div class="uk-dropdown-overlay"></div>').appendTo(this.element);
|
|
}
|
|
|
|
this.overlay.addClass(this.options.cls);
|
|
|
|
this.on({
|
|
|
|
'beforeshow.uk.dropdown': function(e, dropdown) {
|
|
$this.dropdown = dropdown;
|
|
|
|
if ($this.justified && $this.justified.length) {
|
|
justify($this.overlay.css({display:'block', marginLeft:'', marginRight:''}), $this.justified, $this.justified.outerWidth());
|
|
}
|
|
},
|
|
|
|
'show.uk.dropdown': function(e, dropdown) {
|
|
|
|
var h = $this.dropdown.dropdown.outerHeight(true);
|
|
|
|
$this.dropdown.element.removeClass('uk-open');
|
|
|
|
$this.overlay.stop().css('display', 'block').animate({height: h}, $this.options.duration, function() {
|
|
|
|
$this.dropdown.dropdown.css('visibility', '');
|
|
$this.dropdown.element.addClass('uk-open');
|
|
|
|
UI.Utils.checkDisplay($this.dropdown.dropdown, true);
|
|
});
|
|
|
|
$this.pointerleave = false;
|
|
},
|
|
|
|
'hide.uk.dropdown': function() {
|
|
$this.overlay.stop().animate({height: 0}, $this.options.duration);
|
|
},
|
|
|
|
'pointerenter.uk.dropdown': function(e, dropdown) {
|
|
clearTimeout($this.remainIdle);
|
|
},
|
|
|
|
'pointerleave.uk.dropdown': function(e, dropdown) {
|
|
$this.pointerleave = true;
|
|
}
|
|
});
|
|
|
|
|
|
this.overlay.on({
|
|
|
|
'mouseenter': function() {
|
|
if ($this.remainIdle) {
|
|
clearTimeout($this.dropdown.remainIdle);
|
|
clearTimeout($this.remainIdle);
|
|
}
|
|
},
|
|
|
|
'mouseleave': function(){
|
|
|
|
if ($this.pointerleave && active) {
|
|
|
|
$this.remainIdle = setTimeout(function() {
|
|
if(active) active.hide();
|
|
}, active.options.remaintime);
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
});
|
|
|
|
|
|
function justify(ele, justifyTo, boundarywidth, offset) {
|
|
|
|
ele = UI.$(ele);
|
|
justifyTo = UI.$(justifyTo);
|
|
boundarywidth = boundarywidth || window.innerWidth;
|
|
offset = offset || ele.offset();
|
|
|
|
if (justifyTo.length) {
|
|
|
|
var jwidth = justifyTo.outerWidth();
|
|
|
|
ele.css('min-width', jwidth);
|
|
|
|
if (UI.langdirection == 'right') {
|
|
|
|
var right1 = boundarywidth - (justifyTo.offset().left + jwidth),
|
|
right2 = boundarywidth - (ele.offset().left + ele.outerWidth());
|
|
|
|
ele.css('margin-right', right1 - right2);
|
|
|
|
} else {
|
|
ele.css('margin-left', justifyTo.offset().left - offset.left);
|
|
}
|
|
}
|
|
}
|
|
|
|
})(UIkit2);
|