209 lines
7.6 KiB
JavaScript
Vendored
209 lines
7.6 KiB
JavaScript
Vendored
/*!
|
|
* jquery.customscroll 1.0
|
|
*
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
* http://www.gnu.org/licenses/gpl-2.0.html
|
|
*/
|
|
;(function ($) {
|
|
|
|
$.customscrollOptions = {
|
|
always: false,
|
|
show: {
|
|
on: 'mouseenter scrollstart',
|
|
effect: 'fadeIn',
|
|
speed: 250,
|
|
delay: 0
|
|
},
|
|
hide: {
|
|
on: 'mouseleave scrollstop',
|
|
effect: 'fadeOut',
|
|
speed: 250,
|
|
delay: 750
|
|
},
|
|
grow: {
|
|
size: 3,
|
|
speed: 100
|
|
},
|
|
pageUpnDown: {
|
|
speed: 100
|
|
}
|
|
};
|
|
|
|
$.fn.customscroll = function (options) {
|
|
options = $.extend(true, {}, $.customscrollOptions, options || {});
|
|
return this.each(function () {
|
|
var object = $(this);
|
|
|
|
// build template
|
|
object.addClass('customscroll');
|
|
object.html([
|
|
'<div class="wrapper" style="height:' + object.height() + 'px">',
|
|
'<div class="content" style="width:' + object.width() + 'px">',
|
|
object.html(),
|
|
'</div>',
|
|
'</div>',
|
|
'<div class="placeholder" style="top:' + object.css('paddingTop') + ';bottom:' + object.css('paddingBottom') + '">',
|
|
'<div class="track">',
|
|
'<div class="grip"></div>',
|
|
'</div>',
|
|
'</div>'
|
|
].join(''));
|
|
|
|
// get elements
|
|
var wrapper = object.children('.wrapper'),
|
|
placeholder = object.children('.placeholder'),
|
|
track = placeholder.children('.track'),
|
|
grip = track.children('.grip');
|
|
|
|
// object hover
|
|
var showHideTimer,
|
|
show = function (event) {
|
|
if (object.height() >= wrapper[0].scrollHeight) {
|
|
// we dont need scroll
|
|
return;
|
|
}
|
|
if (wrapper[0].scrollHeight < parseInt(object.css('max-height'))) {
|
|
// this is a fix for IE
|
|
return;
|
|
}
|
|
// show
|
|
clearInterval(showHideTimer);
|
|
showHideTimer = setTimeout(function () {
|
|
track[options.show.effect](options.show.speed);
|
|
}, options.show.delay);
|
|
if (!event || event.type !== 'scrollstart') {
|
|
// used for adjusting sizes
|
|
wrapper.trigger('scroll');
|
|
}
|
|
};
|
|
wrapper.on(options.show.on, show);
|
|
wrapper.on(options.hide.on, function callback() {
|
|
// don't hide if always is true
|
|
if (options.always) {
|
|
return;
|
|
}
|
|
if (wrapper.hasClass('keep')) {
|
|
// someone says do not hide, try again later
|
|
return setTimeout(function () {
|
|
callback();
|
|
}, 250);
|
|
}
|
|
// hide
|
|
clearInterval(showHideTimer);
|
|
showHideTimer = setTimeout(function () {
|
|
track[options.hide.effect](options.hide.speed);
|
|
}, options.hide.delay);
|
|
});
|
|
|
|
// bind scroll event
|
|
var scrollingTimer;
|
|
wrapper.on('scroll', function (event) {
|
|
var height = object.height();
|
|
grip.css({
|
|
// grip height is view height / scroll height * 200 (4 is for margins)
|
|
height: height / this.scrollHeight * height - parseInt(object.css('paddingTop')) - parseInt(object.css('paddingBottom')),
|
|
// scroll position
|
|
marginTop: this.scrollTop * 100 / this.scrollHeight * height / 100 + 'px'
|
|
});
|
|
// custom scroll start / end events
|
|
if (!scrollingTimer) {
|
|
wrapper.trigger('scrollstart');
|
|
}
|
|
clearInterval(scrollingTimer);
|
|
scrollingTimer = setTimeout(function () {
|
|
wrapper.trigger('scrollstop');
|
|
scrollingTimer = null;
|
|
}, 200);
|
|
});
|
|
|
|
// placeholder and track hover
|
|
wrapper.on('mouseover', function () {
|
|
// do not hide track and show
|
|
wrapper.addClass('keep');
|
|
show();
|
|
});
|
|
|
|
// placeholder and track hover
|
|
wrapper.on('mouseleave', function () {
|
|
// do not hide track and show
|
|
wrapper.removeClass('keep');
|
|
});
|
|
placeholder.on('mouseover', function () {
|
|
// do not hide track and show
|
|
wrapper.addClass('keep');
|
|
show();
|
|
});
|
|
placeholder.on('mouseleave', function () {
|
|
// hide track
|
|
wrapper.removeClass('keep');
|
|
});
|
|
track.on('mouseenter', function () {
|
|
track.addClass('hover');
|
|
if (options.grow) {
|
|
// stop animation queue and animate
|
|
track.stop(true, true);
|
|
track.animate({width: '+=' + options.grow.size + 'px'}, options.grow.speed);
|
|
}
|
|
});
|
|
track.on('mouseleave', function hover() {
|
|
track.removeClass('hover');
|
|
if (options.grow) {
|
|
// stop animation queue and animate
|
|
track.stop(true, true);
|
|
track.animate({width: '-=' + options.grow.size + 'px'}, options.grow.speed);
|
|
}
|
|
});
|
|
|
|
// page up / down (track click)
|
|
track.on('click', function (event) {
|
|
if ($(event.target).hasClass('grip')) {
|
|
// do not trigger when clicking the egrip
|
|
return;
|
|
}
|
|
if (event.pageY - track.offset().top > parseInt(grip.css('marginTop'))) {
|
|
// clicked after grip
|
|
var operation = '+';
|
|
} else {
|
|
// clicked before grip
|
|
var operation = '-';
|
|
}
|
|
// scroll
|
|
wrapper.animate({
|
|
scrollTop: operation + '=' + object.height() + 'px'
|
|
}, options.pageUpnDown.speed);
|
|
});
|
|
|
|
// show initially if always is true
|
|
if (options.always) {
|
|
show();
|
|
}
|
|
// grip drag
|
|
var dragging = false;
|
|
grip.on('mousedown', function (event) {
|
|
// do not hide
|
|
wrapper.addClass('keep');
|
|
// mark as dragging
|
|
dragging = true;
|
|
// prevent text selection
|
|
$('body').addClass('dragging');
|
|
});
|
|
$(document).on('mousemove', function (event) {
|
|
if (dragging) {
|
|
// we have drag, move
|
|
wrapper.scrollTop(wrapper[0].scrollHeight * (event.pageY - track.offset().top - grip.height() / 2) / object.height());
|
|
event.preventDefault();
|
|
}
|
|
});
|
|
$(document).on('mouseup', function () {
|
|
if (dragging) {
|
|
// we have drag, remove
|
|
wrapper.removeClass('keep');
|
|
dragging = false;
|
|
$('body').removeClass('dragging');
|
|
}
|
|
});
|
|
|
|
});
|
|
};
|
|
})(jQuery); |