Skip to content

Instantly share code, notes, and snippets.

@jsdf
Last active August 29, 2015 14:25
Show Gist options
  • Save jsdf/1780e66e19597f001133 to your computer and use it in GitHub Desktop.
Save jsdf/1780e66e19597f001133 to your computer and use it in GitHub Desktop.
hacker news collapsible comments
(function() {
// attach all comment disclosers
$('.comment').forEach(function(comment) {
var commentRoot = closest(comment, '.athing')
CommentDiscloser(commentRoot)
})
function CommentDiscloser(root) {
// initial state
var state = {open: true}
var header = root.querySelector('.comhead')
var body = root.querySelector('.comment')
var childComments = findChildComments(root)
body.style.overflow = 'hidden'
// create toggler ui element
var toggler = document.createElement('a')
toggler.href = '#'
toggler.addEventListener('click', handleToggle)
prepend(header, toggler)
render() // render initial state
function handleToggle(e) {
e.stopPropagation()
e.preventDefault()
setState({open: !state.open})
}
function setState(stateUpdate) {
state = merge(state, stateUpdate)
render()
}
function render() {
toggler.innerHTML = state.open ? '[ – ]' : '[ + ]'
body.style.height = state.open ? 'auto' : '0px'
body.style.overflowY = 'hidden'
childComments.forEach(function(child) {
child.style.display = state.open ? 'block' : 'none'
})
}
}
function findChildComments(root) {
var children = []
var possibleChild = root
var rootIndent = root.querySelector('.ind img').width
while (possibleChild.nextElementSibling) {
possibleChild = possibleChild.nextElementSibling
if (possibleChild.querySelector('.ind img').width > rootIndent) {
children.push(possibleChild)
} else {
break
}
}
return children
}
function $(selector) {
return toArray(document.querySelectorAll(selector))
}
function toArray(arraylike) {
return Array.prototype.slice.call(arraylike)
}
function prepend(parent, el) {
parent.insertBefore(el, parent.firstChild)
return parent
}
function closest(startEl, selector) {
var currentEl = startEl
while (currentEl.parentNode) {
currentEl = currentEl.parentNode
if (currentEl.matches(selector)) return currentEl
}
return null
}
function merge() {
var target = {}
for (var i = 0; i < arguments.length; i++) {
var source = arguments[i]
for (var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key]
}
}
}
return target
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment