S3.Blog

19 Марта 2024
A A A   RSS-лента
"Я знаю, что ничего не знаю, но многие не знают и этого". Сократ [?].

Фиксы & Хаки: Длинные строки в PRE

Дата последнего изменения: 3 Октября 2009
Метки статьи: Фиксы & Хаки, HTML, JavaScript, © Авторское
При вставке примеров кода на страницы web-мастера обычно используют пробелы для отступов. Тег <pre> прекрасно отображаeт отступы, но тут есть и обратная сторона медали - если строка очень длинная, то она может или вылезти за пределы контейнера, или, что еще хуже, не запланировано растянуть этот контейнер, что может привести к краху всего дизайна страницы.
 

Интернет буквально кишит практически только одним решением на уровне CSS:
pre {
	overflow: auto;
	width: 100%;
	white-space: pre-wrap; /* css-3 */ 
	white-space: -moz-pre-wrap; /* Mozilla, начиная с 1999 года */ 
	white-space: -pre-wrap; /* Opera 4-6 */ 
	white-space: -o-pre-wrap; /* Opera 7 */ 
	word-wrap: break-word; /* Internet Explorer 5.5+ */ 
}

При подключении этого стиля длинные строки принудительно переносятся и в итоге получаем слегка не читаемую кашу.

Плюс ко всему, а точнее минус, в Internet Explorer, до 8й версии включительно, если у PRE появляется горизонтальный скроллинг, то у этого элемента автоматически добавляется правый отступ, равный ширине скроллинга, и который не возможно убрать.

Лично меня это не устраивает, поэтому был рожден следующий JavaScript , который подменяет оригинальный PRE его дубликатом, но уже с правильно отображенным содержимым:
<script language="javascript">
function fix_pre() {
	//-- check IE --------------------
	var this_ie = false;
	/*@cc_on
		/*@if (@_jscript)
			this_ie = (document.all && !window.opera) ? true : false;
		/*@else @*/
			this_ie = false;
		/*@end
	@*/

	//-- Process ---------------------
	var ary=document.getElementsByTagName('pre');
	var ary_dubl = new Array();
	for (var i=0; i<ary.length; i++) {
		ary_dubl[i] = ary[i];
	}
	for (var i=0; i<ary_dubl.length; i++) {
		var el = ary_dubl[i];

		var width = el.offsetWidth;
		var height = el.offsetHeight;

		var txt = el.innerHTML;
		txt = txt.replace(/\r/g, "");

		var el_new = document.createElement("pre");
		el_new.style.width = width + 'px';
		el_new.style.height = height + 'px';

		if (this_ie) {
			txt = txt.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
			txt = txt.replace(/([^\n]*)\n/g, "<nobr>$1&nbsp;</nobr><br>");
			txt = txt.replace(/\n/g, "<br>");
		}

		el_new.innerHTML = txt;
		el.style.display = 'none';
		el.parentNode.insertBefore(el_new, el);
	}
}
</script>

Теперь в конце html-страницы разместите вызов метода fix_pre() и все ваши PRE будут отображаться именно так как вы задумывали.
<script language="javascript">
fix_pre();
</script>

Демонстрация оригинального PRE, PRE + CSS и PRE + JavaScript тут: demo.html


UPD:

через час, после написания этой статьи и её вдумчивого прочтения пришла мысль, что JavaScript можно оптимизировать, избавившись от создания дубликатов PRE
В итоге получился вот такой скрипт:
function fix_pre() {
	//-- Process ---------------------
	var ary=document.getElementsByTagName('pre');
	for (var i=0; i<ary.length; i++) {
		ary[i].style.display = 'none';
	}
	for (var i=0; i<ary.length; i++) {
		var el = ary[i];

		el.style.height = '1px';

		var width = el.parentNode.offsetWidth - 16;
		el.style.width = width + 'px';

		el.style.display = 'block';
		var height = el.offsetHeight;
		var fix = 0;
		if (el.scrollWidth > el.offsetWidth) {
			fix = 8;
		}

		el.style.height = (el.scrollHeight + fix) + 'px';
	}
}



Похожие материалы:




 
  Имя *:   Решите пример *: =
 
Полужирный Курсив Подчеркнутый Перечеркнутый
 
Вставить изображение Сделать цитатой Вставить ссылку Вставить код

Вставить смайл
 
 

 



© S3.Blog: Если критикуешь, не предлагая решения проблемы, то ты становишься частью этой проблемы.