При разработке собственных редакторов текста или систем отображения сложной документации внутри 1С программисты часто сталкиваются с тем, что стандартные гиперссылки-якоря (вида #target) отказываются работать. В этой статье мы подробно разберем, почему возникает эта проблема, как на нее влияют особенности платформы 1С:Предприятие и какие существуют надежные способы реализации навигации внутри HTML-поля.
Разберем ситуацию: когда мы передаем HTML-код в поле документа через метод УстановитьТекст() или напрямую присваиваем значение строковому реквизиту, связанному с полем, документ создается "в памяти". В этот момент у него отсутствует физический адрес (URL). Большинство браузерных движков (как старый Internet Explorer/Trident, так и современные WebKit/Chromium, используемые в 1С) в таких случаях присваивают странице базовый адрес about:blank.
Когда пользователь нажимает на ссылку <a href="#chapter1">, браузер пытается выполнить переход по адресу about:blank#chapter1. В контексте безопасности 1С или из-за особенностей обработки навигации внутри контейнера управления этот переход часто блокируется или просто игнорируется. Проанализируем основные методы обхода этого ограничения.
Одним из самых популярных и "мягких" решений является перехват события нажатия на ссылку с последующей программной прокруткой страницы до нужного элемента. Рассмотрим, как это реализовать с помощью библиотеки JQuery. Нам необходимо добавить скрипт в секцию <head> нашего HTML-документа.
Проанализируем пример кода, который позволяет плавно прокрутить страницу до нужного якоря:
$(document).ready(function() {
$('a').click(function() {
var elementClick = $(this).attr('href');
var firstChar = elementClick.substr(0,1);
if (firstChar == '#') {
var destination = $(elementClick).offset().top;
$('html, body').animate({ scrollTop: parseInt(destination) }, 1000);
return false;
}
});
});
Разберем по шагам, что происходит в этом скрипте:
click на все теги <a>.href.offset().top.animate для плавной прокрутки. Значение 1000 — это время анимации в миллисекундах.return false предотвращает стандартное поведение браузера (попытку перехода), которую мы и хотим избежать.Если нет возможности или желания подключать тяжелую библиотеку JQuery (например, в мобильном приложении или при жестких требованиях к скорости загрузки), можно воспользоваться современным методом scrollIntoView. Рассмотрим, как это сделать программно из кода 1С или вшить в сам HTML.
В современных версиях платформы (8.3.14+), где используется движок WebKit/Chromium, отлично работает следующий подход:
function scrollToAnchor(anchorId) {
var element = document.getElementById(anchorId);
if (element) {
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
}
Вызвать эту функцию можно непосредственно при нажатии на ссылку, изменив HTML-код следующим образом:
<a href="javascript:void(0);" onclick="scrollToAnchor('my_target_id')">Перейти к разделу</a>
Выясним причину, почему иногда помогает вставка тега <base>. Если мы укажем браузеру, какой адрес считать основным, он может начать корректно сопоставлять относительные ссылки. Посмотрим на пример добавления тега в <head>:
<base href="file:///C:/temp/">
Однако этот метод имеет существенный недостаток: при использовании путей к временному хранилищу 1С (вида e1cib/tempstorage/) для картинок, явное указание base может "сломать" отображение этих картинок, так как браузер начнет искать их относительно указанного пути, а не в виртуальной файловой системе 1С.
Как отмечают опытные разработчики, якоря начинают работать "сами по себе", если документ загружен не как текст, а как файл. Разберем алгоритм этого метода:
ТекстовыйДокумент.Записать().Элементы.ПолеHTMLДокумента.УстановитьТекст() или Перейти(), передавая путь к файлу.Преимущество: Полная поддержка стандартного поведения браузера, включая якоря и историю переходов.
Недостаток: Проблемы с безопасностью (нужны права на запись в папку) и потенциальные трудности с отображением картинок из временного хранилища 1С, так как контекст сеанса может потеряться при обращении к локальному файлу.
В коде первого сообщения темы автор пытался использовать метод execCommand("CreateBookmark", ...). Важно понимать, что этот метод является устаревшим (deprecated) в спецификациях современных браузеров. Вместо него рекомендуется манипулировать DOM-деревом напрямую через объект Документ в 1С.
Например, чтобы программно вставить якорь в текущую позицию курсора, лучше использовать следующий подход в 1С:
// Получаем объект документа
ДокументHTML = Элементы.ПолеHTMLДокумента.Документ;
// Создаем новый элемент "A"
НовыйЯкорь = ДокументHTML.createElement("a");
НовыйЯкорь.id = "MyAnchorName";
НовыйЯкорь.name = "MyAnchorName";
// Вставляем его в нужное место через Range или AppendChild
Проанализировав ситуацию, мы видим, что наиболее универсальным и современным решением для платформы 1С:Предприятие 8.3 является использование JavaScript-перехватчиков. Это позволяет:
Рассмотрим финальный совет: если вы используете JQuery, всегда проверяйте версию библиотеки. Для корректной работы animate в старых релизах 1С (где движок IE) лучше использовать более старые версии JQuery (например, 1.12.4), так как новые версии могут содержать несовместимый синтаксис.