Search code examples
javascriptjqueryangularjssticky

Stick a div with Sticky-kit and release it in an specific point in AngularJS


I have a webpage with two columns. I want to stick a div in the left column until the user scrolls down to an specific end of an element in the right column. I´m trying to use the Jquery library Sticky-kit http://leafo.net/sticky-kit/ . I´m able to stick the div, but I cannot release it when I hit the end of the element of the right column. The Jquery code is inside an AngularJS directive (although I think it doesn´t affect to the problem).

Find a plunker: https://plnkr.co/edit/6tT6408OY530b6hYflDL?p=preview

HTML:

<div class="container">
      <div class="column-one">
        <div sticky class="stick">
          <map latitude="39.65" longitude="3.0175" zoom="8" class="map-container" style="height: 300px; margin-bottom: 20px"></map>
        </div>
      </div>
      <div class="column-two">
        <h3>Sticky Navigation Example</h3>
        <p>The navbar will stick to the top when you reach its scroll position.</p>
        <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
        <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
        <h3 id="release-stick">I WANT TO RELEASE THE STICKY COLUMN AT THE END OF THIS ELEMENT</h3>
        <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
        <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
        <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
        <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      </div>
    </div>

JS:

var app = angular.module('app', []);
app.controller('mainCtrl', function($scope){
  $scope.welcome = "Hello, testing sticky!" ;
});

app.directive('sticky', function() {    
    function link(scope, element, attrs) {          

        console.log("Sticky directive has been called!");
        $(document).ready(function() {
            //var elParent = $("#release-sticky");    
            console.log("Sticky tries to get parent!");              
            var options = {/*parent: elParent,*/ bottoming: false};         
            $(".stick").stick_in_parent(options); 
        });                                               
    };

    return {        
        link: link
    };
});

CSS:

.column-one {width: 40%; float:left; margin-right: 20px}
.column-two {width: 50%; float:right; margin-right: 20px}

Solution

  • There are three problems with the code. First of all, considering you are using floats, you need to add an element with clear property at the end of the #release-sticky (or use a css clearfix). So basically something like:

    <div id="release-sticky" class="container">
      ...contents...
      <div style="clear: both"></div>
    </div>
    

    The reason behind this is that when you use floats, and don't clear afterwards, the browser doesnt allocate height for the parent. (so basically your #release-sticky has 0 height).

    Secondly, there appears to be some kind of error when using the bottoming option. Removing it seems to fix the problems :)

    Lastly, there is no need for $(document).ready() since, as AngularJS docs state:

    Angular initializes automatically upon DOMContentLoaded event or when the angular.js script is evaluated if at that time document.readyState is set to 'complete'.

    Also, i changed the element that had sticky class but just for display purposes, it works just as well if you revert the change (it just has no border then).

    Plunk: https://plnkr.co/edit/h3ws1pckAHxk9T0JlnMJ?p=preview