Как создать уникальный селектор CSS для элемента DOM?

javascript dom css-selectors

5524 просмотра

6 ответа

Мне нужно создать уникальный селектор CSS для элементов.
В частности, у меня есть обработчик события onclick, который должен помнить, по какому целевому элементу был нажат и отправлять эту информацию на мой сервер. Есть ли способ сделать это без модификации DOM?

PS мой javascript-код должен запускаться на разных
сторонних веб-сайтах, поэтому я не могу делать никаких предположений относительно html.

Автор: tsds Источник Размещён: 12.11.2019 09:11

Ответы (6)


1 плюс

Решение

допустим, у вас есть список ссылок для простоты: вы можете просто передать индекс триггерного элемента в коллекцию всех элементов

<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

В противном случае, если каждый из ваших элементов имеет свой атрибут (например, идентификатор), вы можете передать этот атрибут

пример на JsFiddle: http://jsfiddle.net/t7J8T/

Автор: fcalderan Размещён: 21.12.2011 10:32

4 плюса

Да, вы могли бы сделать это. Но с несколькими оговорками. Чтобы гарантировать, что селекторы уникальны, вам нужно использовать то, :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);
}

Затем добавьте это в ваш обработчик кликов для каждого элемента, который вы хотите моделировать. Я оставлю вас для реализации getChildNumber().

Edit: Просто видел ваш комментарий про то , что третья сторона кода ... так что вы можете добавить eventаргумент, заменить все экземпляры thisс , event.targetа затем просто прикрепить функцию к windowсобытию щелчка «S , если это проще.

Автор: Nathan MacInnes Размещён: 21.12.2011 10:35

3 плюса

Эта функция создает длинный, но довольно практичный уникальный селектор, работает быстро.

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)
Автор: redisko Размещён: 05.04.2018 02:18

1 плюс

Возможно, вы могли бы пройтись по дереву DOM от узла обратно к элементу body, чтобы сгенерировать селектор.

Firebug имеет функцию для этого, используя как XPath, так и CSS-селекторы.

Смотрите этот ответ

Автор: Jani Hartikainen Размещён: 21.12.2011 10:29

1 плюс

"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.

Автор: Maneesh Singh Размещён: 11.09.2014 07:07

1 плюс

Проверьте эту библиотеку генератора селекторов CSS @ medv / finder

Статус сборки

  • Создает кратчайшие селекторы
  • Уникальные селекторы на странице
  • Стабильные и надежные селекторы
  • Gzip 2.9 кБ и уменьшенный размер

Пример сгенерированного селектора:

.blog > article:nth-child(3) .add-comment
Автор: Anton Medvedev Размещён: 21.02.2018 06:36
Вопросы из категории :
32x32