Статьи

Сокровища Techy # 5: Обманка CSS-счетчиков в Internet Explorer

Шоколадный ИП Фадж. Ммм Ммм!

Посмотрите на этот пример упорядоченного списка со стилизованной нумерацией: http://www.sitepoint.com/examples/css-counters/

Нумерация элементов списка в этом примере реализована с использованием счетчиков CSS , функции CSS2, которая позволяет подсчитывать экземпляры определенного элемента (или группы элементов, идентифицированных селектором), а затем использовать псевдоэлементы для отображения номеров. В простейшем воплощении его можно использовать для замены нумерации упорядоченного списка, как в примере выше, что добавляет немного нумерации к нумерации, просто чтобы проиллюстрировать, что это происходит. Поскольку это становится более сложным, его можно использовать для замены устаревшего атрибута начала или для применения систем нумерации, которые более сложны, чем поддерживает нумерация собственных списков, например, нумерация, такая как 1.1 , 1.2 и так далее.

CSS для этого примера выглядит следующим образом:

#css-counters-test
{
	counter-reset: step;
}
#css-counters-test li::before
{
	counter-increment: step;
	content: counter(step) ": ";
	color: green;
	font-weight: bold;
}

Теперь проблема с его более широким распространением заключается в том, что, как это часто бывает, он не поддерживается в Internet Explorer; даже не IE8. Однако, используя проприетарную особенность реализации CSS в IE , мы на самом деле можем реализовать счетчики. Как? Используя хваленое, но редко используемое свойство выражения .

Основная проблема с выражением и внешняя причина, по которой он не используется для генерируемого контента, состоит в том, что он постоянно переоценивает — хотя его можно использовать для изменения HTML- элемента, если мы позволяем ему постоянно переоценивать, тогда мы буду постоянно менять HTML . Ничего хорошего. Но … мы можем использовать выражения таким образом, чтобы избежать переоценки, используя одноразовое выражение использования , изобретенное Джейсоном Дэвисом.

Взгляните на страницу примера в IE, и вы увидите, что нумерация там тоже работает, и это делается с помощью следующего кода:

 #css-counters-test li
{
	zoom: expression(
		  (typeof step == "undefined" ? step = 1 : step++), 
		  this.innerHTML = (typeof this.processed == "undefined" 
				? ("<span class=before>" + step + ": </span>") 
				: "") 
			+ this.innerHTML, 
		  this.processed = true, 
		  this.runtimeStyle.zoom = "1"
		  );
}

#css-counters-test li span.before
{
	color: darkblue;
	font-weight: bold;
}

Теория выражения одноразового использования проста: выражение может принимать любое количество операторов, но возвращается только последнее . Таким образом, в последнем утверждении мы переопределяем свойство expression, записывая в runtimeStyle (который является записываемой версией currentStyle , свойством computed-style IE ), и оно удаляет свойство expression и тем самым предотвращает его переоценку — оно не повторяет оценить, потому что его больше нет!

(На самом деле, по причинам, которые я не смог понять, каждое из этих выражений фактически вычисляется дважды , и именно поэтому я использовал processedIE оценивает открытый тег и закрывающий тег для каждого экземпляра селектора, но это всего лишь предположение. Но в любом случае, простое предостережение, подобное этому, не является проблемой. Использование свойства zoom здесь произвольно — мы можем использовать любое свойство CSS , если IE его поддерживает; я выбрал zoomheightauto

Так что у нас это. В то время как нормальное выражение, которое вычисляется постоянно, бесполезно для изменения HTML , то, что мы имеем здесь, может быть использовано для этого и, следовательно, может использоваться для реализации счетчиков CSS !