javascript – Barba.js (analogue of Pjax.js) and working with it

Question:

In general, now I use barba.js to navigate through pages without reloading and creating smooth animations.

I was not too lazy to build an example so that there was a concept of how this business looks and works.

Here's an abbreviated view of the code:

document.addEventListener("DOMContentLoaded", function() {

    Barba.Pjax.init();
    Barba.Prefetch.init();

    var FadeTransition = Barba.BaseTransition.extend({
        start: function() {
            Promise
                .all([this.newContainerLoading, this.fadeOut()])
                .then(this.fadeIn.bind(this));
        },

        fadeOut: function() {
            return $(this.oldContainer).animate({
                opacity: 0
            }).promise();
        },

        fadeIn: function() {
            var _this = this;
            var $el = $(this.newContainer);

            $(this.oldContainer).hide();

            $el.css({
                visibility: 'visible',
                opacity: 0
            });

            $el.animate({
                opacity: 1
            }, 400, function() {
                _this.done();
            });
        },

        newContainer: function() {
            var $newPageHead = $('<head />').html(
                $.parseHTML(
                    newPageRawHTML.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0], document, true
                )
            );
        },

        done: function() {
            var headTags = [
                "meta[name='keywords']",
                "meta[name='description']",
                "meta[property^='og']",
                "meta[name^='twitter']",
                "meta[itemprop]",
                "link[itemprop]",
                "link[rel='prev']",
                "link[rel='next']",
                "link[rel='canonical']"
            ].join(',');
            $('head').find(headTags).remove();
            $newPageHead.find(headTags).appendTo('head');
        }
    });

    Barba.Pjax.getTransition = function() {
        return FadeTransition;
    };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/barba.js/0.0.10/barba.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

<ul class="uMenuRoot">
  <li><a href="/"><span>Home</span></a></li>
  <li><a href="/about.html"><span>About us</span></a></li>
  <li><a href="/contacts.html"><span>Contacts</span></a></li>
</ul>

<main id="barba-wrapper">
  <section class="barba-container middle">
    Page content		 
  </section>
</main>

I shoveled everything I could in search of a solution. So the question! Is it possible to force the content of the <head> to be reloaded? That is, extract the content of this tag and replace the already loaded one.

Let's supplement the question a little by changing the problem. It would be nice to replace not all styles and scripts from <head> , but only some data. For example, the OpenGraph markup required for the Share buttons.

More details about the animation used in the example are described here .

Strictly speaking, we are talking about this part of the code:

newContainer: function() {
var $newPageHead = $('<head />').html(
$.parseHTML(
newPageRawHTML.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0], document, true
)
);
},

done: function() {
var headTags = [
"meta[name='keywords']",
"meta[name='description']",
"meta[property^='og']",
"meta[name^='twitter']",
"meta[itemprop]",
"link[itemprop]",
"link[rel='prev']",
"link[rel='next']",
"link[rel='canonical']"
].join(',');
$('head').find(headTags).remove();
$newPageHead.find(headTags).appendTo('head');
}

With this piece of code, I want to extract certain elements from the <head> , exactly from the page that is being loaded. Then remove the same elements after the end of the animation and replace them with the ones obtained earlier.

After the end of the animation, the selected elements disappear, but new ones are not added. I don’t know what else to change. You can poke the code here .


So. Let's supplement the question a little! I managed to figure out how to reload the meta tags. There are no problems with this and the posting works correctly. We also managed to figure out the animation. In fact, all this is easily connected with animate.css and you can sculpt different animations for different buttons. You can see it here .

The only unresolved issue now is the issue of reloading the scripts. For example, in the same example, a map is embedded on the contact page. Attempts to run initmap.js through the barba.js script have been unsuccessful. If someone finishes this moment – it will be just fine!

Here is the Plunkr code .

Answer:

An answer was received from the author in the English version of SO. To solve this problem, it is better to use Events after animation:

<script type="text/javascript">
        document.addEventListener("DOMContentLoaded", function() {

            Barba.Pjax.init();
            Barba.Prefetch.init();

            var FadeTransition = Barba.BaseTransition.extend({
                    start: function() {
                        Promise
                            .all([this.newContainerLoading, this.fadeOut()])
                            .then(this.fadeIn.bind(this));
                    },

                    fadeOut: function() {
                        return $(this.oldContainer).animate({
                             opacity: 0
                        }).promise();
                    },

                    fadeIn: function() {
                        var _this = this;
                        var $el = $(this.newContainer);

                        $(this.oldContainer).hide();

                        $el.css({
                            visibility: 'visible',
                            opacity: 0
                        });

                        $el.animate({
                            opacity: 1
                        }, 400, function() {
                            _this.done();
                        });
                    }
            });

            Barba.Pjax.getTransition = function() {
                return FadeTransition;
            };

            Barba.Dispatcher.on('newPageReady', function(currentStatus, oldStatus, container, newPageRawHTML) {
          // html head parser borrowed from jquery pjax
          var $newPageHead = $( '<head />' ).html(
              $.parseHTML(
                  newPageRawHTML.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]
                , document
                , true
              )
          );
          var headTags = [
              "meta[name='keywords']"
            , "meta[name='description']"
            , "meta[property^='og']"
            , "meta[name^='twitter']"
            , "meta[itemprop]"
            , "link[itemprop]"
            , "link[rel='prev']"
            , "link[rel='next']"
            , "link[rel='canonical']"
          ].join(',');
          $( 'head' ).find( headTags ).remove(); // Remove current head tags
          $newPageHead.find( headTags ).appendTo( 'head' ); // Append new tags to the head
      });

        });
    </script>

See the result here .

Scroll to Top