slimScroll scrolls to fast (wheelStep and touchScrollStep not working) - javascript

I'm using slimScroll within a js project for a scroll bar on one side of the page. There are a lot of elements within the the scrollView and right now it's scrolling way to quickly and not intuitively. When I reduce the amount of wheel and/or touchScrollStep there is not change it speed.
* Version: 1.3.0
*
*/
(function($) {
jQuery.fn.extend({
slimScroll: function(options) {
var defaults = {
// width in pixels of the visible scroll area
width : 'auto',
// height in pixels of the visible scroll area
height : '250px',
// width in pixels of the scrollbar and rail
size : '7px',
// scrollbar color, accepts any hex/color value
color: '#000',
// scrollbar position - left/right
position : 'right',
// distance in pixels between the side edge and the scrollbar
distance : '1px',
// default scroll position on load - top / bottom / $('selector')
start : 'top',
// sets scrollbar opacity
opacity : .4,
// enables always-on mode for the scrollbar
alwaysVisible : false,
// check if we should hide the scrollbar when user is hovering over
disableFadeOut : false,
// sets visibility of the rail
railVisible : false,
// sets rail color
railColor : '#333',
// sets rail opacity
railOpacity : .2,
// whether we should use jQuery UI Draggable to enable bar dragging
railDraggable : true,
// defautlt CSS class of the slimscroll rail
railClass : 'slimScrollRail',
// defautlt CSS class of the slimscroll bar
barClass : 'slimScrollBar',
// defautlt CSS class of the slimscroll wrapper
wrapperClass : 'slimScrollDiv',
// check if mousewheel should scroll the window if we reach top/bottom
allowPageScroll : false,
// scroll amount applied to each mouse wheel step
wheelStep : 20,
// scroll amount applied when user is using gestures
touchScrollStep : 200,
// sets border radius
borderRadius: '7px',
// sets border radius of the rail
railBorderRadius : '7px'
};
var o = $.extend(defaults, options);
// do it for every element that matches selector
this.each(function(){
var isOverPanel, isOverBar, isDragg, queueHide, touchDif,
barHeight, percentScroll, lastScroll,
divS = '<div></div>',
minBarHeight = 30,
releaseScroll = false;
// used in event handlers and for better minification
var me = $(this);
// ensure we are not binding it again
if (me.parent().hasClass(o.wrapperClass))
{
// start from last bar position
var offset = me.scrollTop();
// find bar and rail
bar = me.parent().find('.' + o.barClass);
rail = me.parent().find('.' + o.railClass);
getBarHeight();
// check if we should scroll existing instance
if ($.isPlainObject(options))
{
// Pass height: auto to an existing slimscroll object to force a resize after contents have changed
if ( 'height' in options && options.height == 'auto' ) {
me.parent().css('height', 'auto');
me.css('height', 'auto');
var height = me.parent().parent().height();
me.parent().css('height', height);
me.css('height', height);
}
if ('scrollTo' in options)
{
// jump to a static point
offset = parseInt(o.scrollTo);
}
else if ('scrollBy' in options)
{
// jump by value pixels
offset += parseInt(o.scrollBy);
}
else if ('destroy' in options)
{
// remove slimscroll elements
bar.remove();
rail.remove();
me.unwrap();
return;
}
// scroll content by the given offset
scrollContent(offset, false, true);
}
return;
}
// optionally set height to the parent's height
o.height = (o.height == 'auto') ? me.parent().height() : o.height;
// wrap content
var wrapper = $(divS)
.addClass(o.wrapperClass)
.css({
position: 'relative',
overflow: 'hidden',
width: o.width,
height: o.height
});
// update style for the div
me.css({
overflow: 'hidden',
width: o.width,
height: o.height
});
// create scrollbar rail
var rail = $(divS)
.addClass(o.railClass)
.css({
width: o.size,
height: '100%',
position: 'absolute',
top: 0,
display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',
'border-radius': o.railBorderRadius,
background: o.railColor,
opacity: o.railOpacity,
zIndex: 90
});
// create scrollbar
var bar = $(divS)
.addClass(o.barClass)
.css({
background: o.color,
width: o.size,
position: 'absolute',
top: 0,
opacity: o.opacity,
display: o.alwaysVisible ? 'block' : 'none',
'border-radius' : o.borderRadius,
BorderRadius: o.borderRadius,
MozBorderRadius: o.borderRadius,
WebkitBorderRadius: o.borderRadius,
zIndex: 99
});
// set position
var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance };
rail.css(posCss);
bar.css(posCss);
// wrap it
me.wrap(wrapper);
// append to parent div
me.parent().append(bar);
me.parent().append(rail);
// make it draggable and no longer dependent on the jqueryUI
if (o.railDraggable){
bar.bind("mousedown", function(e) {
var $doc = $(document);
isDragg = true;
t = parseFloat(bar.css('top'));
pageY = e.pageY;
$doc.bind("mousemove.slimscroll", function(e){
currTop = t + e.pageY - pageY;
bar.css('top', currTop);
scrollContent(0, bar.position().top, false);// scroll content
});
$doc.bind("mouseup.slimscroll", function(e) {
isDragg = false;hideBar();
$doc.unbind('.slimscroll');
});
return false;
}).bind("selectstart.slimscroll", function(e){
e.stopPropagation();
e.preventDefault();
return false;
});
}
// on rail over
rail.hover(function(){
showBar();
}, function(){
hideBar();
});
// on bar over
bar.hover(function(){
isOverBar = true;
}, function(){
isOverBar = false;
});
// show on parent mouseover
me.hover(function(){
isOverPanel = true;
showBar();
hideBar();
}, function(){
isOverPanel = false;
hideBar();
});
// support for mobile
me.bind('touchstart', function(e,b){
if (e.originalEvent.touches.length)
{
// record where touch started
touchDif = e.originalEvent.touches[0].pageY;
}
});
me.bind('touchmove', function(e){
// prevent scrolling the page if necessary
if(!releaseScroll)
{
e.originalEvent.preventDefault();
}
if (e.originalEvent.touches.length)
{
// see how far user swiped
var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;
// scroll content
scrollContent(diff, true);
touchDif = e.originalEvent.touches[0].pageY;
}
});
// set up initial height
getBarHeight();
// check start position
if (o.start === 'bottom')
{
// scroll content to bottom
bar.css({ top: me.outerHeight() - bar.outerHeight() });
scrollContent(0, true);
}
else if (o.start !== 'top')
{
// assume jQuery selector
scrollContent($(o.start).position().top, null, true);
// make sure bar stays hidden
if (!o.alwaysVisible) { bar.hide(); }
}
// attach scroll events
attachWheel();
function _onWheel(e)
{
// use mouse wheel only when mouse is over
if (!isOverPanel) { return; }
var e = e || window.event;
var delta = 0;
if (e.wheelDelta) { delta = -e.wheelDelta/120; }
if (e.detail) { delta = e.detail / 3; }
var target = e.target || e.srcTarget || e.srcElement;
if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {
// scroll content
scrollContent(delta, true);
}
// stop window scroll
if (e.preventDefault && !releaseScroll) { e.preventDefault(); }
if (!releaseScroll) { e.returnValue = false; }
}
function scrollContent(y, isWheel, isJump)
{
releaseScroll = false;
var delta = y;
var maxTop = me.outerHeight() - bar.outerHeight();
if (isWheel)
{
// move bar with mouse wheel
delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();
// move bar, make sure it doesn't go out
delta = Math.min(Math.max(delta, 0), maxTop);
// if scrolling down, make sure a fractional change to the
// scroll position isn't rounded away when the scrollbar's CSS is set
// this flooring of delta would happened automatically when
// bar.css is set below, but we floor here for clarity
delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);
// scroll the scrollbar
bar.css({ top: delta + 'px' });
}
// calculate actual scroll amount
percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight());
delta = percentScroll * (me[0].scrollHeight - me.outerHeight());
if (isJump)
{
delta = y;
var offsetTop = delta / me[0].scrollHeight * me.outerHeight();
offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);
bar.css({ top: offsetTop + 'px' });
}
// scroll content
me.scrollTop(delta);
// fire scrolling event
me.trigger('slimscrolling', ~~delta);
// ensure bar is visible
showBar();
// trigger hide when scroll is stopped
hideBar();
}
function attachWheel()
{
if (window.addEventListener)
{
this.addEventListener('DOMMouseScroll', _onWheel, false );
this.addEventListener('mousewheel', _onWheel, false );
this.addEventListener('MozMousePixelScroll', _onWheel, false );
}
else
{
document.attachEvent("onmousewheel", _onWheel)
}
}
function getBarHeight()
{
// calculate scrollbar height and make sure it is not too small
barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);
bar.css({ height: barHeight + 'px' });
// hide scrollbar if content is not long enough
var display = barHeight == me.outerHeight() ? 'none' : 'block';
bar.css({ display: display });
}
function showBar()
{
// recalculate bar height
getBarHeight();
clearTimeout(queueHide);
// when bar reached top or bottom
if (percentScroll == ~~percentScroll)
{
//release wheel
releaseScroll = o.allowPageScroll;
// publish approporiate event
if (lastScroll != percentScroll)
{
var msg = (~~percentScroll == 0) ? 'top' : 'bottom';
me.trigger('slimscroll', msg);
}
}
else
{
releaseScroll = false;
}
lastScroll = percentScroll;
// show only when required
if(barHeight >= me.outerHeight()) {
//allow window scroll
releaseScroll = true;
return;
}
bar.stop(true,true).fadeIn('fast');
if (o.railVisible) { rail.stop(true,true).fadeIn('fast'); }
}
function hideBar()
{
// only hide when options allow it
if (!o.alwaysVisible)
{
queueHide = setTimeout(function(){
if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg)
{
bar.fadeOut('slow');
rail.fadeOut('slow');
}
}, 1000);
}
}
});
// maintain chainability
return this;
}
});
jQuery.fn.extend({
slimscroll: jQuery.fn.slimScroll
});
})(jQuery);

