Страницы

Поиск по вопросам

четверг, 19 декабря 2019 г.

Как можно определить, что элемент кастомный?

#javascript #html #jquery


Коллеги, можно ли определить, что тот или иной элемент кастомный?

К примеру:



/* Так, естественно можно захватить элмемент */

console.log(document.getElementsByTagName('div')[0]);

console.log(document.getElementsByTagName('zinaida')[0]);




А как я могу захватить все кастомные элементы, именно кастомные... В данном случае получить массив из элементов Хочу сразу отметить тот факт, что присвоить им какой либо class или другой какой либо атрибут и определить по class или атрибуту, я и сам соображу... Такой метод, как создать некий массив из всех элементов и сверять с этим массивом, тоже не нужен, тем более, что я уже так делал...


Ответы

Ответ 1



const elems = document.body.getElementsByTagName('*'); const isUnknown = function(value) { return value instanceof HTMLUnknownElement; }; for (let el of elems) { if (isUnknown(el)) { el.classList.add('unknown'); } else { el.classList.add('no-unknown'); } }; .unknown { color: red; } .no-unknown { color: green; } zinaida pavel
div
span

p

А еще есть второй вариант. По требованиям спецификации кастомные элементы надо создавать через дефис. Можно почитать тут Например так: zinaida И тут оказывается, что пример выше не будет работать с касотмным элементом с дефисом. И выйти из ситуации можно так: const elems = document.body.getElementsByTagName('*'); for (let el of elems) { if (!(el.__proto__ instanceof HTMLElement)) { el.classList.add('custom'); } else { el.classList.add('no-custom'); } }; .custom { color: red; } .no-custom { color: green; } zinaida pavel
div
span

p

Этот блок добавлен автором вопроса. Так как при использовании данного примера, выявлен БАГ. Почему-то 'элемент- NAV определяется как custom Коллеги, предлагаю, если кто выявит еще какие проблемы, дополнить ответ const elems = document.body.getElementsByTagName('*'); for (let el of elems) { if (!(el.__proto__ instanceof HTMLElement)) { el.classList.add('custom'); } else { el.classList.add('no-custom'); } }; .custom { color: red; } .no-custom { color: green; } Это Zina
Это div

Это p

Это span

Ответ 2



Посмотрев примеры выше, пришла еще одна идея. Раз кастомные элементы обязательно надо создавать через дефис, почему бы тогда не проверить наличие дефиса в tagName Вариант первый - регулярное выражения: const elems = document.body.getElementsByTagName('*'); for (let i of elems) { let reg = new RegExp(/-/g); console.log(i.localName + ' - ' + (reg.test(i.localName) ? 'da' : 'net')); } zinaida pavel
div
span

p

Вариант два: const elems = document.body.getElementsByTagName('*'); for (let i of elems) { if (i.localName.indexOf('-') !== -1) { console.log(i.localName + ' - da') } else { console.log(i.localName + ' - net') } } zinaida pavel
div
span

p



Ответ 3



Похоже что у кастомных (не зарегистрированных) элементов прототип HTMLUnknownElement - тогда как у стандартных прототипом является его предок HTMLElement, а у зарегистрированных свои прототипы. Соответственно, определить незарегистрированный кастомный элемент можно по этому признаку, выражением element instanceof HTMLUnknownElement Под спойлером ниже, пример кода с простейшим методом Element.isCustom(), и функцией поиска кастомных элементов по селектору - getCustomElements(): HTMLElement.prototype.isCustom = function () { return this instanceof HTMLUnknownElement; }; function getCustomElements(selector, fromElement = null) { let result = [], allEls = (fromElement || document).querySelectorAll(selector); for (let el of allEls) { if (el.isCustom()) result.push(el); } return result; } let cntnr = document.querySelector('#container'); cntnr.addEventListener('click', e => { let els = document.querySelectorAll('.found'); els.forEach(el => el.classList.remove('found')); let selector = e.target.dataset.selector; if (!selector) return; els = getCustomElements(selector); els.forEach(el => el.classList.add('found')); }); #container { height: calc(100vh - 10px); } #container * { display: inline-block; min-width: 40px; line-height: 2em; margin: 4px; padding: 10px; font: 16px sans-serif; color: #000; border: 1px dashed #aaa; } #container > span { background-color: #777; border: none; text-transform: uppercase; color: #fff; cursor: pointer; } #container .found { border: 1px solid #d44; color: #d44; } #container test.found { border: 1px solid #2a2; color: #2a2; }
Найти все кастомные Найти только <test>
div
zinaida test 1 pavel some span test 2

p

Необязательным параметром fromElement задается тот элемент, от которого будет выполняться поиск ("вниз" по DOM). Клик по области результата сбрасывает классы с найденных элементов. В целом, код достаточно простой, думаю что он не требует подробных пояснений :) Источники инфы: https://stackoverflow.com/q/27334365 HTMLUnknownElement (MDN)

Комментариев нет:

Отправить комментарий