Фиксы & Хаки: Длинные строки в PRE
При вставке примеров кода на страницы web-мастера обычно используют пробелы для отступов. Тег <pre> прекрасно отображаeт отступы, но тут есть и обратная сторона медали - если строка очень длинная, то она может или вылезти за пределы контейнера, или, что еще хуже, не запланировано растянуть этот контейнер, что может привести к краху всего дизайна страницы.
Интернет буквально кишит практически только одним решением на уровне CSS:
При подключении этого стиля длинные строки принудительно переносятся и в итоге получаем слегка не читаемую кашу.
Плюс ко всему, а точнее минус, в Internet Explorer, до 8й версии включительно, если у PRE появляется горизонтальный скроллинг, то у этого элемента автоматически добавляется правый отступ, равный ширине скроллинга, и который не возможно убрать.
Лично меня это не устраивает, поэтому был рожден следующий JavaScript , который подменяет оригинальный PRE его дубликатом, но уже с правильно отображенным содержимым:
Теперь в конце html-страницы разместите вызов метода fix_pre() и все ваши PRE будут отображаться именно так как вы задумывали.
Демонстрация оригинального PRE, PRE + CSS и PRE + JavaScript тут: demo.html
UPD:
через час, после написания этой статьи и её вдумчивого прочтения пришла мысль, что JavaScript можно оптимизировать, избавившись от создания дубликатов PRE
В итоге получился вот такой скрипт:
Интернет буквально кишит практически только одним решением на уровне 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, " ");
txt = txt.replace(/([^\n]*)\n/g, "<nobr>$1 </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';
}
}