• 0

Javascript Layout Issue


Question

Hi

 

I'm building a layout, and ignoring all the stuff about sizing for mobile and so on - I want to achieve something fairly specific.  When scrolling on large screens, the black "A title goes here" scrolls upwards until it sits under the menu and stops - that is working.

 

The sidebar similarly scrolls up until it sits under the menu and then stops.  But the footer could impact it, so when the footer reaches the bottom of the sidebar, it "pushes" it up, so the sidebar scrolls with the page again.

 

This is all working just fine, but awkwardly on line 283, I am having to add a specific offset value.  I know that if I change the height of any of the elements above the sidebar, the offset value needs to change.  But I can't work out how to derive what it should be, so that any sizing of Hero image will work, for example.

 

Sorry for the messy code, I will be tidying that up once this works.  Would anyone take a look?  Also, yeah I'd never put all my CSS and JS in with my HTML normally, it's just for ease of postings sake.

 

Hope @mrbestersees this - he's usually great with these thing...

 

Thanks

 

<!DOCTYPE html>
<html lang="en-GB" dir="ltr">
<head>
<title></title>
<!-- Encolding //-->
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no">
<link rel="profile" href="http://gmpg.org/xfn/11">
<!-- Scripts //-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.0/js/foundation.min.js"></script>

<!-- Styles //-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.0/css/foundation.min.css">
<style>
BODY {}

BODY #pageHolder {
  padding-top: 0rem;
}

BODY.large #pageHolder,
BODY.medium #pageHolder {
  margin-top: 56px;
}

BODY.small #pageHolder {
  margin-top: 41px;
}

BODY.small SIDEBAR,
BODY.medium SIDEBAR {
  padding-top: 1rem;
}

BODY.large SIDEBAR{
  position: relative;
  top: 0;
}
.heroImage{
	background-image: URL("https://theluxurytravelexpert.files.wordpress.com/2014/01/scenery.jpg");
	background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
}
BODY.large .heroImage{
	height: 400px;
}
BODY.medium .heroImage{
	height: 300px;
}
BODY.small .heroImage{
	height: 200px;
}
H1{
	background: black;
	color: white;
	position: relative;
	top: 0;
	margin: 0px;
	z-index: 10;
}
.top-bar NAV UL LI.menu-text H2 {
  font-size: 1em;
  padding: 0rem;
  margin: 0rem;
  line-height: 1;
  font-weight: bold;
}

.title-bar .title-bar-left h2 {
  font-size: 1em;
  padding: 0rem;
  margin: 0rem;
  line-height: 1;
  font-weight: bold;
}

H1,H2,H3,H4,H5,H6 {
  font-weight: bold;
}

a:focus {
  outline: none;
}

SIDEBAR {
  background: #00ff00;
  font-size: 0.9em;
}

FOOTER {
  background: #e6e6e6;
  font-size: 0.9em;
  /*padding-top: 1rem;*/
}

FOOTER UL LI A {
  padding: 0.3rem 0rem;
}

FOOTER SECTION P {
  padding: 0rem;
}





.top-bar NAV UL LI A {
  /*color: #DDDDDD;*/
}

.top-bar NAV UL LI.is-active {
  /*color: #FFFF;*/
  /*background: #AA0000;*/
}

.top-bar NAV UL LI A:hover {
  /*color: #FFFF;*/
  /*background: #FF0000;*/
}

.top-bar NAV UL LI UL.first-sub {
  /*top: 126%;
  left: 17px;*/
}

.top-bar .top-bar-right ul {
  /*background: #000000;*/
}

.top-bar .top-bar-right ul LI button {
  /*background-color: #FF0000;*/
}

.top-bar .top-bar-right ul LI button:hover {
  /*background-color: #CC0000;*/
}

.dropdown.menu>li.is-dropdown-submenu-parent>a:after {
  /*border-color: #FFFFFF transparent transparent;*/
}

.is-dropdown-submenu .is-dropdown-submenu-parent.opens-right>a:after {
  /*border-color: transparent transparent transparent #FFFFFF;*/
}

#offCanvasLeft {
  /*background: #000000;*/
}

#offCanvasLeft UL#sideMenu {
  /*background: #000000;*/
}

#offCanvasLeft UL#sideMenu LI A {
  /*color: #FFFFFF;*/
}

#offCanvasLeft UL#sideMenu .is-active A {
  /*background: #660000;*/
}

#offCanvasLeft UL#sideMenu A:hover {
  /*background: #FF0000;*/
}

.is-accordion-submenu-parent>a:after {
  /*border-color: #FFFFFF transparent transparent;*/
}

