jQuery Scrollify - first section ignores offset - javascript

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.

Related

Only use scroll-snap on specific sections, otherwise use normal scroll

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.

Scrolling on webpage with mouse location - hover on side elements

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!

Colorbox positioning on top of another element

I've got quite an issue with positioning of colorbox. The methods described on official website http://www.jacklmoore.com/colorbox/ are not quite enough for my purpose. The thing is that I have button opening the colorbox and I need to position it "over the button" (button is 50px height, colorbox is something about 700px height so I need to center it over the button (something like 300px top of the button).
I have tried basic repositioning with jquery in onOpen and onLoad function in colorbox like:
onOpen:function() {
$('#colorbox').removeAttr('top');
$('#colorbox').css('top','200px');
},
It works but colorbox settings automatically overwrite those settings right after onOpen or onLoad and colorbox is positioned in center of the viewport again.
So I am basically calling for help, colorbox positioning settings like top, left etc. are simply not enough for positioning on top of the button element.
Thanks in advance!
Edit: full code below
$(".reserve_").live('click',function() {
var loadUrl = $(this).attr("href");
$.colorbox({
innerWidth:660,
innerHeight:720,
returnFocus: true,
overlayClose: true,
fixed: false,
iframe: true,
href: loadUrl,
opacity: 0.6,
reposition: true,
onOpen:function() {
$('#colorbox').removeAttr('top');//test
$('#colorbox').css('top','200px');//test
},
onLoad: function() {
$('#colorbox').removeAttr('top');//test
$('#colorbox').css('top','200px');//test
},
onClosed:function() {
}
});
return false;
});
EDIT 2: link on jsfiddle: http://jsfiddle.net/zS8J8/8/ (sorry about the messy code in CSS and HTML)
The jsfiddle was helpful, I was able to use the same code as you and get it working.
This was tested in firefox 20, chrome 26, IE 9 on Win 7. The "Open Colorbox" link isn't visible in IE using your HTML, but if you move your mouse in that area, you'll see the cursor change and if you click, Colorbox will open in the correct location.
Here's the HTML, I changed class="rezervuj" to id="rezervuj" because we're keying on a single element rather than a bunch of images:
<h3 style="margin-bottom: 300px;">TOP OF THE PAGE</h3>
<div class="unitKontejner">
<div style="float:right;">
<a id="rezervuj" href="http://www.imgur.com">
<div class="reserveIt">
<div class="reserveIt-content">
open colorbox »
</div>
</div>
</a>
</div>
</div>
Here's the script that you can put in the head:
<script>
$(document).ready(function(){
// I removed the options that were set to the default.
// The top and left can be left out or set to a default,
// I used them as a test to see the difference when the event hook is used.
$("#rezervuj").colorbox({
iframe:true,
innerWidth:660,
innerHeight:720,
opacity: 0.6,
top: 0,
left: 0
});
// Use the "cbox_complete" event hook.
// It allows the colorbox div to be positioned after it opens,
// but before the content is loaded.
$(document).bind('cbox_complete', function(){
// Grab the position of the button,
// colorbox can be positioned relative to it.
var pos = $(rezervuj).position();
//console.log(pos);
// Set the position of the colorbox div
// You can add to or subtract from the pos values
// Example: top: (pos.top + 20) + "px"
$("#colorbox").css({
position: "absolute",
top: pos.top + "px",
left: pos.left + "px"
}).show();
});
});
</script>
you can also try this.
$.colorbox({
width: "600px", height: "500px", inline: false, overlayClose: false, escKey: true, iframe: true,
onComplete: function () {
$('#colorbox').removeAttr('top');//test
$('#colorbox').css('top', '100px');//test
$('#colorbox').removeAttr('display');//test
$('#colorbox').css('display', 'block');//test
},
onLoad: function () {
$('#colorbox').removeAttr('display');//test
$('#colorbox').css('display', 'none');//test
},
});

carouFredSel: Show partial items?

I'm using carouFredSel to create a vertical carousel. Everything works great, except I would prefer if partial items would be shown at the bottom, cropped, rather than being hidden. This way it would indicate to users that there are additional items that can be scrolled.
I have been reading the documentation, but so far can't tell if what I am after is possible.
Check out the JSFiddle to see what I mean. Watch the bottom most item on the page.
Javascript
$("ul").carouFredSel({
direction: "up",
align: "top",
width: 100,
height: "100%",
items: {
visible: "variable",
width: 100,
height: "variable"
},
scroll: {
items: 1,
mousewheel: true,
easing: "swing",
duration: 500
},
auto: false,
prev: {
button: ".prev",
key: "up"
},
next: {
button: ".next",
key: "down"
}
});​
This is a bit of a hack, but it works. Set the height of the scroller (in this case, ul) to 150% and the parent element (in this case, body) to overflow: hidden. Now the bottom most element is off screen.
Javascript
$("ul").carouFredSel({
height: "150%"
});
CSS
body {
overflow: hidden;
}
Ha, caroufredsel supports it, no hacks required :))! You can achieve it with the following option:
items: {
visible: '+1'
}
EDIT: This suffers from a problem though. If number of whole visible items + 1 == number of all items, then carousel cannot be scrolled even though one image is visible just partially. You can overcome this issue by setting e.g. minimum: 1 but it is not always a way to go (e.g. if number of images is dynamic and you don't want scroll handlers to appear when there is just one or two images.).
The next not visible element in the vertical carousel is pushed down by the margin.
I'm currently overriding it by the following function:
function cropCarousel () {
var visibleElements = this.triggerHandler("currentVisible"), // show all visible
$lastElement = $(visibleElements[visibleElements.length - 1]); // get the last one
$lastElement.css('margin-bottom', '30px'); // amend the margin
};
cropCarousel.call($('#your_carousel_id'));
The downside of it that you will have to call this function on carousel init and on up and down events. But it works ;)

How can I alter anythingSlider so that it disables the next / previous buttons when only 1 <li> in the <ul>?

I have a page with multiple instances of anythingSlider on it and I'm using PHP to dynamically load pages that swap out the content in them.
Reference: http://ceedcreative.com/CEED_2.0/
I would like to edit the anythingSlider to disable the previous / next buttons if the UL it's displaying only has one LI within it.
In other words, no buttons, just a clean div that's the same heigh and width (no scrolling) if there's only one image.
Try this
$('.anythingSlider:not("#topSlider")').each(function(i, slider) {
// If any slider has less than 2 let members
if ( $("ul li", slider).length < 2 ) {
// don't apply the slider functionality
return;
}
$(slider).anythingSlider({
easing: "easeInOutExpo",
autoPlay: false,
delay: 3000,
startStopped: false,
animationTime: 600,
hashTags: false,
buildNextPrevButtons: true,
buildNavigation: false
});
});
If, for some reason, that doesn't work, this snippet will inspect the list length of every anythingSlider and hide the arrow buttons for any list that is only 1 in length (after excluding the front and back clones).
$(".anythingSlider").each(function(i, slider) {
if ( $("ul li", slider).not(".cloned").length == 1 ) {
$(".arrow", slider).hide();
}
});

Categories