#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 divspanp
А еще есть второй вариант. По требованиям спецификации кастомные элементы надо создавать через дефис. Можно почитать тут Например так: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 divspanp
Этот блок добавлен автором вопроса. Так как при использовании данного примера, выявлен БАГ. Почему-то 'элемент- 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 divspanp
Вариант два: 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 divspanp
Ответ 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>Необязательным параметром fromElement задается тот элемент, от которого будет выполняться поиск ("вниз" по DOM). Клик по области результата сбрасывает классы с найденных элементов. В целом, код достаточно простой, думаю что он не требует подробных пояснений :) Источники инфы: https://stackoverflow.com/q/27334365 HTMLUnknownElement (MDN)
divzinaida test 1 pavel some spantest 2 p
Комментариев нет:
Отправить комментарий