No-framework JavaScript

Matchstick structure

Recently I’ve been stripping out jQuery and Vue from a page I’d been working on. Frameworks can be really useful, but when not utilised fully it’s worth asking whether importing an entire library or framework is necessary. In this post, I’ll share some basic ideas using native vanilla JavaScript.

var getJsonpResponse = function(url, params, callback, appender = document.querySelector('head')) {

// Create <script> object
var script = document.createElement('script');

// build the url with params
script.src = (function(url, params = {}) {

// e.g. params.callback=jsonpcallback_hjhz7
if (typeof params.callback === "undefined") params.callback = "jsonpcallback_" + Math.random().toString(36).substring(7);

// generate param string e.g. n1=v1&n2=v2
var paramString = Object.keys(params).map((key) => {
return key + '=' + encodeURIComponent(params[key]);
}).join('&');

// affix urlParams string on the end of url
if (paramString) {
if (url.indexOf("?") > 0) { // contains ?
let reversed = url.split("").reverse().join("");
if (url.indexOf("?") === 0 || url.indexOf("&") === 0) {
url += paramString;
} else {
url += "&" + paramString;
}
} else {
url += "?" + paramString;
}
}

return url;

})(url, params);

// handler callback
window[params.callback] = function(data) {

// developer defined callback
callback(data);

// tidy up!
// allow the function to be garbage collected, tidy up window, and
// remove the script from the dom
window[params.callback] = null && delete window[params.callback];
script.parentNode.removeChild(script);
};

// append the script to run it
appender.appendChild(script);

};

Making JSONP requests

I find JSONP really useful when querying APIs to get around CORS issues. CORS provides important protection against Cross-Site Request Forgery attacks and depending on how sensitive your data is, you might not want to permit cross domain access to API resources. However, there are times when fetching non-sensitive data that it can be a pain.

Below is a function I wrote to handle JSONP API requests:

var getJsonpResponse = function(url, params, callback, appender = document.querySelector('head')) {

// Create <script> object
var script = document.createElement('script');

// build the url with params
script.src = (function(url, params = {}) {

// e.g. params.callback=jsonpcallback_hjhz7
if (typeof params.callback === "undefined") params.callback = "jsonpcallback_" + Math.random().toString(36).substring(7);

// generate param string e.g. n1=v1&n2=v2
var paramString = Object.keys(params).map((key) => {
return key + '=' + encodeURIComponent(params[key]);
}).join('&');

// affix urlParams string on the end of url
if (paramString) {
if (url.indexOf("?") > 0) { // contains ?
let reversed = url.split("").reverse().join("");
if (url.indexOf("?") === 0 || url.indexOf("&") === 0) {
url += paramString;
} else {
url += "&" + paramString;
}
} else {
url += "?" + paramString;
}
}

return url;

})(url, params);

// handler callback
window[params.callback] = function(data) {

// developer defined callback
callback(data);

// tidy up!
// allow the function to be garbage collected, tidy up window, and
// remove the script from the dom
window[params.callback] = null && delete window[params.callback];
script.parentNode.removeChild(script);
};

// append the script to run it
appender.appendChild(script);

};

State management and updating the DOM on change

Frameworks such as React and Vue will maintain state of an app and, when state updates, makes updates to the DOM and such. Essentially this is an observer pattern where “observers” are notified when the subject or state is altered.

class StateManager {

    constructor() {

        this.stateChangeHandlers = [];

        // when we update state, we notify observers (e.g. templates)
        this.state = {};

    }

    /**
     * This is to update state and automatically call the state change handler
     * @param values {object}
     */
    setState(values = {}) {

        // update state
        this.state = Object.assign(this.state, values);

        // notify handlers
        this.stateChangeHandlers.forEach(handler => {
            handler(this.state);
        });

    }

    /**
     * Register a handler for when state changes
     * @param mixed {args,...} (key, handler) or (handler)
     */
    onStateChange(handler) {

        this.stateChangeHandlers.push(handler);

    }
}


var state = new StateManager();

// here is where we set handler to fire when state changes 
state.onStateChange(function(state) {
    document.getElementById('app').innerHTML = "State changed: " + JSON.stringify(state);
});

state.setState({
    name: "Martyn"
});

Letting go of jQuery

jQuery was a blessing when it arrived especially when browser incompatibility was rife (IE6, ugh!). Standards have come along way and there are so many native methods to do things such as DOM selection, looping, etc than before. By all means, continue to use jQuery if you want as there is tons of useful functionality there. For me though, I’d rather not use it unless it’s really neccessary and ave manage to remove it from a few sites and not be so dependent on it.

I won’t repeat what’s already out there, but I’ll leave this link which I found useful when dropping jQuery from a site:

http://youmightnotneedjquery.com/

Location based personalisation and APIs

Location based personalisation is when a page is personalised for a user depending on their location. For example, a user from China could be shown a notification to visit a company’s Chinese micro-site, or users from India visiting a university website could be shown a block of content informing them about popular courses Indian students apply for. When used in this way, the marketing power of your website can be greatly enhanced. Continue reading →

A Foundation 6 / SASS work-flow

Vector graphic of Foundation yeti in a space rocket

Foundation is one of the most advanced front-end frameworks for building responsive websites. It is designed to work on all types of devices. It uses SASS which is a CSS pre-processor helping to reduce repetition with CSS and save time. In this short tutorial, I’ll discuss my current workflow using these two technologies. Continue reading →

Zend Framework 1 and PHPUnit: Controller tests

Zend Framework logo on green background

This is a example of PHPUnit testing for Zend Framework 1. I haven’t used this framework for a while but do recall the struggle to achieve automated testing on routes. So, if anyone reading this is still stuck on this old framework I hope this might be of some help 🙂 Continue reading →

A Bootstrap 3 / LESS work-flow

Bootstrap stack logo

Currently working on a project and on this occasion worked from the beginning by overwriting Bootstrap’s variables (as opposed to simply just overwriting its styles). My workflow, which will no doubt change as I discover new and better ways, for now it’s working out well. Continue reading →

Deploying with Git

Git logo

I’ve been spending the day putting together a more automated method of deploying my websites – deploying with Git after I push to the remote repository on the server. Not only is this incredible easy to deploy changes once setup, it ensures that my live site is tied in nicely with my version control. Anyway it took a little time to tinker with so I thought I’d share my method I’m using. This approach uses a script to build an bare repository on the server, and hooks to pull changes to the live site. As every production environment is different I suggest this as a guide and make appropriate changes to suite your environment. Continue reading →

Two extremely light JavaScript libraries – ajax and pages

I wanted to apply to my website page caching. This is where a static page is cached in the browser to reduce unnecessary HTTP requests. By caching the page on the first load, the next time the user requests that page it is loaded instantly. This not only puts less demand on the network and server, but allows pages to load in an instant which is rather nice for the user. Here I introduce two new libraries to my growing collection: ajax and pages. Continue reading →

Less HTTP requests and optimising assets (CSS, JavaScript, images) to enhance performance

Recently I made some enhancements to my website to boost performance. This current website was my first time to create a custom WordPress theme and template so I’d carefully followed the documentation in order to do that. However, once I had a running website on top of WordPress I wanted to spend some time improving loading times. This post I’ll briefly write about some of the changes I was able to make and notice results. Continue reading →