Skip to content

Instantly share code, notes, and snippets.

@dux
Last active September 19, 2016 09:07
Show Gist options
  • Save dux/f8d74b7ac431db6db8f375f3654ed09d to your computer and use it in GitHub Desktop.
Save dux/f8d74b7ac431db6db8f375f3654ed09d to your computer and use it in GitHub Desktop.
Vanilla JS PJAX module - turbolinks replacement
# 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