First of all I want to say that I really like Scrollify and I am now planning to use it. The idea for my site is to have some sections that have snap scrolling behavior and some sections with normal scrolling. Everything works fine EXCEPT that I don't want it to do snap scroll when going from a snap section to a normal section. As it is now it snap scrolls to the normal section and first after it has snapped it goes to normal scrolling.
In other words I think what I am looking for is to be able to control when snap-scrolling is enabled depending on the element that is in the viewport. Maybe there is an easier solution though.
Do you have any suggestions?
(function() {
var firstSection = $('.wrapper .normal-page').eq(0)[0]
var firstSectionClassName = $(firstSection).attr('class')
var base = this;
$.scrollify({
section : ".product-page",
sectionName : "section-name",
interstitialSection : ".normal-page",
easing: "easeOutExpo",
scrollSpeed: 1100,
offset : 0,
scrollbars: true,
standardScrollElements: ".normal-page",
setHeights: true,
overflowScroll: true,
before:function(index, arr) {
var currentItem = $.scrollify.current().attr('class')
if (currentItem !== "product-page") {
$.scrollify.disable();
}
},
after:function() {
$.scrollify.enable();
},
afterResize:function() {
},
afterRender:function() {
console.log("move to the top")
$.scrollify.instantMove("#" + firstSectionClassName)
}
});
})()
HTML
<body>
<div class="wrapper">
<div class="normal-page"></div>
<div class="product-page"></div>
<div class="normal-page"></div>
<div class="product-page"></div>
<div class="normal-page"></div>
</div>
</body>
so I am already trying with the enable and disable methods, but
You'll probably need to use the disable and enable methods to achieve this.
Related
First time using jquery-scrollify. I have a page with a border around it and each section is meant to start 24px from top of page so it starts below the border. Without scrollify my CSS does this fine. Once I implement scrollify, even with the correct offset option, the page is always scrolled so that the top of this first section is right at the top of the page. Once I start scrolling to lower sections, they are respecting the offset and aligning properly. It seems the offset options is ignored for the first section? Is there any way to make the offset apply to the first section / start of page?
HTML
<section class="hero-home">
<div class="slide" style="background-image: url('/img/hero-home1.jpg')"></div>
<div class="slide" style="background-image: url('/img/hero-home2.jpg')"></div>
<div class="slide" style="background-image: url('/img/hero-home3.jpg')"></div>
<div class="slide" style="background-image: url('/img/hero-home4.jpg')"></div>
</section>
JS
var scrollOffset = -24;
$.scrollify({
section: ".slide:visible",
offset: scrollOffset,
easing: "easeOutQuint",
scrollSpeed: 800,
scrollbars: true,
setHeights: false,
updateHash: false,
touchScroll: true
});
The -24 offset is to account for a fixed position frame I have at top of the page. When a new "section" is scrolled to the top, it should stop 24px from top of page rather than right at the top, otherwise it goes under the frame.
The first "section" starts in the right place before I initiate scrollify (my CSS on a containing element has top padding equal to height of the frame). However once scrollify is added, the page is scrolled down 24px so that the first "section" appears right at the top of page. The "offset" options corrects this on all subsequent sections (2nd, 3rd, and 4th section appear at the right place when I scroll down) but the 1st section's initial position is incorrect and ignores the offset option value.
I struggled with this issue as well, to fix this issue you want to provide some handling in the before event.
Solution Example
$(document).ready(function() {
$.scrollify({
section : ".fp-section",
offset:-200,
setHeights:false,
//Add the offset for the first element here:
//snapToElm is the list of element pages
before:function(indexPosition,snapToElm){
if(indexPosition===0){
snapToElm[0].css({"margin-top":"200px"});
}
if(indexPosition>0){
snapToElm[0].css({"margin-top":"0"});
}
},
afterRender:function(){
//set the first element initially to the desired offset
$($(this.section)[0]).css({"margin-top":"200px"});
// stuff to do once scrollify has rendered the list
}
})
});
$.scrollify({
section: "section",
interstitialSection: ".fourth-view,footer",
easing: "easeOutExpo",
scrollSpeed: 1100,
offset:0,
scrollbars: true,
standardScrollElements: "",
setHeights: false,
overflowScroll: true,
updateHash: false,
touchScroll: true,
before: function () {
},
after: function () {
},
afterResize: function () {
},
afterRender: function () {
}
});
if ($.scrollify.current().hasClass('second-view')) {
$.scrollify.setOptions({offset: 0})
}
else {
$.scrollify.setOptions({offset: -64.5})
}
and also
$(window).on('scroll', function () {
if ($.scrollify.current().hasClass('second-view')) {
$.scrollify.setOptions({offset: 0})
}
else {
$.scrollify.setOptions({offset: -64.5})
}
});
remove offset for second section
Change the source code line 660 of jquery.scrollify.js
if(i>0) {
heights[i] = parseInt($this.offset().top) + settings.offset;
} else {
heights[i] = parseInt($this.offset().top);
}
Change to
heights[i] = parseInt($this.offset().top) + settings.offset;
The version of jQuery Scrollify is 1.0.20
I tried the solution below but finally I just added the "section / slide class" to my header or navbar (<header class="slide navbar otherclasses..."></header>) that make my navbar the first element, it may not fit anyone but in my case its by far the most confortable for my users.
Edit : you need to set setHeights: false otherwise its not going to work well.
So I have this layout here .
<div class="content">
<div class="direction_left"></div>
<div class="direction_right"></div>
<div class="direction_up"></div>
<div class="direction_down"></div>
</div>
<div id="game">
<div id="pos"></div>
</div>
4 divs, if I hover on top it (should) scroll top, if I hover on bottom it (should) scroll bot, left scrolls left and right scrolls right!
On mouse hover on any of the four divs inside the content will scroll the page accordingly.
Important h_amount is horizontal and v_amount is for vertical
function scroll_h() {
console.log('scrolling left and right'+h_amount);
$('#game').animate({
scrollLeft: h_amount
}, 100, 'linear',function() {
if (h_amount != '') {
scroll_h();
}
});
}
function scroll_v() {
console.log('scrolling up and down'+v_amount);
$('#game').animate({
scrollTop: v_amount
}, 100, 'linear',function() {
if (v_amount != '') {
scroll_v();
}
});
}
and then on hover I call
$('.direction_right').hover(function() {
console.log('scroll right');
h_amount = '+=50';
scroll_h();
}, function() {
h_amount = '';
});
$('.direction_up').hover(function() {
console.log('scroll up');
v_amount = '-=50';
scroll_v();
}, function() {
v_amount = '';
});
FULL fiddle here
The problem, I cannot understand why it does not work for up and down. I think my script is correct so am thinking maybe css which is a general weakness of mine might be wrong :D help!
I think I found my answer, please correct me if I am wrong!
Found this question here which asks why his scrollTop() wont animate, and the answer says that window does not have a scrollTop() property, and to use body or html instead (depends on browser, so use both).
Therefore I think my #game div does not have a scrollTop() property either! So I replaced it with html,body and its now working :D.
*
P.S. Don't really know if its actually working or "working".
*
new fiddle here
Also changed that gradient background because it made me dizzy!
Please check this almost identical question first: jQuery Sortable List - scroll bar jumps up when sorting
I have exactly the same problem, only that I tried all the suggested solutions there with no luck
Here is the way to reproduce
create a sortable list
have it scrollable
scroll down
reorder items
scroll position "jumps" up
Here is the code (see also in JSFiddle)
Html
<ul id="panel" class="scroll">
<li class="content" style="background-color:red">item1</li>
<li class="content" style="background-color:green">item2</li>
<li class="content" style="background-color:blue">item3</li>
<li class="content" style="background-color:gray">item4</li>
<li class="content" style="background-color:yellow">item5</li>
</ul>
JavaScript
$(function() {
$("#panel").sortable({
items: ".content",
forcePlaceholderSize: true
}).disableSelection();
$(".content").disableSelection();
});
CSS
.scroll{
overflow: scroll;
border:1px solid red;
height: 200px;
width: 150px;
}
.content{
height: 50px;
width: 100%;
}
Here is the code (in JSFiddle) after trying the notion of the accepted answer (with no luck)
I can try to understand why it happens (list get's "shortened" for a quick second), but all attempts to use placeholders or helpers to avoid it didn't work either. I feel I tried almost any permutation of the "scrollable" options with no luck
Browsers I tried
IE9, Firefox 10.0.1, and Chrome 17
JQuery versions
core 1.7.1, UI v 1.8.17
Am I doing something wrong? Is there a solution? Could it be a bug?
If you modifiy your CSS for the .scroll element by adding:
position:relative;
That should resolve this issue.
Adding overflow-y:scroll to the sortable list even without the height property solved it for me. It only shows a disabled scrollbar, but that's okay.
아래로 스크롤 할때 는 이런식으로 하면 됩니다.
var cY = -1;
var base = 0;
$("").sortable({
sort: function(event, ui) {
var nextCY = event.pageY;
if(cY - nextCY < -10){
if(event.clientY + ui.helper.outerHeight(true) - 20 > document.body.clientHeight) {
base = base === 0 ? event.clientY : base;
var move = event.clientY - base;
var curScrollY = $(document).scrollTop();
$(document).scrollTop(curScrollY + move+3);
base = event.clientY;
}
}
},
// .....
});
Seems like jQuery UI 1.9.2 solved the issue.
If you are unable to change the library, there's a workaround including a simple scroll bar operation. The idea is simple:
Keep the previous scroll position every time you scroll.
Set scroll back to the previous position when you start dragging your element.
Here you go;
var lastScrollPosition = 0; //variables defined in upper scope
var tempScrollPosition = 0;
window.onscroll = function () { // Up to you requirement you may change it to another elemnet e.g $("#YourPanel").onscroll
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function () {
tempScrollPosition = lastScrollPosition; // Scrolls don't change from position a to b. They cover some numbers between a and b during the change to create a smooth sliding visual. That's why we pick the previous scroll position with a timer of 250ms.
}, 250));
lastScrollPosition = $(document).scrollTop(); // Up to you requirement you may change it to another elemnet e.g $("#YourPanel").onscroll
};
$("#YourSortablePanel").sortable({
start: function (event, ui) {
$(document).scrollTop(tempScrollPosition);
}
});
This is caused by the height of the container changing when sorting (just before the placeholder is created)
The problem is well described and answered in this stack overflow : https://stackoverflow.com/a/32477389/2604980
For me this sortable options were working if you don't want to remove overflow css from body:
start(e, ui) {
if (fixOffset) ui.item.css('transform', `translateY(${document.body.scrollTop}px)`);
fixOffset = true;
},
change(e, ui) {
ui.item.css('transform', `translateY(${document.body.scrollTop}px)`);
},
stop(e, ui) {
ui.item.css('transform', 'translateY(0)');
},
I saw this technique at the bottom of a web page where the TAB stays in place at the bottom of the page and can be opened and closed to display more info. I assume it can be rotated to display a different special for different days. Can you point me to anything like it or explain the technique ? thanks. Here is a sample: http://www.tmdhosting.com/ look at the bottom of the page .
position: fixed is how you manage to keep something at the bottom or top of the page, regardless of scrolling.
This is easily discoverable using firebug's (http://getfirebug.com/) inspect element feature
You can check out my version of this at uxspoke.com
I wrote a jQuery plugin to do it, and calling it is straightforward:
$('#about').pulloutPanel({open:true}).
click(function() { $(this).trigger('toggle'); }) });
I basically instrument the panel to support "open", "close" events, and the implement the appropriate animations around them. The only "hard" part is getting the height right. It also supports "toggle" so you can add a generic click handler to it to open or close it. Finally, it uses opened/closed classes to keep track of its current state. That's it!
The code's pretty coupled to the technologies on the page (Csster) and the design it is in, so I'm not sure it will work for you. You can either use Csster, or just put the CSS rules into your stylesheet and remove them from the code. The important Css attributes are the positioning and bottom.
Here it is:
$.fn.pulloutPanel = function(options) {
var settings = $.extend({}, {
attachTo: 'bottom',
css: {
left: 0,
minHeight: 390,
border: '1px 1px 1px 0 solid #666',
has: [roundedCorners('tr', 10),boxShadow([0,0], 10, phaseToColor('requirements').saturate(-30).darken(50))],
cursor: 'pointer'
}, options);
return $(this).each(function() {
var $this = $(this);
$this.addClass('pullout_panel');
$this.bind('open', function(event) {
$this.animate({bottom: 0}, 'slow', 'easeOutBounce', function() {
$this.removeClass('closed').addClass('opened');
$this.trigger('opened');
});
});
$this.bind('close', function(event) {
var height = $this.innerHeight();
$this.animate({bottom: -height + 50}, 'slow', 'easeOutBounce', function() {
$this.addClass('closed').removeClass('opened');
$this.trigger('closed');
});
});
$this.bind('toggle', function(event) {
$this.trigger($this.hasClass('opened') ? 'close' : 'open');
});
once(function() {
Csster.style({
'.pullout_panel': {
position: 'fixed',
bottom: 0,
has: [settings.css]
}
});
});
$this.trigger(settings.open ? 'open' : 'close');
});
};
I'm just working on my personal website, giving it a bit of a revamp.
I've implemented a sort of 'accordion' menu feature, where if a menu button is clicked, the "non-clicked" buttons disappear, and then the clicked button is moved to the top of the list, where then a panel animates down in which I will be putting text content.
In Firefox this works perfectly, however in IE and Chrome the button jumps to the top of the page and then animates to position, instead of animating from where it started from.
Anyone any ideas how to fix this?
Offending code:
function Accordion(e)
{
var o =
{
init: function()
{
o.button = e;
o.addClickHandler();
},
addClickHandler: function()
{
o.button.click(function(){
o.button.removeClass('unselected');
o.button.addClass('selected');
o.fader();
});
},
fader: function()
{
$j('.unselected').animate({opacity:0}, 1000);
var wait = setInterval(function() {
if(!$j('.unselected').is(":animated") ) {
clearInterval(wait);
o.shifter();
}
}, 100);
},
shifter: function()
{
o.button.css({'position':'absolute'});
o.button.animate({top:91}, 500, o.createInfoBox);
},
createInfoBox: function()
{
var buttonParent = o.button.parent();
buttonParent.append("<div class='infoBox'></div>");
$j('.infoBox').animate({height:390});
}
}
o.init();
return o;
}
}
The issue lies within the shifter function, where I'm setting the position to absolute and then animating so the desired effect can be achieved. I understand why it's doing this (presume it's just resetting itself to top:0 and then animating to top:91) but does anyone have a quick solution? It's late and it's doing my head in.
Much appreciated,
Dave
HAve you tried using the current position of the element when you switch it to absolute... for example:
function() {
var currentp = $(this).offset();
o.button.css({'position':'absolute', top: currentp.top});
o.button.animate({top:91}, 500, o.createInfoBox);
}
Note there are two different offset functions and im not sure which one you want use here so you might want to review the docs on that.
Also you could always just re-theme the jQuery-ui accordian and save yourself the trouble ;-)