I've just played around with this script and I kept adjusting the numbers and these are the numbers that felt more natural to me.
wheelStep : 10,
touchScrollStep : 75
The only thing I'm not happy with is how it doesn't understand how fast you scrolled with touch events, so it doesn't have that inertia effect like native iOS does naturally. I'm hoping they'll add that option soon.

Find
delta = (y > 0) ? Math.ceil(delta): Math.floor(delta);
and change it to the following:
var speedfix = 10;
delta = (y > 0) ? Math.ceil(delta) + speedfix : Math.floor(delta)- speedfix;
Change the value of speedfix to your requirement

Related

How can I recalculate a variable upon screen resize?

I have two variables that calculate the clientHeight, divide by 2 and add 44. It is currently working as intended except if the window is resized, the page needs to be refreshed for it to recalculate clientHeight. Once it is refreshed, it repositions the div correctly. How can I recalculate the clientHeight for each upon window resize so the page doesn't need to be refreshed for it to run the script again and grab the new height?
This is part of an animation that animates based on scroll position. As you scroll down the page, the div animates.
var triggerOffset = document.documentElement.clientHeight / 2 + 44;
var cardHeight = $('#card').outerHeight(true) / 2 + 22;
var duration = 1000;
var requestId = null;
var sceneStart;
if (window.matchMedia("(max-width: 1080px)").matches) {
sceneStart = 4000
} else {
sceneStart = 4000
}
console.log(sceneStart);
TweenLite.set(".contain", {
top: triggerOffset - cardHeight
});
TweenLite.set(".timeline-trigger", {
top: triggerOffset
});
TweenLite.set(".start-trigger", {
top: sceneStart
});
TweenLite.set(".end-trigger", {
top: sceneStart + duration
});
// SCROLL MAGIC!!!
var tl = new TimelineMax({ paused: true })
.set(".card", { }, sceneStart)
.to(".card", duration, { rotationY: 180 }, sceneStart)
.set(".card", { })
// Only update on animation frames
window.addEventListener("scroll", function() {
if (!requestId) {
requestId = requestAnimationFrame(update);
}
});
update();
// Set timeline time to scrollTop
function update() {
tl.time(window.pageYOffset + triggerOffset);
requestId = null;
}
I'm hoping to have the position of the card adjust when the window is resized. Currently, the window needs to be refreshed for it to recalculate.
You are looking for window.onresize
window.addEventListener("resize", function() {
triggerOffset = document.documentElement.clientHeight / 2 + 44;
});
You can use the window.onresize global event listeners be providing it a function that will simply recalculate your triggerOffset :
// THIS IS THE VARIABLE I WANT TO CHANGE ON RESIZE
var triggerOffset = document.documentElement.clientHeight / 2 + 44;
window.onresize = function() {
// each time the window will resize this code will trigger
// we re cacalculate the triggerOffset value
triggerOffset = document.documentElement.clientHeight / 2 + 44;
// we also need to se reset the top value onto the .contain dom element
// basically since we recalculated the triggerOffset you must also update where this value was needed
TweenLite.set(".contain", {
top: triggerOffset - cardHeight
});
TweenLite.set(".timeline-trigger", {
top: triggerOffset
});
}
TweenLite.set(".contain", {
top: triggerOffset - cardHeight
});
TweenLite.set(".timeline-trigger", {
top: triggerOffset
});
TweenLite.set(".start-trigger", {
top: sceneStart
});
TweenLite.set(".end-trigger", {
top: sceneStart + duration
});
UPDATE :
A better solution if you are using multiple scripts file where you are doing the same logic is using the 'resize' event provided by #ControlAltDel.
In each script file you will add en event listener and put your logic in the callback :
window.addEventListener("resize", function() {
triggerOffset = document.documentElement.clientHeight / 2 + 44;
TweenLit.set(...);
TweenLit.set(...);
});

