My site is www.to-hawaii.com. The length of the right panel is controlled by the length of the middle panel. In other words the middle panel will adjust to the length of the right panel which is naturally shorter. In some cases though the right panel is longer, see here http://www.to-hawaii.com/bg/ and this creates a strange scroll on the right. Is there a way to fix that? In other words if there is a way to have the script work like this: if the middle panel is longer than the right panel, match the right's panel width so it is as long as the middle panel and if the right panel is longer, match the middle panel's width so it is the same length as the right panel.
The function I am currently using to make the right panel width match the middle panel width is:
$(document).on('ready',function(){
if($(window).width() > 768){
var heightLeft = $(".leftpanel").height();
var heightMiddle = $(".midpanel").height();
if(heightLeft >= heightMiddle){
$(".rightpanel").css("height",heightLeft - 10);
$(".midpanel").css("height",heightLeft - 10);
}else{
$(".rightpanel").css("height",heightMiddle +2);
}
}
$(window).resize(function(){
if($(window).width() >= 768){
$(".rightpanel").css("height", "auto");
$(".midpanel").css("height", "auto");
var heightLeft = $(".leftpanel").height();
var heightMiddle = $(".midpanel").height();
if(heightLeft >= heightMiddle){
$(".rightpanel").css("height",heightLeft - 10);
$(".midpanel").css("height",heightLeft - 10);
}if(heightLeft < heightMiddle){
$(".rightpanel").css("height",heightMiddle +2);
}
}
if($(window).width() < 561){
$(".rightpanel").css("height", "auto");
$(".midpanel").css("height", "auto");
}
})
})
you could try something like this:
$(document).on('ready',function(){
var rightHeight = $('.rightPanel').height();
var leftHeight = $('.leftPanel').height();
var midHeight = $('.midPanel').height();
if (rightHeight > midHeight) {
midHeight = rightHeight;
$('.midPanel').css('height', midHeight);
}
else if (midHeight > rightHeight) {
rightHeight = midHeight;
$('.rightPanel').css('height', rightHeight);
}
// If window is resized
window.addEventListener("resize", adjustPanes);
function adjustPanes(rightHeight, midHeight) {
if (rightHeight > midHeight) {
midHeight = rightHeight;
$('.midPanel').css('height', midHeight);
}
else if (midHeight > rightHeight) {
rightHeight = midHeight;
$('.rightPanel').css('height', rightHeight);
}
}
});
Alternatively, you could set all three panels to the height of the wrapper div that you have created.
This would make them each the same length.
$(document).on('ready',function(){
var wrapperHeight = $('#wrapper').height();
$('.midPanel').height(wrapperHeight);
$('.leftPanel').height(wrapperHeight);
$('.righttPanel').height(wrapperHeight);
});
Related
I was created a code for calculating the height at a time of scrolling.
When the window height is greater than my first div section height,
the second section will show.
When i get back to top from bottom the second section will hide.
Code :
$(window).scroll(function() {
var $height = $(window).scrollTop();
var outerheigth = $(".smart-light-top-bnr").height();
var sliderheigth = $(".smart-light-edu1").height();
var outheigth = parseInt(outerheigth)+parseInt(sliderheigth);
if($height >= outerheigth && $height <= outheigth) {
document.getElementById("smart-light-edu").style.display = "block";
} else {
document.getElementById("smart-light-edu").style.display = "none";
}});
Issue : When i get back to top of window the div is not hide.
Thanks
Ahhh!. Finally i get the solution, after searching and facing some bug..
Here is the code:
$(window).scroll(function() {
var $height = $(window).scrollTop();
var outerheigth = $(".smart-light-top-bnr").height();
var sliderheigth = $(".smart-light-edu1").height();
var outheigth = parseInt(outerheigth)+parseInt(sliderheigth);
if($height >= outerheigth && $height <= outheigth) {
swiper.init();
}
});
Happy coding !!!
I have huge sidebar element and when the page is scrolled sidebar point to the current element that is in a viewport. But sometimes active element is out of sidebar visible space i.e below or above borders. And then the user needs to scroll manually to be able to see active element.
I want to try use logic for determining if the active element is out sidebar visible space and auto scroll if needed.
$(window).on('scroll', function () {
var scrollTop = $(this).scrollTop();
var container = $('#sectionMenu');
var containerHeight = container.height();
$(data).each(function () {
var topDistance = $(this).offset().top - 250;
var id = $(this).attr('id');
var elem = $('#_' + id);
if ((topDistance) < scrollTop && (topDistance + $(this).height() * 0.95) > scrollTop) {
if (autoScrollFlag) {
if (!elem.hasClass('sideBarActive')) {
var scrollPosition = elem.offset().top - container.offset().top;
removeActiveMenuItems(data);
elem.addClass('sideBarActive');
if (containerHeight < scrollPosition) {
// TODO automated scroll
}
}
}
autoScrollFlag = 1;
}
});
});
The solution that has worked for me was like this.
if (containerHeight < scrollPosition) {
container.animate({
scrollTop: '+=100px'
}, 800);
}
I'm trying to get the div to snap to the center of the viewport, right now it just snaps to the top. I was trying to put an offset of 50% but can only get it in px's.
EDIT
I added a new fiddle where I tried to include $(window).scrollTop() / 2)
http://jsfiddle.net/kZY9R/84/
$("#item").offset().top - 100
var body = $("html, body");
var items = $(".item");
var animating = false;
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
if (!animating) {
$.data(this, 'scrollTimer', setTimeout(function() {
items.each(function(key, value) {
if ($(value).offset().top > $(window).scrollTop()) {
animating = true;
$(body).stop().animate( { scrollTop: $(value).offset().top }, 1000,'swing');
setTimeout(function() { animating = false; }, 2000);
return false;
}
});
}, 50));
}
});
I found this:
$('html, body').animate({scrollTop: $('#your-id').offset().top -100 }, 'slow');
Source: Run ScrollTop with offset of element by ID
Here's the trick to keep your viewport centralized on a particular div.
Prerequisites
You need to take into account the following three criteria to be able to centralize the viewport on a given item:
height of the last item that appeared on the viewport.
The distance of the last item from the top of the page, i.e. the offset().top of the item.
The height value of the viewport (i.e the window object).
Calculating Vertical Position of the Item
The required scrollTop value for the window can be calculated as in the following:
var scrollValue = itemOffset // offset of the item from the top of the page
- .5 * windowHeight // half the height of the window
+ .5 * itemHeight; // half the height of the item
You are basically, moving the top of your viewport to the item under view's top offset initially. This, as you've already experienced, snaps the item to the top of the window.
The real magic part comes when you subtract half of the window's height to go halfway along it vertically, and then shifting your view back down by adding half the item's height. This makes the item appear vertically centralized with regards to the viewport.
Note:
To be able to query the last item that appeared on the viewport, you have to iterate over all of the elements that have a top offset value (i.e. offset().top) less than or equal to that of the window's scrollTop value:
$.each($('.item'), function(i, value) {
if ($(viewport).scrollTop() >= $(this).offset().top) {
lastItemInView = $(this);
}
});
With the above, the lastItemInView variable will always end up with the last element visible in the window.
Demo
Not sure if you figured this out yet or not but I took some code from this answer (How to tell if a DOM element is visible in the current viewport?) that shows how to tell if an element is visible in the view port.
Using that I modified your code to loop through each item and find the first visible one in the viewport and then center that one also factoring in the margin-top you have. Let me know if this helps!
Fiddle: http://jsfiddle.net/kZY9R/86/
var body = $("html, body");
var items = $(".item");
var animating = false;
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
if (!animating) {
$.data(this, 'scrollTimer', setTimeout(function() {
items.each(function(key, value) {
if (elementInViewport(value)) {
animating = true;
var margin = parseInt($(value).css('margin-top'));
$('html,body').animate({
scrollTop: $(value).offset().top - ($(window).height() + margin - $(value).outerHeight(true)) / 2
}, 200);
setTimeout(function() {
animating = false;
}, 2000);
return false;
}
});
}, 50));
}
});
function elementInViewport(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while (el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}
i've been looking for this for a couple of days but still no joy!
I would like to have a div scroll in a fixed position until it gets to the top of the footer.
Here is a fiddle of what i have so far: http://jsfiddle.net/danieljoseph/uk4mC/
I'm using this JQuery code but this uses pixels to determine when the div stops. I would like to use the top of the footer as the stop point:
$(document).scroll(function() {
var scrollVal = $(document).scrollTop();
$('#floating-container').css('top',scrollVal+'px');
if (scrollVal < 50) {
$('#floating-container').css('top','50px');
}
if (scrollVal > 2347) {
$('#floating-container').css('top','2347px');
}
});
The issue is that i am using a CMS and the client will be adding text to the page so the second value will change depending on what they add.
I hope i've been clear enough! please let me know if you require more details.
Thanks,
You have to check in the scroll event if the bottom edge of your div is lower than the footer. If it is, place the div at the position of the footer minus the height of the div.
$(function(){
var container = $('#floating-container');
var minTop = $('header').outerHeight();
var maxTop = $('footer').offset().top - container.outerHeight();
$(document).scroll(function() {
var scrollVal = $(document).scrollTop();
container.css('top', scrollVal);
if (scrollVal < minTop) {
container.css('top', minTop);
}
if (container.offset().top > maxTop ) {
container.css('top', maxTop );
}
});
});
Fiddle
And, a much shorter variant of the script above:
$(function(){
var container = $('#floating-container');
var minTop = $('header').outerHeight();
var maxTop = $('footer').offset().top - container.outerHeight();
$(document).scroll(function() {
container.css('top', Math.min( Math.max(minTop, $(document).scrollTop()), maxTop ));
});
});
Short version fiddle.
Just read the position of the footers top when you load the page:
http://jsfiddle.net/uk4mC/1/
var footerTop = $('#text-block').position().top;
and then use that as a trigger:
if (scrollVal < footerTop) { }
I added some special features to the sidebar of my webapplication. You can see a concept of the user interface on my testing site. (It's about the right sidebar)
The sidebar stops scrolling if it is scrolled to its end.
Moreover there are selected listitems in the sidebar wich stay on the top or the bottom of the sidebar if they would scroll out of the view.
My code is written in Javascript using jQuery. Unfortunately scrolling on my page is lagging now. Here are the links to my demo page (rightclick -> show sourcecode) and its javascript file.
How can I speed up the code (and let is still abstract) ?
I paste the javascript code here for those of you who don't want to follow the links.
HTML: (example)
<ul id="right">
<li><h3>Headline</h3></li>
<li><a>Item</a></li>
<li><a>Item</a></li>
<li><a class="selected">Active Item</a></li>
<li><a>Item</a></li>
<li><h3>Headline</h3></li>
<li><a>Item</a></li>
<li><a>Item</a></li>
</ul>
Javascript:
var Scrollers = $('#content,#left,#right');
var Scrollable = new Array(Scrollers.length);
var TopOffset = new Array(Scrollers.length);
var BottomOffset = new Array(Scrollers.length);
var OuterHeight = new Array(Scrollers.length);
var OuterHeightAndOffsets = new Array(Scrollers.length);
function ScrollInit(){
Scrollers.each(function(i){
// constants
TopOffset[i] = parseInt($(this).css("margin-top").replace("px",""));
BottomOffset[i] = parseInt($(this).css("margin-bottom").replace("px",""));
OuterHeight[i] = parseInt($(this).outerHeight());
OuterHeightAndOffsets[i] = TopOffset[i] + BottomOffset[i] + OuterHeight[i];
// classes
$(this).removeClass('snapped top bottom');
if(OuterHeightAndOffsets[i] < $(window).height()){
$(this).addClass('snapped top');
Scrollable[i] = false;
} else {
Scrollable[i] = true;
}
});
}
ScrollInit();
var SelectedListitems = $('li.selected');
var SelectedListitemsActive = new Array(SelectedListitems.length); for(var i=SelectedListitems.length; i<0; i++) SelectedListitemsActive[i] = false;
function ScrollCalc(){
// list item locking
SelectedListitems.each(function(i){
if(!($(this).parent().hasClass('snapped top'))){
var ListItemOffset = $(this).offset().top - $(window).scrollTop();
var ListItemState=0; // 0:in, 1:above, 2:under
if(ListItemOffset <= $(this).parent().offset().top){ ListItemState=1; }
else if(ListItemOffset + $(this).outerHeight() >= $(window).height()){ ListItemState=2; }
// no snapped clone so far
if(ListItemState){
if(SelectedListitemsActive[i]!=true && !$(this).parent().hasClass('snapped')){
var AppendClasses = 'clone snapped '; if(ListItemState == 1) AppendClasses += 'top '; else AppendClasses += 'bottom ';
$(this).parent().append($(this).clone().addClass(AppendClasses + i));
SelectedListitemsActive[i] = true;
}
// already snapped, clone existing
} else {
if(SelectedListitemsActive[i]==true){
$('.clone.snapped.' + i).remove();
SelectedListitemsActive[i] = false;
}
}
}
});
// scroll container locking
Scrollers.each(function(i){
if(Scrollable[i]){
if($(window).scrollTop()+$(window).height() > OuterHeightAndOffsets[i]){
$(this).addClass('snapped bottom');
} else {
$(this).removeClass('snapped bottom');
}
}
});
ScrollEvent = false;
}
ScrollCalc();
$(window).scroll(function(){
ScrollCalc();
});
I've just have a look at you link and believe that the lagging is not because of your javascript. If you don't think so try to disable all scripts in window.scroll event, still lagging right?
Now try to remove all shadow properties - box-shadow and text-shadow. Also remember to disable changing shadow opacity in simple.js (changing shadow during scroll event always laggy).
Now you can see it run very fast!!! Back to css file and enable each shadow properties and find out what is most suitable for you.
There is a much faster, easier way to get the effect you want.
Try this: when the window scrolls down far enough, set your sidebar's css position property to fixed. When it scrolls up, set the position of the sidebar back to relative.
var sidebar = document.getElementById('side'),
section;
sidebar.style.position = 'relative';
sidebar.style.bottom = '0px';
sidebar.style.right = '0px';
window.onscroll = function(){
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
maxTop = section ? section.offsetTop : sidebar.offsetHeight - window.innerHeight;
sidebar.style.top = sidebar.style.bottom = null;
if (scrollTop > maxTop) {
if (section) {
sidebar.style.top = - section.offsetTop + 'px';
} else {
sidebar.style.bottom = '0px';
}
sidebar.style.position = 'fixed';
} else {
sidebar.style.position = 'relative';
}
}
You can see it working here - http://jsfiddle.net/cL4Dy/