О каких элементах идёт речь:
const ancestorSelector = 'селектор_предка';
const descendantSelector = `${ancestorSelector} селектор_потомка`;
Если цеплять обработчик клика непосредственно на потомков - от элемента, на котором висит обработчик, поднимаемся к предку и удаляем его:
document.querySelectorAll(descendantSelector).forEach(function(n) {
n.addEventListener('click', this);
}, e => e.currentTarget.closest(ancestorSelector).replaceWith());
Если применять делегирование - пробуем подняться от целевого элемента к потомку, если таковой нашёлся, поднимаемся к предку и удаляем его:
document.addEventListener('click', e => {
const descendant = e.target.closest(descendantSelector);
if (descendant) {
descendant.closest(ancestorSelector).outerHTML = '';
}
});
// или
document.addEventListener('click', ({ target: t }) =>
(t = t.closest(descendantSelector)) && t.closest(ancestorSelector).remove()
);
UPD.
Наконец-то дождались, теперь сокращённой версии делегированного обработчика можно придать более пристойный вид:
document.addEventListener('click', e => {
e.target.closest(descendantSelector)?.closest(ancestorSelector).remove();
});