Building an animated menu with Jquery that responds to page scrolling

Sorry for the terrible title, but I'm not sure how else to describe what I'm trying to build. I'm using some code I found on this site, basically what I'm trying to do is build a left handed navigation menu, that highlights the appropriate section as the user scrolls to it.
$(document).ready(function() {
var topRange = 200, // measure from the top of the viewport to X pixels down
edgeMargin = 20, // margin above the top or margin from the end of the page
animationTime = 600, // time in milliseconds
contentTop = []; //array of sidebar links
$('nav ul').append('<div id="slider"></div>');
var sliderTop = $("nav ul li a").eq(0).parent().position().top;
var sliderLeft = $("nav ul li a").eq(0).parent().position().left;
var sliderHeight = $("nav ul li a").eq(0).parent().outerHeight();
$('#slider').css({
'height': sliderHeight,
'left': sliderLeft,
'top': sliderTop,
'width': '100%'
});
// Stop animated scroll if the user does something
$('html,body').bind('scroll mousedown DOMMouseScroll mousewheel keyup', function(e) {
if (e.which > 0 || e.type == 'mousedown' || e.type == 'mousewheel') {
$('html,body').stop();
}
})
// Set up content an array of locations
$('#sidebar').find('a').each(function() {
contentTop.push($($(this).attr('href')).offset().top);
})
// Animate menu scroll to content
$('#sidebar').find('a').click(function() {
var sel = this,
newTop = Math.min(contentTop[$('#sidebar a').index($(this))], $(document).height() - $(window).height()); // get content top or top position if at the document bottom
$('html,body').stop().animate({
'scrollTop': newTop
}, animationTime, function() {
window.location.hash = $(sel).attr('href');
});
return false;
})
//scroll function
function scroller() {
var winTop = $(window).scrollTop(),
bodyHt = $(document).height(),
vpHt = $(window).height() + edgeMargin; // viewport height + margin
$.each(contentTop, function(i, loc) {
if ((loc > winTop - edgeMargin && (loc < winTop + topRange || (winTop + vpHt) >= bodyHt))) {
//animate slider
x = $("#sidebar li").eq(i).position();
$("#slider").animate({
top: (x.top)
}, 100);
}
})
}
//scroll event handler
$(window).scroll(scroller)
})
I have most of it working, however when you actually click a link on the menu the animation is very slow to catch up with the actual scrolling. I understand why this is happening, because it updates the position one at a time after each section is reached, but I'm wondering if there's a way to make this animation faster, and more fluid. I've attached a fiddle with my code, thank you in advance for your help!
http://jsfiddle.net/jamesmyers/6mbmq1pe/
You will get a better slider animation effect by temporarily detaching the scroll handler and scrolling the slider directly, with the same animationTime as for the main animation.
To do this, you also need to :
namespace the scroll event .nav, to allow safe use of .off()
stop() the slider animation in the "if the user does something" block
I've also included a few efficiency savings in the way contentTop and #slider are set up but these are not actually necessary.
$(document).ready(function() {
var topRange = 200, // measure from the top of the viewport to X pixels down
edgeMargin = 20, // margin above the top or margin from the end of the page
animationTime = 600, // time in milliseconds
contentTop, //array of sidebar links
navLinkWrapper = $("nav ul li a").eq(0).parent();
var $slider = $("<div id=\"slider\" />").css({
'height': navLinkWrapper.outerHeight(),
'left': navLinkWrapper.position().left,
'top': navLinkWrapper.position().top,
'width': '100%'
}).appendTo($('nav ul'));
// Stop animated scroll if the user does something
$('html,body').on('scroll mousedown DOMMouseScroll mousewheel keyup', function(e) {
if (e.which > 0 || e.type == 'mousedown' || e.type == 'mousewheel') {
$('html,body').stop();
$slider.stop(); //<<<<<<<
}
});
// Set up content an array of locations
contentTop = $('#sidebar a').map(function() {
return $($(this).attr('href')).offset().top;
});
// Animate menu scroll to content
$('#sidebar a').on('click', function(e) {
e.preventDefault();
$(window).off('scroll.nav', scroller); //<<<<<<<
$slider.stop().animate({ //<<<<<<<
top: ($(this).closest("li").position().top) //<<<<<<<
}, animationTime); //<<<<<<<
var sel = this,
newTop = Math.min(contentTop[$('#sidebar a').index($(this))], $(document).height() - $(window).height()); // get content top or top position if at the document bottom
$('html,body').stop().animate({
'scrollTop': newTop
}, animationTime, function() {
window.location.hash = $(sel).attr('href');
$(window).on('scroll.nav', scroller); //<<<<<<<
});
});
//scroll function
function scroller() {
var winTop = $(window).scrollTop(),
bodyHt = $(document).height(),
vpHt = $(window).height() + edgeMargin; // viewport height + margin
$.each(contentTop, function(i, loc) {
if ((loc > winTop - edgeMargin && (loc < winTop + topRange || (winTop + vpHt) >= bodyHt))) {
//animate slider
$slider.animate({
top: ($("#sidebar li").eq(i).position().top)
}, 100);
}
});
}
//scroll event handler
$(window).on('scroll.nav', scroller); //<<<<<<<
});
Updated fiddle

