Last active
September 19, 2016 09:07
-
-
Save dux/f8d74b7ac431db6db8f375f3654ed09d to your computer and use it in GitHub Desktop.
Vanilla JS PJAX module - turbolinks replacement
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Page.init '#full_page' | |
# Page.skip (el) -> ! /\/admin\//.test(el) | |
# Page.after_load -> | |
# window.initMap() | |
# $('.focus').first().focus(); | |
# clearInterval(window.total_time_interval); | |
# alert 'loaded' | |
# | |
# Page.after_load() | |
@Page = | |
skip_on: [], | |
# reload and refresh are the same things | |
reload: (func) -> @refresh(func) | |
refresh: (func) -> | |
func = undefined if typeof func == 'object' | |
Page.load(location.pathname+location.search, { done:func }) | |
# skip pjax and load page | |
redirect: (href) -> | |
location.href = href | |
false | |
# handle load errors | |
alert: (msg) -> alert msg | |
# milliseconds | |
now: -> Date.now() | |
# extract node from block of data | |
replace_node_data: (data, dom_id) -> | |
dom_id = dom_id.replace('#','') | |
blok = document.createElement('div') | |
blok.innerHTML = data | |
# replace title if found | |
title = blok.querySelector('title') | |
document.title = title.innerHTML if title | |
# replace document part | |
blok = blok.querySelector('#'+dom_id) | |
document.getElementById(dom_id).innerHTML = blok.innerHTML | |
# eval scripts in block | |
arr = blok.getElementsByTagName('script') | |
eval el.innerHTML for el in arr | |
# ajax getpage | |
get:(path, callback) -> | |
xhr = new XMLHttpRequest(); | |
xhr.onreadystatechange = -> | |
if xhr.readyState == XMLHttpRequest.DONE | |
if xhr.status == 200 | |
callback(xhr.responseText) | |
else | |
Page.alert 'something else other than 200 was returned' | |
xhr.open("GET", path, true); | |
xhr.send(); | |
# has to be called with ID of DOM element that will hold ajax data | |
init: (@full_page=false) -> | |
return alert "#full_page ID referece not defined in PJAX!\n\nWrap whole page in one DIV element" unless @full_page | |
@full_page = @full_page.replace('#','') | |
if window.history && window.history.pushState | |
window.history.pushState({ href:location.href, type:'init' }, document.title, location.href) | |
window.onpopstate = (event) -> | |
if event.state && event.state.href | |
Page.load(event.state.href, skip_history:true); | |
else | |
history.go(-2) | |
skip: -> | |
for el in arguments | |
Page.skip_on.push el | |
load: (href, opts={}) -> | |
return false unless href | |
return if href == '#' | |
return @redirect(href) if /^http/.test(href) | |
return @redirect(href) if /#/.test(href) | |
for el in Page.skip_on | |
switch typeof el | |
when 'object' then return @redirect(href) if el.test(href) | |
when 'function' then return @redirect(href) if el(href) | |
else return @redirect(href) if el == href | |
speed = @now() | |
@get href, (data) => | |
console.log "Page.load #{if opts.skip_history then '(back trigger)' else ''} #{@now()-speed}ms: #{href}" | |
@replace_node_data(data, @full_page) | |
@after_load() | |
unless opts.skip_history | |
if location.href.indexOf(href) > -1 | |
window.history.replaceState({ href:href, type:'replaced' }, document.title, href) | |
else | |
window.history.pushState({ href:href, type:'pushed' }, document.title, href) | |
# call done on done if defined done | |
opts.done() if opts.done | |
# scroll to top if Page.load(url, { scroll_to_top: true }) | |
window.scrollTo(0, 0) if opts.scroll_to_top | |
after_load: (func) -> | |
if func | |
@after_load_func = func | |
else | |
@after_load_func() | |
replace_part: (dom_id) -> | |
@load location.href, (ajax_data) -> | |
replace_node_data(ajax_data, dom_id) | |
# this has to be here | |
@Pjax = Page |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment