Your IP : 216.73.216.86


Current Path : /var/www/homesaver/www/bitrix/templates/landing24/assets/js/components/
Upload File :
Current File : /var/www/homesaver/www/bitrix/templates/landing24/assets/js/components/hs.scroll-nav.js

/**
 * HSScrollNav Component.
 *
 * @author Htmlstream
 * @version 1.0
 * @requires jQuery
 *
 */
;(function ($) {
  'use strict';
  $.HSCore.components.HSScrollNav = {

    /**
     * Base configuraion of the component.
     *
     * @private
     */
    _baseConfig: {
      duration: 400,
      easing: 'linear',
      over: $(),
      activeItemClass: 'active',
      afterShow: function(){},
      beforeShow: function(){}
    },

    /**
     * All initialized item on the page.
     *
     * @private
     */
    _pageCollection: $(),


    /**
     * Initialization of the component.
     *
     * @param {jQuery} collection
     * @param {Object} config
     *
     * @public
     * @return {jQuery}
     */
    init: function(collection, config) {

      var self = this;

      if( !collection || !collection.length ) return $();

      collection.each(function(i, el) {

        var $this = $(el),
            itemConfig = config && $.isPlainObject(config) ?
                         $.extend(true, {}, self._baseConfig, config, $this.data()) :
                         $.extend(true, {}, self._baseConfig, $this.data());

        if( !$this.data('HSScrollNav') ) {

          $this.data('HSScrollNav', new HSScrollNav($this, itemConfig));

          self._pageCollection = self._pageCollection.add( $this );

        }

      });

      $(window).on('scroll.HSScrollNav', function(){

        self._pageCollection.each(function(i, el) {

          if($.contains(document, el))
          {
            $(el).data('HSScrollNav').highlight();
          }

        });

      }).trigger('scroll.HSScrollNav');

      return collection;

    }

  }


  /**
   * HSScrollNav.
   *
   * @param {jQuery} element
   * @param {Object} config
   *
   * @constructor
   */
  function HSScrollNav(element, config) {

    /**
     * Current element.
     *
     * @public
     */
    this.element = element;

    /**
     * Configuraion.
     *
     * @public
     */
    this.config = config;

    /**
     * Sections.
     *
     * @public
     */
    this._items = $();

    this._makeItems();
    this._bindEvents();
  }

  /**
   * Return collection of sections.
   *
   * @private
   * @return {jQuery}
   */
  HSScrollNav.prototype._makeItems = function() {

    var self = this;

	  this.element
	  .find('a[href*="#"]').filter(function(key, item) {
		  var hash = item.getAttribute("href").split("#")[1];
		  return !!document.getElementById(hash);
	  })
	  .each(function(i, el) {
      var $this = $(el);
      if( !$this.data('HSScrollNavSection') ) {
        $this.data('HSScrollNavSection', new HSScrollNavSection($this, self.config));
        self._items = self._items.add( $this );
      }
    });
  };

  /**
   * Binds necessary events.
   *
   * @private
   * @return {undefined}
   */
  HSScrollNav.prototype._bindEvents = function() {

    var self = this;

    this.element.on('click.HSScrollNav', 'a[href*="#"]', function(e) {
      var link = this;
      self._lockHightlight = true;
      if(self.current) self.current.unhighlight();
      link.blur();
      self.current = $(link).data('HSScrollNavSection');

		if (self.current)
		{
			self.current.highlight();
			$(this).data('HSScrollNavSection').show(function () {
				self._lockHightlight = false;
			});
			e.preventDefault();
		}
    });

  };

  /**
   * Activates necessary menu item.
   *
   * @public
   */
  HSScrollNav.prototype.highlight = function() {

    var self = this, items, currentItem, current, scrollTop;

    if(!this._items.length || this._lockHightlight) return;

    scrollTop = $(window).scrollTop();

    if(scrollTop + $(window).height() === $(document).height()) {

      this.current = this._items.last().data('HSScrollNavSection');

      this.unhighlight();
      this.current.highlight();
      this.current.changeHash();

      return;
    }

    this._items.each(function(i, el){

      var Section = $(el).data('HSScrollNavSection'),
          $section = Section.section;

      if(scrollTop >= Section.offset) {
        current = Section;
      }

    });

    if(current && this.current != current) {

      this.unhighlight();
      current.highlight();
      if(this.current) current.changeHash();

      this.current = current;

    }

  };

  /**
   * Deactivates all menu items.
   *
   * @public
   */
  HSScrollNav.prototype.unhighlight = function() {

    this._items.each(function(i, el){
      $(el).data('HSScrollNavSection').unhighlight();
    });

  };

  /**
   * HSScrollNavSection.
   *
   * @param {jQuery} element
   *
   * @constructor
   */
  function HSScrollNavSection(element, config) {

    var self = this;

    /**
     * Current section.
     *
     * @public
     */
    this.element = element;

    /**
     * Configuration.
     *
     * @public
     */
    this.config = config;

    /**
     * Getter for acces to the section element.
     *
     * @public
     */
    Object.defineProperty(this, 'section', {
		  value: $("#"+self.element.attr('href').split("#")[1])
    });

    /**
     * Getter for determinate position of the section relative to document.
     *
     * @public
     */

    Object.defineProperty(this, 'offset', {
      get: function() {

        // todo: need relative selector (only current header)
        var header = $('.u-header, header');
        if(header.length > 0)
        {
          var headerHeight = header.outerHeight(),
            headerStyles = getComputedStyle(header.get(0)),
            headerPosition = headerStyles.position,
            offset = self.section.offset().top,
            headerTop = parseInt(headerStyles.top),
            headerMarginTop = parseInt(headerStyles.marginTop);
        }
        else
        {
          var headerHeight = 0,
            headerPosition = 'fixed',
            offset = self.section.offset().top,
            headerTop = 0,
            headerMarginTop = 0;
        }

        if(headerPosition == 'fixed' && headerTop == 0) {
          offset = offset - headerHeight - headerMarginTop;
        }
        if(self.config.over.length) {
          offset = offset - self.config.over.outerHeight();
        }

        return offset;
      }
    });


  }

  /**
   * Moves to the section.
   *
   * @public
   */
  HSScrollNavSection.prototype.show = function(callback) {

    var self = this;

    if( !this.section.length ) return;

    self.config.beforeShow.call(self.section);

    this.changeHash();

    $('html, body').stop().animate({
      scrollTop: self.offset + 3
    }, {
      duration: self.config.duration,
      easing: self.config.easing,
      complete: function() {
        $('html, body').stop().animate({
          scrollTop: self.offset + 3
        }, {
          duration: self.config.duration,
          easing: self.config.easing,
          complete: function() {
            self.config.afterShow.call(self.section);
            if($.isFunction(callback)) callback();
          }
        });
      }
    });

  };

  /**
   * Changes location's hash.
   *
   * @public
   */
  HSScrollNavSection.prototype.changeHash = function() {
    this.section.attr('id', '');
	// window.location.hash = "#"+this.element.attr('href').split("#")[1];
	this.section.attr('id', this.element.attr('href').split("#")[1]);
  };

  /**
   * Activates the menu item.
   *
   * @public
   */
  HSScrollNavSection.prototype.highlight = function() {

    var parent = this.element.parent('li');
    if(parent.length) parent.addClass(this.config.activeItemClass);

  };

  /**
   * Deactivates the menu item.
   *
   * @public
   */
  HSScrollNavSection.prototype.unhighlight = function() {

    var parent = this.element.parent('li');
    if(parent.length) parent.removeClass(this.config.activeItemClass);

  };



})(jQuery);