Here's a recursive solution:
function closest(el, selector, stopSelector) {
if(!el || !el.parentElement) return null
else if(stopSelector && el.parentElement.matches(stopSelector)) return null
else if(el.parentElement.matches(selector)) return el.parentElement
else return closest(el.parentElement, selector, stopSelector)
}