Фиксы & Хаки: Длинные строки в 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'; } }