Через современные API
function getElementByAttribute(name, value, root = document) {
if (value === undefined) return root.querySelector(`[${CSS.escape(name)}]`);
return root.querySelector(`[${CSS.escape(name)}="${CSS.escape(String(value))}"]`);
}
function getElementsByAttribute(name, value, root = document) {
const sel = value === undefined
? `[${CSS.escape(name)}]`
: `[${CSS.escape(name)}="${CSS.escape(String(value))}"]`;
return [...root.querySelectorAll(sel)];
}
Без querySelector (учебный вариант)
Обход дерева (TreeWalker / рекурсия), проверка el.hasAttribute / getAttribute.
На собеседовании
Упомяните экранирование (CSS.escape), область поиска (root), отличие «есть атрибут» vs «атрибут равен value», data-* через dataset.