Списки в IE, Mozilla, Opera. Version 1.1

11th October 2003 - 16:21

(продолжение «OL, LI: content, counter»)

— Revenge doesn’t work.
— Sure it does.

х/ф «Get Carter»

Если внести незначительные изменения в скрипт, то работать будет и в Opera 7 (но не младше). Однако это влечёт за собой необходимость дополнительных проверок. Всё-таки, раз уж Opera поддерживает счётчики CSS, то JavaScript ей не показываем.

<script language="JavaScript"><!--

if (!/Opera/.test(navigator.userAgent)){
	GoGoGo();
}

function GoGoGo(){
	OLs = document.getElementsByTagName("OL");
	for ( j = 0; j < OLs.length; j++ ) {
		LetsDoIt(OLs[j]);
	}
}

function LetsDoIt(element) {
	element.style.listStyleType = 'none';
	oM = element.childNodes.length;
	k = 0;
	for ( i = 0; i < oM; i++ ) {
		oLI = element.childNodes[i];
		if ( oLI.innerHTML!=undefined && !/li/.test(oLI.innerHTML) ){
			k++;
			oLI.innerHTML = k + '. ' + oLI.innerHTML;
			oLI.innerHTML = oLI.innerHTML.replace(/(([1-999]\. )([1-999]\. )*)/, "$1$2");
			oLI.innerHTML = oLI.innerHTML.replace(/[1-999]\. /, '');
		}
		if ( oLI.innerHTML!=undefined ){
			oLI.innerHTML = oLI.innerHTML.replace(/<li>((([1-999]\. )?)*)/gi, "<li>$1" + k + '. ');
		}
	}
}

--></script>

Update: Исправляя старые баги, добавляя новые…

По просьбе RusPutin’а изменил скрипт. Добавляем пару строк в CSS (для Оперы) и меняем function GoGoGo:

CSS:
ul li:before {content: "" !important;}
ol ul li {counter-reset: ol1 ol2 ol3 и так далее;}

JavaScript:
function GoGoGo(){

  OLs = document.getElementsByTagName("OL");
    for ( j = 0; j < OLs.length; j++ ) {
      LetsDoItOL(OLs[j]);
    }

  ULs = document.getElementsByTagName("UL");
    for ( j = 0; j < ULs.length; j++ ) {
      ULs[j].innerHTML =
        ULs[j].innerHTML.replace(/<li>((([1-999]\. )?)*)/gi, "<li>");
    }

}

Самый пакостный баг:

JavaScript:
if ( oLI.innerHTML!=undefined && !/li/.test(oLI.innerHTML) ){…}

Здесь я поторопился. Если оставить в таком виде, то при встрече «li» в тексте счётчик собьётся. Глупейший недосмотр, надо так:

JavaScript:
if ( oLI.innerHTML!=undefined && !/<li>/.test(oLI.innerHTML) ){…}

Для IE5.0 добавлена следующая строка:

JavaScript:
if (/MSIE 5.0/.test(navigator.userAgent)){ var undefined='' }

Test page (download all versions)

Проверено: Opera6+, IE5+, Mozilla1.4/FB0.6.

В потребности использования OL>UL сомнений нет, но OL>UL>OL… Нужна ли такая вложенность? Imfo, в ней мало дружелюбия по отношению к пользователю. Я решил не делать подобного, но если кому-то это действительно необходимо, то вот небольшой набросок, дорабатывайте сами.

Update 2:

  1. RegExp: [1-999] нужно поменять на \d+.
  2. Хак: html:root.
CSS:
ol {list-style-type: decimal;} /* IE, Opera, Mozilla */
html>body ol {list-style-type: none;} /* Opera, Mozilla */
html:root ol {list-style-type: decimal;} /* Mozilla */

Ссылки прежние.

Categories: CSS, dHtml, Web-билдинг | comments: (2)

Комментарии

1. Alexey 2nd April 2004 - 13:47

Нашел баг: Если длинна подсписка 10 и более элементов, то список сбивается. Исправьте плиз!!!!

Mash:

Большое спасибо.

На днях выложу другую версию (просто есть ещё пара моментов, над которыми стоит подумать).

12.04.2004: сделано.

2. vir 1st November 2005 - 04:31

Вот мой вариант. Работает в Firefox и IE6.0. Может кому пригодится.
GoGoGo(document, "");

function GoGoGo (html, prefix)
{
var OLs = html.getElementsByTagName(«OL»);
var flag = false;
for (var j = 0; j < OLs.length; j++) {
flag = false;
var parent = OLs[j].parentNode;
while (parent != html && parent != null) {
if (parent.tagName == «UL») {
flag = true;
break;
}

for (var i = 0; i < OLs.length; i++) {
if (parent == OLs[i]) {
flag = true;
break;
}
}

parent = parent.parentNode;
}
if (flag)
continue;
LetsDoIt(OLs[j], prefix);
}
}

function LetsDoIt (element, prefix)
{
element.style.listStyleType = 'none';
var oM = element.childNodes.length;
for (var i = 0; i < oM; i++ ) {
oLI = element.childNodes[i];
oLI.innerHTML = prefix + (i+1) + «. » + oLI.innerHTML;

GoGoGo (oLI, prefix + (i+1) + «. »);
}
}

Комментарии временно отключены.