Home

Awesome

better-ajaxify<br>NPM version NPM downloads Build Status Coverage Status Twitter

A simple PJAX engine for websites

The library helps to solve the performance problem for HTML pages and also improves user experience. There is a term called "Full AJAX website" that defines a web site that instead of regular links or forms uses AJAX requests. After including an extra library on your page and simple adaptation on backend each navigation change triggers a partial reload instead of full refetching and rerendering of the whole page. That experience is always faster and nicer: user doesn't see white flashes, moreover you can show cool animations instead.

LIVE DEMO

Index

<!-- MarkdownTOC levels="2" autolink="true" --> <!-- /MarkdownTOC -->

Installing

Library distributed via NPM:

$ npm install better-ajaxify --save-dev

This will clone the latest version of the better-ajaxify into the node_modules directory at the root of your project.

Then append the following html elements on your page:

<script src="node_modules/better-ajaxify/dist/better-ajaxify.js"></script>

Links

HTML element <code><a></code> allows to navigate to a url. Library modifies this behavior to prevent a white flash. Request to server is made using <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" target="_blank">Fetch API</a>, and response body replaces the current document without a full page reload.

In some cases regular <code><a></code> behavior preserved:

To disable library for a particular <code><a></code> element you could also call method <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault" target="_blank"><code>Event#preventDefault</code></a> in the <code>click</code> event listener:

myLink.addEventListener("click", function(e) {
  // call preventDefault to stop ajaxify from invoking a fetch request
  e.preventDefault();
}, false);

Forms

HTML element <code><form></code> serializes user input data and to sumbits it to new server url specified in the <code>action</code> attribute. Then browser triggers full page reload with the new url. Library modifies this behavior to prevent a white flash. Request to server is made using <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" target="_blank">Fetch API</a>, and response body replaces the current document without a full page reload.

In some cases regular <code><form></code> behavior is not modified:

To disable library for a particular <code><form></code> element you could also call method <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault" target="_blank"><code>Event#preventDefault</code></a> in the <code>submit</code> event listener:

myForm.addEventListener("submit", function(e) {
  // call preventDefault to stop ajaxify from invoking a fetch request
  e.preventDefault();
}, false);

Custom events

The library introduces set of new custom events.

Event nameType of Event#detailDescription
ajaxify:serializeFormDataTrigerred only for forms and contains user input data
ajaxify:fetchRequestTrigerred when a navigation AJAX request starts
ajaxify:loadResponseTrigerred when a navigation AJAX request ends
ajaxify:errorErrorTrigerred when an error happened during a navigation AJAX request
ajaxify:renderDocumentTriggered when the current page is ready to update visual state

ajaxify:fetch

Custom event ajaxify:fetch used to modify AJAX request construction under some obstacles. For instance code below uses sessionStorage as a cache source with responses from server so no network used for repeated requests:

document.addEventListener("ajaxify:fetch", function(e) {
    const req = e.detail;
    // cache only GET responses
    if (req.method !== "GET") return;

    const html = sessionStorage[req.url];
    if (html) {
        e.preventDefault();
        // construct new Response object with cached response content
        const res = new Response(html);
        Object.defineProperty(res, "url", {get: () => req.url});
        
        const event = document.createEvent("CustomEvent");
        event.initCustomEvent("ajaxify:load", true, true, res);
        // fire ajaxify:load to continue flow of changing the current page state
        document.dispatchEvent(event);
    }
}, true);

ajaxify:load

Custom event ajaxify:load used to modify how to process server responses. For instance code below stores a new key-value pair in sessionStorage to cache server responses on client side:

document.addEventListener("ajaxify:load", function(e) {
    const res = e.detail;
    // cache only GET responses
    if (req.method !== "GET") return;
    
    if (res.ok && !res.bodyUsed) {
        res.clone().text().then(html => {
            sessionStorage[res.url] = html;
        });
    }
}, true);