Как получить доступ к CSS-контенту с помощью JavaScript - PullRequest
53 голосов
/ 16 апреля 2010

Я генерирую нумерацию своих заголовков и цифр с помощью свойств CSS counter и content:

img.figure:after {
  counter-increment: figure;
  content: "Fig. " counter(section) "." counter(figure);
}

Это (предполагается, что соответствующий браузер) дает красивую маркировку "Рис. 1.1", "Рис. 1.2" и т. Д. После любого изображения.

Вопрос: Как я могу получить доступ к этому из Javascript? Вопрос двоякий: я хотел бы получить доступ к или текущему значению определенного счетчика (в определенном узле DOM) или значению содержимого, сгенерированного CSS (по определенный узел DOM) или , очевидно, обе информации.

Справочная информация: Я хотел бы добавить к ссылкам, обратным ссылкам на цифры соответствующее число, например:

<a href="#fig1">see here</h>
------------------------^ " (Fig 1.1)" inserted via JS

Насколько я вижу, это сводится к этой проблеме: Я мог получить доступ content или counter-increment через getComputedStyle:

var fig_content = window.getComputedStyle(
                    document.getElementById('fig-a'),
                    ':after').content;

Однако это не значение live , а значение, объявленное в таблице стилей. Я не могу найти интерфейс для доступа к действительному значению real . В случае счетчика нет даже реального CSS-свойства для запроса.

Редактировать: Копая глубже и глубже через спецификации DOM, я нашел интерфейс счетчика стилей DOM Level 2 . Похоже, это а) разрешает доступ к текущему значению счетчика и б) по крайней мере реализовано в Firefox. Тем не менее, я понятия не имею, как его использовать. Мой нынешний подход трагически погиб после выхода Firebug:

// should return a DOM 2 Counter interface implementation...
window.getComputedStyle(fig_a_element, ':after')
      .getPropertyCSSValue("counter-increment")[0]
      .getCounterValue();

[Exception... "Modifications are not allowed for this document" code: "7"
 nsresult: "0x80530007 (NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR)"
 location: "http://localhost/countertest.html Line: 71"]

Любая идея, как это можно воплотить в жизнь, будет высоко оценена.

Редактировать 2: Видимо, я неверно истолковал объект Counter в стиле DOM Level 2. У него тоже нет свойства для возврата текущего значения счетчика. Это делает вышеуказанный подход недействительным.

Новый подход: есть ли возможность читать содержимое псевдоэлемента через DOM? То есть я могу выбрать псевдоэлемент (на ум приходит treeWalker) и затем получить его nodeValue? (Если вы начнете набирать 'jQuery' сейчас, пожалуйста, измените этот термин на 'Sizzle' ...)

Ответы [ 4 ]

22 голосов
/ 16 апреля 2010

Я не могу найти интерфейс для доступа к реальной стоимости. [счетчика]

Да. Я не думаю, что есть один. К сожалению.

Единственное, о чем я могу подумать, - это просмотреть каждый элемент (включая его :before / :after псевдоэлементы) перед элементом в документе, найти счетчики и сложить, сколько их есть.

Очевидно, это отвратительно. Если вы попытаетесь воспроизвести собственный механизм браузера counter, вероятно, будет проще (и гораздо более совместимо, учитывая отсутствие поддержки счетчиков / содержимого в IE <= 7) просто заменить его на свои собственные счетчики на основе сценариев. , например. что-то вроде: </p>

<a href="#prettypicture">this</a>

<div class="counter level=0">...</div>
<img id="prettypicture" class="counter level=1" alt="ooo, pretty"/>
window.onload= function() {
    var counters= Node_getElementsByClassName(document.body, 'counter');
    var indices= [];
    for (var counteri= 0; counteri<counters.length; counteri++) {
        var counter= counters[counteri];

        var level= Element_getClassArgument(counter, 'level');
        while (indices.length<=level)
            indices.push(0);
        indices[level]++;
        indices= indices.slice(level+1);
        var text= document.createTextNode('Figure '+indices.join('.'));
        counter.parentNode.insertBefore(text, counter.nextSibling);

        if (counter.id!=='') {
            for (var linki= document.links.length; linki-->0;) {
                var link= document.links[i];
                if (
                    link.hostname===location.hostname && link.pathname===location.pathname &&
                    link.search===location.search && link.hash==='#'+counter.id
                ) {
                    var text= document.createTextNode('('+indices.join('.')+')');
                    link.parentNode.insertBefore(text, link.nextSibling);
                }
            }
        }
    }
};
15 голосов
/ 25 мая 2010

читать это:

Созданный контент не изменяет дерево документов. В частности, это не возвращается на язык документа процессор (например, для повторного анализа).


Содержимое, указанное в таблице стилей, не становится частью DOM.

, поэтому по этой причине getComputedStyle не будет работать в этом случае ; я думаю, что единственный способ, это выполнить классический цикл через , как кто-то описал ниже!

1 голос
/ 18 мая 2010

Я бы перенес вашу CSS в Javascript, это позволит вам получить подпись к рисунку, а также вы получите больший охват браузером. Используя jQuery, вы бы сделали что-то вроде этого:

$(function() {
  var section = 0;
  $(".section").each(function() {
    section++;
    var figure = 0;
    $(this).find("img.figure").each(function() {
      figure++;
      var s = "Fig. " + section + "." + figure;
      $(this).attr({alt:s}).after(s);
    });
  });
});

Тогда вы можете сделать:

<div class="section">blabla <img id="foo" src="http://www.example.com/foo.jpg"></div>
<p>Lorem ipsum dolor sit amet <a href="#foo" class="figurereference">see here</a></p>

<script type="text/javascript">
  $(function() {
    $("a.figurereference").each(function() {
      var selector = $(this).attr("href");
      var $img = $(selector);
      var s = $(this).text() + " (" + $img.attr("alt") + ")";
      $(this).text(s);
    });
  });
</script>

Хотя я согласен, что делать это с помощью CSS было бы очень аккуратно.

0 голосов
/ 16 апреля 2010

Я не могу найти интерфейс для доступа к реальному значению.

Если вы не можете получить значение из window.getComputedStyle, кажется, что это будет невозможно.

Что еще более важно, хотя он и может это делать, я думаю, что это может злоупотреблять CSS, поскольку на этом этапе вы преодолеваете барьер между контентом и представлением.

Проверьте этот связанный вопрос Как правильно использовать свойство css “Content”?

...