Alternative to Push.js

619 Views Asked by At

I'm building a hybrid app with Phonegap, but I don't want to use Ratchet, is there any alternative to Ratchet's push.js?

I want the user to move between pages without page refresh.

1

There are 1 best solutions below

0
On BEST ANSWER

One option is to find a functional router (Backbone's for example), pull out the content loading/transition code from push.js, and write some custom code to package and inject your UI into the DOM.

push.js has code to manage the browser history cache and to make the ajax requests to support its content requests. If you are using some MV* like Backbone (as I am) you can package and feed your views into a modified version of the push.js success XHR handler. Besides that, the swapContent method, bars & transitionMap associative arrays are all that you need to attach your content to the DOM and transition to a new page.

I like the question you asked because it isn't clear how to fill the gap between minimalist UI frameworks that don't go far beyond prototyping like ratchet and ChocolateChipUI and full angular frameworks Ionic or OnsenUI.

Here are the code elements you need borrowed from push.js

    var transitionMap  = {
      slideIn  : 'slide-out',
      slideOut : 'slide-in',
      fade     : 'fade'
    };

    var bars = {
      bartab             : '.bar-tab',
      barnav             : '.bar-nav',
      barfooter          : '.bar-footer',
      barheadersecondary : '.bar-header-secondary'
    };

    var transition = function (data, options) {
        var key;
        var barElement;

        if (data.title) {
          document.title = data.title;
        }

        if (options.transition) {
            for (key in bars) {
                if (bars.hasOwnProperty(key)) {
                    barElement = document.querySelector(bars[key]);
                    if (data[key]) {
                        swapContent(data[key], barElement);
                    } else if (barElement) {
                        barElement.parentNode.removeChild(barElement);
                    }
                }
            }
        }

        swapContent(data.contents, options.container, options.transition, function () {});

    };

    var swapContent = function (swap, container, transition, complete) {
        var enter;
        var containerDirection;
        var swapDirection;

        if (!transition) {
            if (container) {
              container.innerHTML = swap.innerHTML;
            } else if (swap.classList.contains('content')) {
              document.body.appendChild(swap);
            } else {
              document.body.insertBefore(swap, document.querySelector('.content'));
            }
        } else {
            enter  = /in$/.test(transition);

            if (transition === 'fade') {
              container.classList.add('in');
              container.classList.add('fade');
              swap.classList.add('fade');
            }

            if (/slide/.test(transition)) {
              swap.classList.add('sliding-in', enter ? 'right' : 'left');
              swap.classList.add('sliding');
              container.classList.add('sliding');
            }

            container.parentNode.insertBefore(swap, container);
        }

        if (!transition) {
            complete && complete();
        }

        if (transition === 'fade') {
            container.offsetWidth; // force reflow
            container.classList.remove('in');
            var fadeContainerEnd = function () {
                container.removeEventListener('webkitTransitionEnd', fadeContainerEnd);
                swap.classList.add('in');
                swap.addEventListener('webkitTransitionEnd', fadeSwapEnd);
            };
            var fadeSwapEnd = function () {
                swap.removeEventListener('webkitTransitionEnd', fadeSwapEnd);
                container.parentNode.removeChild(container);
                swap.classList.remove('fade');
                swap.classList.remove('in');
                complete && complete();
            };
            container.addEventListener('webkitTransitionEnd', fadeContainerEnd);
        }

        if (/slide/.test(transition)) {
            var slideEnd = function () {
                swap.removeEventListener('webkitTransitionEnd', slideEnd);
                swap.classList.remove('sliding', 'sliding-in');
                swap.classList.remove(swapDirection);
                container.parentNode.removeChild(container);
                complete && complete();
            };

            container.offsetWidth; // force reflow
            swapDirection      = enter ? 'right' : 'left';
            containerDirection = enter ? 'left' : 'right';
            container.classList.add(containerDirection);
            swap.classList.remove(swapDirection);
            swap.addEventListener('webkitTransitionEnd', slideEnd);
        }
    };

And you can transition to new content

var data = {
  bartab             : menuDOM,
  barnav             : navigationDOM,
  barfooter          : null,
  barheadersecondary : null
  title: "New Page",
  content: pageContentDOM
};


var options = {
        transition: "slide-in",
        container: document.querySelector(".content")
};

transition(data, options);