How to Recreate the Android Facebook app's view swiping UX?

I'm looking to make something exactly like Facebook's Android app's UX for swiping between News Feed, Friend Requests, Messages, and Notifications. You should be able to "peek" at the next view by panning to the right of left, and it should snap to the next page when released if some threshold has been passed or when swiped.
Every scroll snap solution I've seen only snaps after the scrolling stops, whereas I only ever want to scroll one page at a time.
EDIT: Here's what I have so far. It seems to work fine when emulating an Android device in Google Chrome, but doesn't work when I run it on my Galaxy S4 running 4.4.2. Looking into it a bit more, it looks like touchcancel is being fired right after the first touchmove event which seems like a bug. Is there any way to get around this?
var width = parseInt($(document.body).width());
var panThreshold = 0.15;
var currentViewPage = 0;
$('.listContent').on('touchstart', function(e) {
console.log("touchstart");
currentViewPage = Math.round(this.scrollLeft / width);
});
$('.listContent').on('touchend', function(e) {
console.log("touchend");
var delta = currentViewPage * width - this.scrollLeft;
if (Math.abs(delta) > width * panThreshold) {
if (delta < 0) {
currentViewPage++;
} else {
currentViewPage--;
}
}
$(this).animate({
scrollLeft: currentViewPage * width
}, 100);
});
In case anyone wants to do this in the future, the only way I found to actually do this was to manually control all touch events and then re-implement the normally-native vertical scrolling.
It might not be the prettiest, but here's a fiddle to what I ended up doing (edited to use mouse events instead of touch events): http://jsfiddle.net/xtwzcjhL/
$(function () {
var width = parseInt($(document.body).width());
var panThreshold = 0.15;
var currentViewPage = 0;
var start; // Screen position of touchstart event
var isHorizontalScroll = false; // Locks the scrolling as horizontal
var target; // Target of the first touch event
var isFirst; // Is the first touchmove event
var beginScrollTop; // Beginning scrollTop of ul
var atanFactor = 0.6; // atan(0.6) = ~31 degrees (or less) from horizontal to be considered a horizontal scroll
var isMove = false;
$('body').on('mousedown', '.listContent', function (e) {
isMove = true;
isFirst = true;
isHorizontalScroll = false;
target = $(this);
currentViewPage = Math.round(target.scrollLeft() / width);
beginScrollTop = target.closest('ul').scrollTop();
start = {
x: e.originalEvent.screenX,
y: e.originalEvent.screenY
}
}).on('mousemove', '.listContent', function (e) {
if (!isMove) {
return false;
}
e.preventDefault();
var delta = {
x: start.x - e.originalEvent.screenX,
y: start.y - e.originalEvent.screenY
}
// If already horizontally scrolling or the first touchmove is within the atanFactor, horizontally scroll, otherwise it's a vertical scroll of the ul
if (isHorizontalScroll || (isFirst && Math.abs(delta.x * atanFactor) > Math.abs(delta.y))) {
isHorizontalScroll = true;
target.scrollLeft(currentViewPage * width + delta.x);
} else {
target.closest('ul').scrollTop(beginScrollTop + delta.y);
}
isFirst = false;
}).on('mouseup mouseout', '.listContent', function (e) {
isMove = false;
isFirst = false;
if (isHorizontalScroll) {
var delta = currentViewPage * width - target.scrollLeft();
if (Math.abs(delta) > width * panThreshold) {
if (delta < 0) {
currentViewPage++;
} else {
currentViewPage--;
}
}
$(this).animate({
scrollLeft: currentViewPage * width
}, 100);
}
});
});

