Как реализовать переход по якорям в поле HTML-документа 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке собственных редакторов текста или систем отображения сложной документации внутри 1С программисты часто сталкиваются с тем, что стандартные гиперссылки-якоря (вида #target) отказываются работать. В этой статье мы подробно разберем, почему возникает эта проблема, как на нее влияют особенности платформы 1С:Предприятие и какие существуют надежные способы реализации навигации внутри HTML-поля.

В чем причина неработоспособности якорей?

Разберем ситуацию: когда мы передаем HTML-код в поле документа через метод УстановитьТекст() или напрямую присваиваем значение строковому реквизиту, связанному с полем, документ создается "в памяти". В этот момент у него отсутствует физический адрес (URL). Большинство браузерных движков (как старый Internet Explorer/Trident, так и современные WebKit/Chromium, используемые в 1С) в таких случаях присваивают странице базовый адрес about:blank.

Когда пользователь нажимает на ссылку <a href="#chapter1">, браузер пытается выполнить переход по адресу about:blank#chapter1. В контексте безопасности 1С или из-за особенностей обработки навигации внутри контейнера управления этот переход часто блокируется или просто игнорируется. Проанализируем основные методы обхода этого ограничения.

Способ 1. Принудительная прокрутка через JQuery

Одним из самых популярных и "мягких" решений является перехват события нажатия на ссылку с последующей программной прокруткой страницы до нужного элемента. Рассмотрим, как это реализовать с помощью библиотеки 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;
        }
    });
});

Разберем по шагам, что происходит в этом скрипте:

  1. Мы вешаем обработчик события click на все теги <a>.
  2. При нажатии мы получаем значение атрибута href.
  3. Проверяем, начинается ли адрес с символа #. Это позволяет нам отделить внутренние ссылки от внешних (http/https).
  4. Если это якорь, мы вычисляем координаты целевого элемента с помощью offset().top.
  5. Используем метод animate для плавной прокрутки. Значение 1000 — это время анимации в миллисекундах.
  6. Важно: return false предотвращает стандартное поведение браузера (попытку перехода), которую мы и хотим избежать.

Способ 2. Решение на чистом JavaScript (Vanilla JS)

Если нет возможности или желания подключать тяжелую библиотеку 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>

Способ 3. Использование тега BASE

Выясним причину, почему иногда помогает вставка тега <base>. Если мы укажем браузеру, какой адрес считать основным, он может начать корректно сопоставлять относительные ссылки. Посмотрим на пример добавления тега в <head>:

<base href="file:///C:/temp/">

Однако этот метод имеет существенный недостаток: при использовании путей к временному хранилищу 1С (вида e1cib/tempstorage/) для картинок, явное указание base может "сломать" отображение этих картинок, так как браузер начнет искать их относительно указанного пути, а не в виртуальной файловой системе 1С.

Способ 4. Работа с временными файлами

Как отмечают опытные разработчики, якоря начинают работать "сами по себе", если документ загружен не как текст, а как файл. Разберем алгоритм этого метода:

  1. Записываем сформированную строку HTML во временный файл на диске пользователя с помощью ТекстовыйДокумент.Записать().
  2. Получаем путь к этому файлу.
  3. Используем метод Элементы.Поле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), так как новые версии могут содержать несовместимый синтаксис.

← На главную