Действия

MediaWiki

Common.js: различия между версиями

Материал из ВикиВоины

Строка 32: Строка 32:
  
 
   if ($(window).width() < 640) {
 
   if ($(window).width() < 640) {
     var contents = $('<div class="contents-overlay"></div>').hide();
+
     // Код для мобильных устройств
    var sideNav = $('<ul class="side-nav"></ul>');
 
    var contentsItemWrap = $('<div class="contents-item-wrap"></div>');
 
    var contentsItemWrapFirst = $('<li></li>');
 
    var label = $('<label class="sidebar" id="p-tb">Содержание</label>');
 
 
 
    label.appendTo(contentsItemWrapFirst);
 
    contentsItemWrapFirst.appendTo(sideNav);
 
    sideNav.appendTo(contents);
 
    contentsItemWrap.appendTo(sideNav);
 
    contents.appendTo('.inner-wrap');
 
 
 
    createContentsList($('#toc > ul'), contentsItemWrap);
 
 
 
    var closeButton = $('<button class="close-button"><i class="fa fa-times"></i></button>');
 
    contents.append(closeButton);
 
 
 
    var isContentsOpen = false;
 
 
 
    $('.content-button').on('click touchstart', function(e) {
 
      e.preventDefault();
 
      contents.toggle();
 
      updateIconColor();
 
    });
 
 
 
    $('.close-button').on('click touchstart', function(e) {
 
      e.preventDefault();
 
      contents.hide();
 
      updateIconColor();
 
    });
 
 
 
    function updateIconColor() {
 
      var isVisible = contents.is(':visible');
 
      $('.fa-list-ul').css('color', isVisible ? '#511414' : '');
 
    }
 
 
   } else {
 
   } else {
 
     if ($('#toc').length) {
 
     if ($('#toc').length) {
Строка 101: Строка 67:
 
             var id = $heading.attr('id');
 
             var id = $heading.attr('id');
 
             if (id) {
 
             if (id) {
               var $contentItem = $('.side-nav a[href="#' + id + '"]').parent(); // Находим элемент списка содержания, соответствующий текущему заголовку
+
              // Экранируем символы для использования в CSS селекторах
 +
              var escapedId = $.escapeSelector(id);
 +
               var $contentItem = $('.side-nav a[href="#' + escapedId + '"]').parent(); // Находим элемент списка содержания, соответствующий текущему заголовку
 
               if ($contentItem.length) {
 
               if ($contentItem.length) {
 
                 // Удаляем класс active у предыдущего активного элемента
 
                 // Удаляем класс active у предыдущего активного элемента

Версия 21:48, 4 мая 2024

$(document).ready(function() {
  var $activeContentItem = null; // Переменная для отслеживания предыдущего активного элемента списка содержания

  function createContentsList($list, $parentItem) {
    $list.children('li').each(function() {
      var $listItem = $(this);
      var classes = $listItem.attr('class').split(' ');
      var tocLevel = classes.find(function(cls) {
        return cls.startsWith('toclevel-');
      });

      if (tocLevel) {
        var $sectionLink = $listItem.children('a').first();
        var sectionTitle = $sectionLink.find('.toctext').text().trim();
        var id = $sectionLink.attr('href'); // Получаем id из атрибута href ссылки
        var listItem = $('<li></li>');
        var sectionLink = $('').text(sectionTitle);
        sectionLink.attr('href', id); // Присваиваем href ссылки id заголовка
        listItem.append(sectionLink);

        var $subList = $listItem.children('ul').first();
        if ($subList.length) {
          var subLinkList = $('<ul class="side-nav"></ul>');
          listItem.append(subLinkList);
          createContentsList($subList, subLinkList);
        }

        $parentItem.append(listItem);
      }
    });
  }

  if ($(window).width() < 640) {
    // Код для мобильных устройств
  } else {
    if ($('#toc').length) {
      var contents = $('<div class="contents side-nav"></div>');
      var isFixed = false;
      var activeSection = null;

      var linkList = $('<ul class="side-nav"></ul>');
      contents.append(linkList);

      var contentLabel = $('<label class="sidebar" id="p-tb">Содержание</label>');
      var contentListItem = $('<li></li>');
      contentListItem.append(contentLabel);
      linkList.append(contentListItem);

      createContentsList($('#toc > ul'), linkList);

      if (linkList.children().length > 1) {
        $('#sidebar:last').append(contents);
      }

      var sidebarTop = $('.sidebar:last').offset().top;
      var contentsTop = contents.offset().top;
      var windowHeight = $(window).height();

      $(window).scroll(function() {
        var scrollTop = $(window).scrollTop();

        // При прокрутке страницы проверяем каждый заголовок на то, находится ли он в области видимости
        $('h1, h2, h3, h4, h5, h6').each(function() {
          var $heading = $(this);
          var headingTop = $heading.offset().top;
          if (headingTop <= scrollTop + 100) { // 100 - отступ от верха экрана
            var id = $heading.attr('id');
            if (id) {
              // Экранируем символы для использования в CSS селекторах
              var escapedId = $.escapeSelector(id);
              var $contentItem = $('.side-nav a[href="#' + escapedId + '"]').parent(); // Находим элемент списка содержания, соответствующий текущему заголовку
              if ($contentItem.length) {
                // Удаляем класс active у предыдущего активного элемента
                if ($activeContentItem) {
                  $activeContentItem.removeClass('active');
                }
                // Добавляем класс active текущему элементу списка содержания
                $contentItem.addClass('active');
                // Обновляем переменную $activeContentItem для следующей итерации
                $activeContentItem = $contentItem;
              }
            }
          }
        });

        // Проверяем, нужно ли зафиксировать боковое меню
        if (scrollTop > sidebarTop && scrollTop > contentsTop && !isFixed) {
          contents.addClass('fixed');
          isFixed = true;
        } else if ((scrollTop <= sidebarTop || scrollTop <= contentsTop) && isFixed) {
          contents.removeClass('fixed');
          isFixed = false;
        }
      });
    }
  }
});