MAIN{
	background: red;
}
</style>
<script>
$(document).ready(function() {
	var sidebarPosTopOrig, titlePosTopOrig;
	
	$(document).foundation();
	
	setupBodySize();
	prepMenus();
	holdStickyElements();

	$(window).resize(function() {
		setupBodySize();
	});
	
	$(window).scroll(function () {
		holdStickyElements();
	});

	function setupBodySize() {
		// Assign BODY classes based upon size
		if ($('#showhideSmall').is(":visible")) {
			$('BODY').addClass("small");
			$('BODY').removeClass("medium");
			$('BODY').removeClass("large");
		}
		if ($('#showhideMedium').is(":visible")) {
			$('BODY').removeClass("small");
			$('BODY').addClass("medium");
			$('BODY').removeClass("large");
		}
		if ($('#showhideLarge').is(":visible")) {
			$('BODY').removeClass("small");
			$('BODY').removeClass("medium");
			$('BODY').addClass("large");
		}
		
		sidebarPosTopOrig =  $('SIDEBAR').position().top;
		titlePosTopOrig =  $('.pageTitle').position().top;
		
		// Set the top of the side menu to compensate for the header
		$('#offCanvasLeft').css('margin-top', $('#mobileHeader').height());
	}
	
	function prepMenus(){
		// Load the top menu into the side menu
		$('#sideMenu').html($('#topMenu').html());

		// Style the side menu sub menus to be vertical
		$('#sideMenu').find("UL").addClass("vertical");

		// Remove the title from the side menu
		$('#sideMenu').find('.menu-text').remove();

		//Turn the side menu into an accordian
		var sideMenu = new Foundation.AccordionMenu($('#sideMenu'), null);

		// Style the top menu to be a drop down
		$('#topMenu').addClass("dropdown");

		//Turn the top menu into a drop down
		var topMenu = new Foundation.DropdownMenu($('#topMenu'), null);
		
		
	}
	
	function holdStickyElements(){
	
		console.log($('.fixedSidebar').height() - $('.fixedSidebar').position().top);
	
		// How far have we scrolled - compensating for the fixed header
		scrollAmount = $(window).scrollTop() + $('HEADER').height();
			
		// Keep the title on screen
		if($('BODY').hasClass("large")){
			// If the page is on a large screen
			
			// Threshold 0 - scroll past here and keep title visible = position of title relative to page originally
			scrollThreshold0 = titlePosTopOrig;
			
			if(scrollAmount <= scrollThreshold0){
				// If the scroll (compensating for the fixed header) hasn't yet reached a distance greater than Threshold 0
				// Meaning - have we scrolled to a point that where the title hasn't yet reached the top of the usable screen
				
				// Keep the title scrolling with the page with a zero difference between itself and its parent.
				holdPoint = 0;
				$('.pageTitle').css('top',holdPoint);
			}
			if(scrollAmount > scrollThreshold0){
				// If the scroll (compensating for the fixed header) has now reached a distance greater than Threshold 0
				// Meaning - have we scrolled to a point that where the title has reached the top of the usable screen
				
				// Fix the title to the top of the usable screen by adjusting the relative difference of the title to it's parent as ((distance scrolled minus original position) and then compensate for fixed header)
				holdPoint = scrollAmount - titlePosTopOrig;
				$('.pageTitle').css('top',holdPoint);
			}
		}

		// Keep the sidebar on screen
		if($('BODY').hasClass("large") && $(window).height() > ($('.fixedSidebar').height() + $('HEADER').height() + $('.pageTitle').height())){
			// If the page is on a large screen and taller than the sidebar + header + title
			
			// Threshold 1 = scroll past here and keep sidebar visible = (position of sidebar originally - height of the title)
			scrollThreshold1 = sidebarPosTopOrig - $('.pageTitle').height();
			
			// Threshold 2 = point where the bottom of main and bottom of sidebar align
			scrollThreshold2 = $('.fixedSidebar').height() - $('.pageTitle').height() + 145;	
			
			
			
			if(scrollAmount < scrollThreshold1){
				// If the scroll (compensating for the fixed header) hasn't yet reached a distance greater than Threshold 1
				// Meaning - have we scrolled to a point that where the sidebar hasn't yet reached the top of the usable screen
				
				// Keep the top of the sidebar scrolling with the page with a zero difference between itself and its parent.
				holdPoint = 0;
				$('.fixedSidebar').css('top',holdPoint);
				return;
			}
			
			
			
			if(scrollAmount >= scrollThreshold1 && scrollAmount < scrollThreshold2){
					// If the scroll (compensating for the fixed header) has reached a distance greater than Threshold 1 but not Threshold 2
					// Meaning - have we scrolled to a point that where the sidebar hasnt reached the top of the usable screen but not impacted by the footer
				
					// Fix the top of the sidebar to the top of the usable screen by adjusting the relative difference of the sidebar to it's parent as ((distance scrolled minus original position) and then compensate for fixed header and fixed title)
					holdPoint = scrollAmount - sidebarPosTopOrig + $('.pageTitle').height();
					$('.fixedSidebar').css('top',holdPoint);
					return;
			}
			
			if(scrollAmount >= scrollThreshold2){
				// If the scroll (compensating for the fixed header) has reached a distance greater than Threshold 1 and Threshold 2
				// Meaning - have we scrolled to a point that where the sidebar hasn reached the top of the usable screen but not impacted by the footer
				
				// Fix the bottom of the sidebar to the top of the footer by adjusting the relative difference of the sidebar to it's parent as (distance from the unscrolled top of the sidebar to the top of the footer minus the height of the sidebar)
				holdPoint = $('FOOTER').position().top - sidebarPosTopOrig - $('.fixedSidebar').height();
				$('.fixedSidebar').css('top',holdPoint);
				return;
			}
		}
		return;
	}









});
</script>


