Created
January 19, 2014 02:44
-
-
Save zacs/8499789 to your computer and use it in GitHub Desktop.
Code for adding Grantland-style footnotes to Jekyll.
This file contains 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
var Utils = { | |
cache: {}, | |
watchResize: function(callback) { | |
//throttled resize | |
var resizing; | |
callback.size = 0; | |
function done() | |
{ | |
var curr_size = window.innerWidth; | |
clearTimeout(resizing); | |
resizing = null; | |
// only run on a true resize | |
if (callback.size != curr_size) | |
{ | |
callback(); | |
callback.size = curr_size; | |
} | |
} | |
window.addEventListener('resize', function() { | |
if (resizing) | |
{ | |
clearTimeout(resizing); | |
resizing = null; | |
} | |
resizing = setTimeout(done, 50); | |
}); | |
}, | |
MQ: function() { | |
//get current breakpoint/layout | |
return window.getComputedStyle(document.body, ':after').getPropertyValue('content').replace(/"/g, ''); | |
} | |
}; | |
var footnotes = { | |
config: { | |
footnoteClass: 'footnote', | |
activeClass: 'active-footnote', | |
contentWidth: 600, | |
offset: 20, | |
notePositions: [] | |
}, | |
getTarget: function(x) { | |
x = x || window.event; | |
return x.target || x.srcElement; | |
}, | |
deactivate: function() { | |
//turn off any active footnotes just in case | |
var actives = document.querySelectorAll('.' + footnotes.config.activeClass); | |
for (var i = actives.length - 1; i >= 0; i--) { | |
actives[i].classList.remove(footnotes.config.activeClass); | |
} | |
}, | |
hideNote: function(e) { | |
var target = footnotes.getTarget(e); | |
if (target.classList.contains(footnotes.config.footnoteClass)) { | |
footnotes.deactivate(); | |
} | |
}, | |
setPosition: function(target) { | |
var length = target.length; | |
for (var i = 0; i < length; i++) { | |
var note = footnotes.getNote($(target[i])); | |
if ($('.footnotes').css('position') == 'absolute') { | |
var body = $(this.ie6 ? document.body : document); | |
notePosX = Math.round((body.width() - footnotes.config.contentWidth) / 2) + footnotes.config.contentWidth + footnotes.config.offset; | |
notePosY = $(target[i]).position().top; | |
var fnLength = footnotes.config.notePositions.length; | |
for (var j = 0; j < fnLength; j++) { | |
if (notePosY <= footnotes.config.notePositions[j].bottom) { | |
notePosY = footnotes.config.notePositions[j].bottom + 20; | |
} | |
} | |
//make a note of both the offset and the height | |
footnotes.config.notePositions.push({top: notePosY, bottom: $(note)[0].offset + notePosY}); | |
} else { | |
notePosX = $(target[i]).position().left; | |
//make sure it doesn't hang over the side | |
if (notePosX - (note.offsetWidth / 2) > 0) { | |
notePosX = notePosX - (note.offsetWidth / 2); | |
} else { | |
notePosX = 0; | |
} | |
//apply a little space so it sits below the link | |
notePosY = $(target[i]).position().top + footnotes.config.offset; | |
note.classList.add(footnotes.config.activeClass); | |
} | |
note.style.cssText = 'left:' + notePosX + 'px;top:' + notePosY + 'px;'; | |
} | |
}, | |
getNote: function(target) { | |
var noteLoc = target[0].hash.substr(1); | |
var note = document.getElementById(noteLoc); | |
return note; | |
}, | |
toggleNote: function(e) { | |
var target = footnotes.getTarget(e); | |
var MQ = Utils.MQ(); | |
if (target.classList.contains(footnotes.config.footnoteClass)) { | |
e.preventDefault(); | |
var note = footnotes.getNote($(target)); | |
if (note) { | |
if (note.classList.contains(footnotes.config.activeClass)) { | |
footnotes.deactivate(); | |
} else { | |
footnotes.deactivate(); | |
if (getComputedStyle($('.footnotes')[0]).position != 'absolute') { | |
footnotes.setPosition($(target)); | |
} | |
} | |
} | |
return false; | |
} else { | |
footnotes.deactivate(); | |
} | |
}, | |
init: function(container) { | |
if (container) { | |
// set on state | |
container.addEventListener('mouseover', footnotes.toggleNote); | |
container.addEventListener('touchend', footnotes.toggleNote); | |
//set off state | |
container.addEventListener('mouseout', footnotes.hideNote); | |
if ($('.footnotes').css('position') == 'absolute') { | |
//if large, we need to set the position right away | |
footnotes.setPosition($('.' + footnotes.config.footnoteClass)); | |
} | |
$('.footnotes').css({"visibility": "visible"}); | |
} | |
} | |
}; | |
This file contains 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
// This should be called when the document is ready... | |
$( ".reversefootnote" ).remove(); | |
if ($('.' + footnotes.config.footnoteClass).length > 0) { | |
$(window).bind('load', function() { | |
setTimeout(function() { | |
footnotes.init($('body')[0]); | |
}, 200); | |
}); | |
Utils.watchResize(function() { | |
footnotes.config.notePositions = []; | |
footnotes.init($('body')[0]); | |
}); | |
} |
This file contains 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
.footnotes { | |
visibility: hidden; | |
position: absolute; | |
left: 0; | |
top: 0; | |
width: 200px; | |
} | |
.footnotes ol li { | |
position: absolute; | |
top: 0px; | |
width: 160px; | |
margin-top: -10px; | |
} | |
.footnotes ol li p { | |
width: 160px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment