Skip to content

Instantly share code, notes, and snippets.

@dimsemenov
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save dimsemenov/07ae7a4cf059b0e4857d to your computer and use it in GitHub Desktop.

Select an option

Save dimsemenov/07ae7a4cf059b0e4857d to your computer and use it in GitHub Desktop.

Revisions

  1. dimsemenov revised this gist Jun 4, 2015. 1 changed file with 17 additions and 6 deletions.
    23 changes: 17 additions & 6 deletions deeplinking.js
    Original file line number Diff line number Diff line change
    @@ -22,13 +22,24 @@
    var hashChange = self.st.deeplinking.change;
    var getSlideIdByHash = function() {
    var h,
    hash = window.location.hash,
    hashes = {},
    index = 0,
    img;
    hash = window.location.hash,
    hashes = {},
    index = 0,
    img,
    numSlides,
    slideEls;

    for(var i = 0; i < self.slides.length; i++) {
    img = self.slides[i].content.find('.rsImage');
    if(self.slides) {
    numSlides = self.slides.length;
    } else {
    slideEls = self.slider.children();
    numSlides = slideEls.length;
    }


    for(var i = 0; i < numSlides; i++) {

    img = self.slides ? self.slides[i].content.find('.rsImage') : slideEls.eq(i).find('.rsImage');
    if(img) {
    h = img.attr('alt');
    hashes[h] = i;
  2. dimsemenov revised this gist Jun 4, 2015. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion deeplinking.js
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,6 @@

    var hashChange = self.st.deeplinking.change;
    var getSlideIdByHash = function() {
    var self = $('.royalSlider').data('royalSlider');
    var h,
    hash = window.location.hash,
    hashes = {},
  3. dimsemenov created this gist Jun 4, 2015.
    307 changes: 307 additions & 0 deletions deeplinking.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,307 @@
    (function($) {

    "use strict";

    $.extend($.rsProto, {
    _initDeeplinking: function() {
    var self = this,
    isBlocked,
    hashTimeout,
    hashChangeTimeout;

    self._hashDefaults = {
    enabled: false,
    change: false,
    prefix: ''
    };

    self.st.deeplinking = $.extend({}, self._hashDefaults, self.st.deeplinking);

    if(self.st.deeplinking.enabled) {

    var hashChange = self.st.deeplinking.change;
    var getSlideIdByHash = function() {
    var self = $('.royalSlider').data('royalSlider');
    var h,
    hash = window.location.hash,
    hashes = {},
    index = 0,
    img;

    for(var i = 0; i < self.slides.length; i++) {
    img = self.slides[i].content.find('.rsImage');
    if(img) {
    h = img.attr('alt');
    hashes[h] = i;
    }

    }

    if(hash) {
    index = hashes[hash.substring(1)] || index;
    return index;
    }
    return -1;
    };


    var id = getSlideIdByHash();
    if(id !== -1) {
    self.st.startSlideId = id;
    }

    if(hashChange) {
    $(window).on('hashchange'+self.ns, function(e){
    if(!isBlocked) {
    var id = getSlideIdByHash();
    if(id < 0) {
    return;
    }
    if(id > self.numSlides - 1) {
    id = self.numSlides - 1;
    }

    self.goTo( id );
    }
    });



    self.ev.on('rsBeforeAnimStart', function() {
    if(hashTimeout) {
    clearTimeout(hashTimeout);
    }
    if(hashChangeTimeout) {
    clearTimeout(hashChangeTimeout);
    }
    });

    self.ev.on('rsAfterSlideChange', function() {
    if(hashTimeout) {
    clearTimeout(hashTimeout);
    }
    if(hashChangeTimeout) {
    clearTimeout(hashChangeTimeout);
    }

    hashChangeTimeout = setTimeout(function() {
    isBlocked = true;
    var currentSlide = self.currSlide
    window.location.hash = $(currentSlide.content).find('.rsImage').attr('alt');
    hashTimeout = setTimeout(function() {
    isBlocked = false;
    hashTimeout = null;
    }, 60);
    }, 400);

    });
    }
    self.ev.on('rsBeforeDestroy', function() {
    hashChangeTimeout = null;
    hashTimeout = null;
    if(hashChange) {
    $(window).off('hashchange' + self.ns);
    }
    });

    }
    }
    });
    $.rsModules.deeplinking = $.rsProto._initDeeplinking;
    })(jQuery);

    /*!
    * jQuery hashchange event - v1.3 - 7/21/2010
    * http://benalman.com/projects/jquery-hashchange-plugin/
    *
    * Copyright (c) 2010 "Cowboy" Ben Alman
    * Dual licensed under the MIT and GPL licenses.
    * http://benalman.com/about/license/
    */
    (function($,window,undefined){
    '$:nomunge'; // Used by YUI compressor.

    // Reused string.
    var str_hashchange = 'hashchange',

    // Method / object references.
    doc = document,
    fake_onhashchange,
    special = $.event.special,

    // Does the browser support window.onhashchange? Note that IE8 running in
    // IE7 compatibility mode reports true for 'onhashchange' in window, even
    // though the event isn't supported, so also test document.documentMode.
    doc_mode = doc.documentMode,
    supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );

    // Get location.hash (or what you'd expect location.hash to be) sans any
    // leading #. Thanks for making this necessary, Firefox!
    function get_fragment( url ) {
    url = url || location.href;
    return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
    };

    $.fn[ str_hashchange ] = function( fn ) {
    return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
    };

    $.fn[ str_hashchange ].delay = 50;

    special[ str_hashchange ] = $.extend( special[ str_hashchange ], {

    // Called only when the first 'hashchange' event is bound to window.
    setup: function() {
    // If window.onhashchange is supported natively, there's nothing to do..
    if ( supports_onhashchange ) { return false; }

    // Otherwise, we need to create our own. And we don't want to call this
    // until the user binds to the event, just in case they never do, since it
    // will create a polling loop and possibly even a hidden Iframe.
    $( fake_onhashchange.start );
    },

    // Called only when the last 'hashchange' event is unbound from window.
    teardown: function() {
    // If window.onhashchange is supported natively, there's nothing to do..
    if ( supports_onhashchange ) { return false; }

    // Otherwise, we need to stop ours (if possible).
    $( fake_onhashchange.stop );
    }

    });

    // fake_onhashchange does all the work of triggering the window.onhashchange
    // event for browsers that don't natively support it, including creating a
    // polling loop to watch for hash changes and in IE 6/7 creating a hidden
    // Iframe to enable back and forward.
    fake_onhashchange = (function(){
    var self = {},
    timeout_id,

    // Remember the initial hash so it doesn't get triggered immediately.
    last_hash = get_fragment(),

    fn_retval = function(val){ return val; },
    history_set = fn_retval,
    history_get = fn_retval;

    // Start the polling loop.
    self.start = function() {
    timeout_id || poll();
    };

    // Stop the polling loop.
    self.stop = function() {
    timeout_id && clearTimeout( timeout_id );
    timeout_id = undefined;
    };

    // This polling loop checks every $.fn.hashchange.delay milliseconds to see
    // if location.hash has changed, and triggers the 'hashchange' event on
    // window when necessary.
    function poll() {
    var hash = get_fragment(),
    history_hash = history_get( last_hash );

    if ( hash !== last_hash ) {
    history_set( last_hash = hash, history_hash );

    $(window).trigger( str_hashchange );

    } else if ( history_hash !== last_hash ) {
    location.href = location.href.replace( /#.*/, '' ) + history_hash;
    }

    timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
    };

    window.attachEvent && !window.addEventListener && !supports_onhashchange && (function(){
    // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8
    // when running in "IE7 compatibility" mode.

    var iframe,
    iframe_src;

    // When the event is bound and polling starts in IE 6/7, create a hidden
    // Iframe for history handling.
    self.start = function(){
    if ( !iframe ) {
    iframe_src = $.fn[ str_hashchange ].src;
    iframe_src = iframe_src && iframe_src + get_fragment();

    // Create hidden Iframe. Attempt to make Iframe as hidden as possible
    // by using techniques from http://www.paciellogroup.com/blog/?p=604.
    iframe = $('<iframe tabindex="-1" title="empty"/>').hide()

    // When Iframe has completely loaded, initialize the history and
    // start polling.
    .one( 'load', function(){
    iframe_src || history_set( get_fragment() );
    poll();
    })

    // Load Iframe src if specified, otherwise nothing.
    .attr( 'src', iframe_src || 'javascript:0' )

    // Append Iframe after the end of the body to prevent unnecessary
    // initial page scrolling (yes, this works).
    .insertAfter( 'body' )[0].contentWindow;

    // Whenever `document.title` changes, update the Iframe's title to
    // prettify the back/next history menu entries. Since IE sometimes
    // errors with "Unspecified error" the very first time this is set
    // (yes, very useful) wrap this with a try/catch block.
    doc.onpropertychange = function(){
    try {
    if ( event.propertyName === 'title' ) {
    iframe.document.title = doc.title;
    }
    } catch(e) {}
    };

    }
    };

    // Override the "stop" method since an IE6/7 Iframe was created. Even
    // if there are no longer any bound event handlers, the polling loop
    // is still necessary for back/next to work at all!
    self.stop = fn_retval;

    // Get history by looking at the hidden Iframe's location.hash.
    history_get = function() {
    return get_fragment( iframe.location.href );
    };

    // Set a new history item by opening and then closing the Iframe
    // document, *then* setting its location.hash. If document.domain has
    // been set, update that as well.
    history_set = function( hash, history_hash ) {
    var iframe_doc = iframe.document,
    domain = $.fn[ str_hashchange ].domain;

    if ( hash !== history_hash ) {
    // Update Iframe with any initial `document.title` that might be set.
    iframe_doc.title = doc.title;

    // Opening the Iframe's document after it has been closed is what
    // actually adds a history entry.
    iframe_doc.open();

    // Set document.domain for the Iframe document as well, if necessary.
    domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' );

    iframe_doc.close();

    // Update the Iframe's hash, for great justice.
    iframe.location.hash = hash;
    }
    };

    })();

    return self;
    })();

    })(jQuery,this);