</head>
<body>
  <div class="off-canvas-wrapper">

    <section id="pageHolder" class="off-canvas-content row" data-off-canvas-content>
		
		<div class="heroImage"></div>
		<h1 class="pageTitle">A Title Goes Here...</h1>
		<main class="small-12 large-9 columns">
		
        <!-- CONTENT HERE //-->
		


        <article>
          <h3>Title</h3>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
        </article>
		
		 <article>
          <h3>Title</h3>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
          <p>Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body
            Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body Body</p>
        </article>





        <!-- CONTENT HERE //-->
      </main>
      <sidebar id="sidebar" class="small-12 large-3 columns fixedSidebar">

        <aside>
          <h4>Title1</h4>
          <p>Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar</p>
        </aside>

        <aside>
          <h4>Title2</h4>
          <p>Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar</p>
        </aside>
		
		<aside>
          <h4>Title3</h4>
          <p>Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar</p>
        </aside>

        <aside>
          <h4>Title4</h4>
          <p>Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar</p>
        </aside>

        <aside>
          <h4>Title5</h4>
          <p>Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar Sidebar</p>
        </aside>

      </sidebar>
    </section>
    <footer class="row small-up-1 medium-up-3">
      <section class="column column-block">
        <h6>Title</h6>
        <p>A small paragraph of text could go here, such as a privacy statement or contact details. Potentially use this area for social links also!</p>
      </section>
      <section class="column column-block">
        <h6>Title</h6>
        <ul class="menu vertical">
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
        </ul>
      </section>
      <section class="column column-block">
        <h6>Title</h6>
        <ul class="menu vertical">
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
          <li><a href="#">Item</a></li>
        </ul>
      </section>
    </footer>




    <!-- SMALL MENU HERE //-->
    <nav class="off-canvas position-left" id="offCanvasLeft" data-off-canvas class="show-for-small-only">
      <ul id="sideMenu" class="vertical menu"></ul>
    </nav>
    <!-- SMALL MENU HERE //-->



  </div>




  <header style="position: fixed; width: 100%; top: 0px;">

    <!-- SMALL HEADER HERE //-->
    <div id="mobileHeader" class="nav-wrapper show-for-small-only" style="background: #000000; width: 100%;">
      <div class="title-bar">
        <div class="title-bar-left">
          <button class="menu-icon" type="button" data-toggle="offCanvasLeft"></button>
          <span class="title-bar-title">Foundation</span>

        </div>
      </div>
    </div>
    <!-- SMALL HEADER HERE //-->



    <!-- BIG HEADER HERE //-->
    <div id="desktopHeader" class="top-bar show-for-medium">
      <div class="row">
        <nav class="top-bar-left">
          <ul id="topMenu" class="menu">
            <li class="menu-text">Site Title</li>
            <li><a href="#">One</a>
              <ul class="menu">
                <li><a href="#">One - One</a></li>
                <li><a href="#">One - Two</a></li>
                <li><a href="#">One - Three</a></li>
              </ul>
            </li>
            <li><a href="#">Two</a></li>
            <li><a href="#">Three</a>
              <ul class="menu">
                <li><a href="#">Three - One</a></li>
                <li><a href="#">Three - Two</a>
                  <ul class="menu">
                    <li><a href="#">Three - Two - One</a></li>
                    <li><a href="#">Three - Two - Two</a></li>
                    <li><a href="#">Three - Two - Three</a></li>
                  </ul>
                  <li><a href="#">Three - Three</a></li>
              </ul>
              </li>
          </ul>
        </nav>
        <div class="top-bar-right">
          <ul class="menu">
            <li>
              <input type="search" placeholder="Search">
            </li>
            <li>
              <button type="button" class="button">Search</button>
            </li>
          </ul>
        </div>
      </div>
    </div>
    <!-- BIG HEADER HERE //-->


  </header>
  <div id="showhideSmall" class="show-for-small"></div>
  <div id="showhideMedium" class="show-for-medium"></div>
  <div id="showhideLarge" class="show-for-large"></div>
</body>
</html>

 

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

  • 0

Use position: sticky with a polyfill for old browsers, you shouldn't need these type of JavaScript driven things for modern browsers (Especially because it actually slows them down)

  • Like 1
Link to comment
Share on other sites

  • 0
8 hours ago, Seahorsepip said:

You might consider using jsfiddle or codepen, it's easier to look into the code for others.

https://jsfiddle.net/3k8s7knk/

Cheers, I did consider it but my only issue is that jsFiddle takes up too much screen estate as to not sufficiently demonstrate the issue.

7 hours ago, The_Decryptor said:

Use position: sticky with a polyfill for old browsers, you shouldn't need these type of JavaScript driven things for modern browsers (Especially because it actually slows them down)

Not sure sticky will work here but can try...

Link to comment
Share on other sites

This topic is now closed to further replies.