Как создать уникальный селектор css для элемента DOM?
Мне нужно создать уникальный селектор css для элементов.
В частности, у меня есть обработчик событий onclick, который должен помнить, какой целевой элемент
был нажат и отправил эту информацию на мой сервер. Есть ли способ сделать это без внесения изменений DOM?
P. S. мой код Javascript должен быть запущен на разных
3-х партийные сайты, поэтому я не могу делать никаких предположений о html.
6 ответов
допустим у вас есть список ссылок для простоты: вы можете просто передать указатель пусковым элементом в коллекции все элементы
<a href="#">...</a>
<a href="#">...</a>
<a href="#">...</a>
js (jQuery 1.7+, я использовал .on()
в противном случае используйте bind()
функция) может быть
var triggers = $('a');
triggers.on('click', function(e) {
e.preventDefault();
var index = triggers.index($(this));
/* ajax call passing index value */
});
так что если вы нажмете на третий элемент, значение индекса будет 2. Индекса (на основе 0 );
конечно, это действительно до тех пор, пока код (DOM) не изменится. Позже вы можете использовать этот индекс для создания правила css для этот элемент, например, использует :nth-child
в противном случае, если каждый из ваших элементов имеет другой атрибут (например, id), вы можете передать этот атрибут
пример на JsFiddle : http://jsfiddle.net/t7J8T/
Да, вы могли бы это сделать. Но с некоторыми оговорками. Чтобы гарантировать уникальность селекторов, вам необходимо использовать :nth-child()
который не поддерживается повсеместно. Если вы хотите поместить эти селекторы CSS в CSS-файлы, он не будет работать во всех браузерах.
Я бы сделал это что-то вроде этого:
function () {
if (this.id) {
return sendToServer('#' + this.id);
}
var parent = this.parentNode;
var selector = '>' + this.nodeName + ':nth-child(' + getChildNumber(this) ')';
while (!parent.id && parent.nodeName.toLowerCase() !== 'body') {
selector = '>' + this.nodeName + ':nth-child(' + getChildNumber(parent) + ')' + selector;
parent = parent.parentNode;
}
if (parent.nodeName === 'body') {
selector = 'body' + selector;
} else {
selector = '#' + parent.id + selector;
}
return sendToServer(selector);
}
затем добавьте это в обработчик click для каждого элемента, который вы хотите смоделировать. Я оставлю вас, чтобы реализовать getChildNumber()
.
Edit: только что видел ваш комментарий о том, что это сторонний код... таким образом, вы можете добавить
эта функция создает длинный, но довольно практичный уникальный селектор, работает быстро.
const getCssSelector = (el) => {
let path = [], parent;
while (parent = el.parentNode) {
path.unshift(`${el.tagName}:nth-child(${[].indexOf.call(parent.children, el)+1})`);
el = parent;
}
return `${path.join(' > ')}`.toLowerCase();
};
пример результата:
html:nth-child(1) > body:nth-child(2) > div:nth-child(1) > div:nth-child(1) > main:nth-child(3) > div:nth-child(2) > p:nth-child(2)
следующий код создает немного более красивый и короткий селектор
const getCssSelectorShort = (el) => {
let path = [], parent;
while (parent = el.parentNode) {
let tag = el.tagName, siblings;
path.unshift(
el.id ? `#${el.id}` : (
siblings = parent.children,
[].filter.call(siblings, sibling => sibling.tagName === tag).length === 1 ? tag :
`${tag}:nth-child(${1+[].indexOf.call(siblings, el)})`
)
);
el = parent;
};
return `${path.join(' > ')}`.toLowerCase();
};
пример результата:
html > body > div > div > main > div:nth-child(2) > p:nth-child(2)
вы, вероятно, могли бы пересечь дерево DOM от узла обратно к элементу body для создания селектора.
Firebug имеет функцию для этого, используя селекторы XPath и CSS.
посмотреть ответ
"use strict";
function getSelector(_context){
var index, localName,pathSelector, that = _context, node;
if(that =='null') throw 'not an dom reference';
index = getIndex(that);
while(that.tagName){
pathSelector = that.localName+(pathSelector?'>'+pathSelector :'');
that = that.parentNode;
}
pathSelector = pathSelector+':nth-of-type('+index+')';
return pathSelector;
}
function getIndex(node){
var i=1;
var tagName = node.tagName;
while(node.previousSibling){
node = node.previousSibling;
if(node.nodeType === 1 && (tagName.toLowerCase() == node.tagName.toLowerCase())){
i++;
}
}
return i;
}
document.addEventListener('DOMContentLoaded', function(){
document.body.addEventListener('mouseover', function(e){
var c = getSelector(e.target);
var element = document.querySelector(c);
//console.log(element);
console.log(c);
//element.style.color = "red"
});
});
вы можете попробовать это. без использования jquery.
проверьте эту библиотеку генератора селектора CSS @medv / finder
- генерирует самые короткие селекторы
- уникальные селекторы на странице
- стабильные и надежные селекторы
- 2.9 kB gzip и уменьшить размер
пример сгенерированного селектора:
.blog > article:nth-child(3) .add-comment