Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Turbolinks Prefetching Class
function TurbolinksPrefetcher() {
this.hoverTime = 400;
this.fetchers = {};
this.doc = document.implementation.createHTMLDocument('prefetch');
}
TurbolinksPrefetcher.prototype.fetchPage = function (url, success) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('VND.PREFETCH', 'true');
xhr.setRequestHeader('Accept', 'text/html');
xhr.onreadystatechange = function () {
if (xhr.readyState !== XMLHttpRequest.DONE) return;
if (xhr.status !== 200) return;
success(xhr.responseText);
};
xhr.send();
}
TurbolinksPrefetcher.prototype.prefetchTurbolink = function (url) {
var _this = this;
this.fetchPage(url, function (responseText) {
_this.doc.open();
_this.doc.write(responseText);
_this.doc.close();
var snapshot = Turbolinks.Snapshot.fromHTMLElement(_this.doc.documentElement);
Turbolinks.controller.cache.put(url, snapshot);
});
}
TurbolinksPrefetcher.prototype.prefetch = function (url) {
if (this.prefetched(url)) return;
this.prefetchTurbolink(url);
}
TurbolinksPrefetcher.prototype.prefetched = function (url) {
return location.href === url || Turbolinks.controller.cache.has(url);
}
TurbolinksPrefetcher.prototype.prefetching = function (url) {
return !!this.fetchers[url];
}
TurbolinksPrefetcher.prototype.cleanup = function (event) {
var element = event.target;
if(this.fetchers){
clearTimeout(this.fetchers[element.href]);
delete this.fetchers[element.href];
}
element.removeEventListener('mouseleave', this.cleanup);
}
var Prefetcher = new TurbolinksPrefetcher();
document.addEventListener('mouseover', function (event) {
if (!event.target.dataset.prefetch) return;
var url = event.target.href;
if (Prefetcher.prefetched(url)) return;
if (Prefetcher.prefetching(url)) return;
Prefetcher.cleanup(event);
event.target.addEventListener('mouseleave', Prefetcher.cleanup);
Prefetcher.fetchers[url] = setTimeout(function () {
return Prefetcher.prefetch(url);
}, Prefetcher.hoverTime);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.