How can i scroll the page with img tag [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to scroll the page vertically without using the scrollbar.
instead i want to use 2 image tags for scrolling the page.
this was the code i tried for the scroll but it didnt look good:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<style type="text/css">
div.mousescroll {
overflow: hidden;
}
div.mousescroll:hover {
overflow-y: scroll;
}
</style>
<script language="javascript" type="text/javascript">
$(function() {
$(".wrapper1").scroll(function left() {
$(".wrapper2")
.scrollLeft($(".wrapper1").scrollLeft());
});
$(".wrapper2").scroll(function right() {
$(".wrapper1")
.scrollLeft($(".wrapper2").scrollLeft());
});
});
</script>
<div id="first" class="wrapper1 ">
<div id="first2" class=" div1 ">
</div>
<br />
</div>
<br />
<div id="second" class="wrapper2 mousescroll">
<div id="second2" style=" overflow-x:scroll" class="div2">
<table>
...............
</table>
</div>
</div>
imagine that the width of this table is 2000px and instead of scrollbar i wanna use two image tags that can do the scroll job.
can anyone help me with this?
$(window).load(function () {
(function ($) {
jQuery.fn.extend({
slimScroll: function (o) {
var ops = o;
//do it for every element that matches selector
this.each(function () {
var isOverPanel,
isOverBar,
isDragg,
queueHide,
barHeight,
divS = "<div></div>",
minBarHeight = 30,
wheelStep = 30,
o = ops || {},
cwidth = o.width || "auto",
cheight = o.height || "250px",
size = o.size || "7px",
color = o.color || "#000",
position = o.position || "right",
opacity = o.opacity || 0.4,
alwaysVisible = o.alwaysVisible === true;
//used in event handlers and for better minification
var me = $(this);
//wrap content
var wrapper = $(divS)
.css({
position: "relative",
overflow: "hidden",
width: cwidth,
height: cheight,
})
.attr({ class: "slimScrollDiv" });
//update style for the div
me.css({
overflow: "hidden",
width: cwidth,
height: cheight,
});
//create scrollbar rail
var rail = $(divS).css({
width: "15px",
height: "100%",
position: "absolute",
top: 0,
});
//create scrollbar
var bar = $(divS)
.attr({
class: "slimScrollBar ",
style: "border-radius: " + size,
})
.css({
background: color,
width: size,
position: "absolute",
top: 0,
opacity: opacity,
display: alwaysVisible ? "block" : "none",
BorderRadius: size,
MozBorderRadius: size,
WebkitBorderRadius: size,
zIndex: 99,
});
//set position
var posCss = position == "right" ? { right: "1px" } : { left: "1px" };
rail.css(posCss);
bar.css(posCss);
//wrap it
me.wrap(wrapper);
//append to parent div
me.parent().append(bar);
me.parent().append(rail);
//make it draggable
bar.draggable({
axis: "y",
containment: "parent",
start: function () {
isDragg = true;
},
stop: function () {
isDragg = false;
hideBar();
},
drag: function (e) {
//scroll content
scrollContent(0, $(this).position().top, false);
},
});
//on rail over
rail.hover(
function () {
showBar();
},
function () {
hideBar();
}
);
//on bar over
bar.hover(
function () {
isOverBar = true;
},
function () {
isOverBar = false;
}
);
//show on parent mouseover
me.hover(
function () {
isOverPanel = true;
showBar();
hideBar();
},
function () {
isOverPanel = false;
hideBar();
}
);
var _onWheel = function (e) {
//use mouse wheel only when mouse is over
if (!isOverPanel) {
return;
}
var e = e || window.event;
var delta = 0;
if (e.wheelDelta) {
delta = -e.wheelDelta / 120;
}
if (e.detail) {
delta = e.detail / 3;
}
//scroll content
scrollContent(0, delta, true);
//stop window scroll
if (e.preventDefault) {
e.preventDefault();
}
e.returnValue = false;
};
var scrollContent = function (x, y, isWheel) {
var delta = y;
if (isWheel) {
//move bar with mouse wheel
delta = bar.position().top + y * wheelStep;
//move bar, make sure it doesn't go out
delta = Math.max(delta, 0);
var maxTop = me.outerHeight() - bar.outerHeight();
delta = Math.min(delta, maxTop);
//scroll the scrollbar
bar.css({ top: delta + "px" });
}
//calculate actual scroll amount
percentScroll =
parseInt(bar.position().top) /
(me.outerHeight() - bar.outerHeight());
delta = percentScroll * (me[0].scrollHeight - me.outerHeight());
//scroll content
me.scrollTop(delta);
//ensure bar is visible
showBar();
};
var attachWheel = function () {
if (window.addEventListener) {
this.addEventListener("DOMMouseScroll", _onWheel, false);
this.addEventListener("mousewheel", _onWheel, false);
} else {
document.attachEvent("onmousewheel", _onWheel);
}
};
//attach scroll events
attachWheel();
var getBarHeight = function () {
//calculate scrollbar height and make sure it is not too small
barHeight = Math.max(
(me.outerHeight() / me[0].scrollHeight) * me.outerHeight(),
minBarHeight
);
bar.css({ height: barHeight + "px" });
};
//set up initial height
getBarHeight();
var showBar = function () {
//recalculate bar height
getBarHeight();
clearTimeout(queueHide);
//show only when required
if (barHeight >= me.outerHeight()) {
return;
}
bar.fadeIn("fast");
};
var hideBar = function () {
//only hide when options allow it
if (!alwaysVisible) {
queueHide = setTimeout(function () {
if (!isOverBar && !isDragg) {
bar.fadeOut("slow");
}
}, 1000);
}
};
});
//maintain chainability
return this;
},
});
jQuery.fn.extend({
slimscroll: jQuery.fn.slimScroll,
});
})(jQuery);
//invalid name call
$("#Id").slimscroll({
color: "#aaa",
size: "6px",
width: "392px",
height: "525px",
});
});

Centering a div in firefox with jQuery

So I am attempting to use the following code to center a div in the window using jQuery:
(function($) {
$.fn.extend({
center: function(options) {
var options = $.extend({ // Default values
inside: window,
// element, center into window
transition: 0,
// millisecond, transition time
minX: 0,
// pixel, minimum left element value
minY: 0,
// pixel, minimum top element value
withScrolling: true,
// booleen, take care of the scrollbar (scrollTop)
vertical: true,
// booleen, center vertical
horizontal: true // booleen, center horizontal
}, options);
return this.each(function() {
var props = {
position: 'absolute'
};
if (options.vertical) {
var top = ($(options.inside).height() - $(this).outerHeight()) / 2;
if (options.withScrolling) top += $(options.inside).scrollTop() || 0;
top = (top > options.minY ? top : options.minY);
$.extend(props, {
top: top + 'px'
});
}
if (options.horizontal) {
var left = ($(options.inside).width() - $(this).outerWidth()) / 2;
if (options.withScrolling) left += $(options.inside).scrollLeft() || 0;
left = (left > options.minX ? left : options.minX);
$.extend(props, {
left: left + 'px'
});
}
if (options.transition > 0) $(this).animate(props, options.transition);
else $(this).css(props);
return $(this);
});
}
});
})(jQuery);​
This works fine in Chrome but it doesn't seem to vertically center in firefox and I can't figure what I am doing wrong. Is there a bug with firefox that would render it unable to calculate the window height?
I can't remember what I've changed but here it is:
$.fn.extend({
center: function(options) {
var options = $.extend({ // Default values
inside: window,
// element, center into window
transition: 0,
// millisecond, transition time
minX: 0,
// pixel, minimum left element value
minY: 0,
// pixel, minimum top element value
withScrolling: true,
// booleen, take care of the scrollbar (scrollTop)
vertical: true,
// booleen, center vertical
horizontal: true // booleen, center horizontal
}, options);
$(this).each(function() {
var props = {
position: 'absolute'
};
if (options.vertical) {
var top = ($(options.inside).height() - $(this).outerHeight()) / 2;
if (options.withScrolling) top += $(options.inside).scrollTop() || 0;
top = (top > options.minY ? top : options.minY);
$.extend(props, {
top: top + 'px'
});
}
if (options.horizontal) {
var left = ($(options.inside).width() - $(this).outerWidth()) / 2;
if (options.withScrolling) left += $(options.inside).scrollLeft() || 0;
left = (left > options.minX ? left : options.minX);
$.extend(props, {
left: left + 'px'
});
}
if (options.transition > 0) $(this).animate(props, options.transition);
else $(this).css(props);
});
return $(this);
}
});
It seems to work fine in firefox: http://jsfiddle.net/NQRUF/4/
Try this:
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - this.outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - this.outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
Usage:
$(element).center();
Source

Categories

Resources