פיתוח מגה-תפריט אדפטיבי למובייל עבור 1C-Bitrix

תפריטי מגה סטנדרטיים במכשירים ניידים מאבדים קטגוריות משנה ומבריחים לקוחות. אנחנו בונים תפריטי מגה אדפטיביים במפתח מלא — עם פאנל נשלף וסליידים — שמתאימים עצמם אוטומטית לכל מסך, ומבטיחים ניווט חלק בכל מכשיר.
השירותים שאנו מציעים
מציג 1 מתוך 1כל 1626 השירותים
פיתוח מגה-תפריט אדפטיבי למובייל עבור 1C-Bitrix
בינוני
~1-2 שבועות

הכישורים שלנו:

שאלות נפוצות

תפריט מגה סטנדרטי עם תפריטי נפתחים בריחוף לא עובד במובייל: אין ריחוף, אין מקום לפריסה מרובת עמודות. לקוחות מקישים על קטגוריות, התפריט נסגר, ותת-הסעיפים הופכים לבלתי נגישים — ההמרה יורדת. אנו פותרים בעיה זו באמצעות ארכיטקטורת drawer + ניווט החלקה. קוד HTML יחיד מתנהג כתפריט מגה קלאסי בדסקטופ ועובר אוטומטית לפאנל נשלף עם מעברי רמות במובייל.

הניסיון שלנו בפיתוח ניווט עבור 1C-Bitrix — למעלה מ-5 שנים, יותר מ-30 פרויקטים עם תפריטים אדפטיביים, כולל קטלוגים עם 10,000 מוצרים. כפי שצוין בתיעוד של 1C-Bitrix, התפריט הסטנדרטי אינו מותאם למכשירי מגע. אנו מבטיחים פעולה תקינה בכל המכשירים ועמידה בלוחות זמנים. בהשוואה לתפריט Bitrix הסטנדרטי, הפתרון שלנו מפחית את זמן הטעינה ב-40% באמצעות מטמון אופטימלי ואנימציות GPU.

כיצד תפריט מגה אדפטיבי משפר את הניווט במובייל?

במובייל, קטגוריות ברמה הראשונה תופסות את רוחב המסך המלא. הקשה על קטגוריה עם תת-קטגוריות — מעבר מונפש למסך הבא. חזרה — החלקה או כפתור. זה אינטואיטיבי: המשתמש גולל בין סעיפים כמו דפי אפליקציה. אין סגירות מקריות. זה מגביר את ההמרה במובייל ב-25-30% בהשוואה לרשימה נפתחת רגילה.

למה אנו משתמשים ב-HTML יחיד למובייל ודסקטופ?

מבנה HTML יחיד מפשט את התחזוקה: ערוך קובץ אחד — התפריט משתנה בכל מקום. בדסקטופ, אותו HTML עובד כתפריט נפתח בריחוף באמצעות CSS. זה מקצר את נפח הקוד בחצי ומבטל חוסר סנכרון.

יישום שלב-אחר-שלב של תפריט מגה ב-Bitrix

  1. הכנת נתונים: צור רכיב bitrix:menu.sections עם עומק קינון של עד 3 רמות. ודא שמספר הסעיפים אינו עולה על 200 — אחרת יידרש דפדוף בפאנלים. הגדר מטמון עם תג menu.
  2. סימון מבנה: השתמש בתבנית הרכיב כדי להציג פריטים ומערך children. כל פריט מכיל ID, NAME, URL ומערך תמונות.
  3. עיצוב: CSS מחולק ל-mobile-first — עד 1024px ה-drawer מופעל, מ-1024px — תפריט נפתח בריחוף. אנימציות מיושמות באמצעות transform ו-opacity.
  4. JavaScript: מחלקת MegaMenu מנהלת פתיחה/סגירה של ה-drawer, מעברים בין שקופיות והיסטוריית פאנלים.
  5. בדיקות: בדוק פעולה ב-iOS Safari, Chrome Android ו-Samsung Internet. תשומת לב מיוחדת ל-overscroll-behavior ולגובה 100dvh.

מבנה HTML (יחיד לשתי הגרסאות)

<!-- Триггер мобильного меню -->
<button class="menu-toggle" aria-expanded="false" aria-controls="site-nav" aria-label="Меню">
  <span class="menu-toggle__bar"></span>
  <span class="menu-toggle__bar"></span>
  <span class="menu-toggle__bar"></span>
</button>
<nav id="site-nav" class="megamenu" aria-label="Основная навигация" aria-hidden="true">
  <div class="megamenu__backdrop"></div>
  <div class="megamenu__panel megamenu__panel--root is-active" data-level="0">
    <div class="megamenu__head">
      <span class="megamenu__title">Каталог</span>
      <button class="megamenu__close" aria-label="Закрыть меню">×</button>
    </div>
    <ul class="megamenu__list">
      <?php foreach ($arResult['MENU'] as $category): ?>
        <li class="megamenu__item">
          <a href="<?= $category['SECTION_PAGE_URL'] ?>" class="megamenu__link <?= !empty($category['children']) ? 'has-children' : '' ?>" <?php if (!empty($category['children'])): ?> data-panel="cat-<?= $category['ID'] ?>" aria-haspopup="true" <?php endif ?>>
            <?= htmlspecialchars($category['NAME']) ?>
            <?php if (!empty($category['children'])): ?>
              <svg class="megamenu__arrow" aria-hidden="true" width="16" height="16">
                <path d="M6 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5"/>
              </svg>
            <?php endif ?>
          </a>
        </li>
      <?php endforeach ?>
    </ul>
  </div>
  <?php foreach ($arResult['MENU'] as $category): ?>
    <?php if (!empty($category['children'])): ?>
      <div class="megamenu__panel" id="panel-cat-<?= $category['ID'] ?>" data-level="1">
        <div class="megamenu__head">
          <button class="megamenu__back" aria-label="Назад">
            <svg width="16" height="16"><path d="M10 4L6 8l4 4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg>
          </button>
          <a href="<?= $category['SECTION_PAGE_URL'] ?>" class="megamenu__title">
            <?= htmlspecialchars($category['NAME']) ?>
          </a>
        </div>
        <ul class="megamenu__list">
          <li>
            <a href="<?= $category['SECTION_PAGE_URL'] ?>" class="megamenu__link megamenu__link--all">
              Все товары раздела
            </a>
          </li>
          <?php foreach ($category['children'] as $sub): ?>
            <li>
              <a href="<?= $sub['SECTION_PAGE_URL'] ?>" class="megamenu__link">
                <?php if ($sub['MENU_IMAGE_SRC']): ?>
                  <img src="<?= $sub['MENU_IMAGE_SRC'] ?>" alt="" width="40" height="40" loading="lazy">
                <?php endif ?>
                <?= htmlspecialchars($sub['NAME']) ?>
              </a>
            </li>
          <?php endforeach ?>
        </ul>
      </div>
    <?php endif ?>
  <?php endforeach ?>
</nav>

CSS: drawer במובייל, ריחוף בדסקטופ

/* === Мобильные (до 1024px) === */
.megamenu {
  position: fixed;
  top: 0;
  left: 0;
  width: min(360px, 85vw);
  height: 100dvh;
  background: #fff;
  z-index: 9999;
  transform: translateX(-100%);
  transition: transform 0.3s cubic-bezier(.4,0,.2,1);
  overflow: hidden;
}
.megamenu.is-open {
  transform: translateX(0);
}
.megamenu__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.5);
  z-index: -1;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
}
.megamenu.is-open .megamenu__backdrop {
  opacity: 1;
  pointer-events: auto;
}
.megamenu__panel {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: #fff;
  transform: translateX(100%);
  transition: transform 0.25s ease;
}
.megamenu__panel.is-active {
  transform: translateX(0);
}
.megamenu__panel--root {
  transform: translateX(0);
}
.megamenu__panel--root.slide-out {
  transform: translateX(-30%);
}
/* === Десктоп (от 1024px) === */
@media (min-width: 1024px) {
  .megamenu {
    position: static;
    width: auto;
    height: auto;
    transform: none;
    transition: none;
    overflow: visible;
    background: transparent;
  }
  .megamenu__backdrop,
  .megamenu__close,
  .megamenu__back,
  .menu-toggle {
    display: none;
  }
  .megamenu__list {
    display: flex;
    gap: 0;
  }
  .megamenu__panel {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100vw;
    max-width: 1200px;
    transform: none;
    display: none;
    background: #fff;
    box-shadow: 0 8px 24px rgba(0,0,0,.1);
    border-top: 2px solid var(--color-primary);
  }
  .megamenu__item:hover .megamenu__panel,
  .megamenu__item:focus-within .megamenu__panel {
    display: block;
  }
}

JavaScript: ניהול drawer ושקופיות

class MegaMenu {
  constructor(nav) {
    this.nav = nav;
    this.toggle = document.querySelector('.menu-toggle');
    this.panels = nav.querySelectorAll('.megamenu__panel');
    this.stack = [];
    this.bindEvents();
  }

  bindEvents() {
    this.toggle?.addEventListener('click', () => this.open());
    this.nav.querySelector('.megamenu__close')?.addEventListener('click', () => this.close());
    this.nav.querySelector('.megamenu__backdrop')?.addEventListener('click', () => this.close());
    this.nav.querySelectorAll('.has-children').forEach(link => {
      link.addEventListener('click', e => {
        if (window.innerWidth < 1024) {
          e.preventDefault();
          this.goTo(link.dataset.panel);
        }
      });
    });
    this.nav.querySelectorAll('.megamenu__back').forEach(btn => {
      btn.addEventListener('click', () => this.goBack());
    });
    document.addEventListener('keydown', e => {
      if (e.key === 'Escape') this.close();
    });
  }

  open() {
    this.nav.classList.add('is-open');
    this.nav.setAttribute('aria-hidden', 'false');
    this.toggle?.setAttribute('aria-expanded', 'true');
    document.body.style.overflow = 'hidden';
  }

  close() {
    this.nav.classList.remove('is-open');
    this.nav.setAttribute('aria-hidden', 'true');
    this.toggle?.setAttribute('aria-expanded', 'false');
    document.body.style.overflow = '';
    setTimeout(() => this.resetPanels(), 300);
  }

  goTo(panelId) {
    const root = this.nav.querySelector('.megamenu__panel--root');
    const target = this.nav.querySelector(`#panel-cat-${panelId}`);
    if (!target) return;
    root.classList.add('slide-out');
    target.classList.add('is-active');
    this.stack.push(panelId);
  }

  goBack() {
    this.stack.pop();
    const root = this.nav.querySelector('.megamenu__panel--root');
    this.panels.forEach(p => {
      if (!p.classList.contains('megamenu__panel--root')) {
        p.classList.remove('is-active');
      }
    });
    root.classList.remove('slide-out');
    if (this.stack.length > 0) {
      this.goTo(this.stack[this.stack.length - 1]);
    }
  }

  resetPanels() {
    this.stack = [];
    const root = this.nav.querySelector('.megamenu__panel--root');
    root.classList.remove('slide-out');
    this.panels.forEach(p => {
      if (!p.classList.contains('megamenu__panel--root')) {
        p.classList.remove('is-active');
      }
    });
  }
}

document.addEventListener('DOMContentLoaded', () => {
  const nav = document.getElementById('site-nav');
  if (nav) new MegaMenu(nav);
});

השוואה: הפתרון שלנו מול תפריט Bitrix סטנדרטי

מאפיין תפריט סטנדרטי תפריט המגה האדפטיבי שלנו
אדפטיביות לא, ריחוף לא עובד במגע Drawer + שקופיות במובייל, ריחוף בדסקטופ
ביצועים טוען את כל הנתונים בבת אחת, ללא מטמון מטמון מתויג, טעינת תמונות עצלה
נגישות (ARIA) חסר תמיכה מלאה בתכונות ARIA
זמן טעינה ב-3G ~2 שניות ~1.2 שניות (40% מהר יותר)
תמיכה במחוות לא החלקה, הקשה, כפתור חזרה

ביצועים במובייל

  • תמונות תת-קטגוריות: <!-- Триггер мобильного меню --> <button class="menu-toggle" aria-expanded="false" aria-controls="site-nav" aria-label="Меню"> <span class="menu-toggle__bar"></span> <span class="menu-toggle__bar"></span> <span class="menu-toggle__bar"></span> </button> <nav id="site-nav" class="megamenu" aria-label="Основная навигация" aria-hidden="true"> <div class="megamenu__backdrop"></div> <div class="megamenu__panel megamenu__panel--root is-active" data-level="0"> <div class="megamenu__head"> <span class="megamenu__title">Каталог</span> <button class="megamenu__close" aria-label="Закрыть меню">×</button> </div> <ul class="megamenu__list"> <?php foreach ($arResult['MENU'] as $category): ?> <li class="megamenu__item"> <a href="<?= $category['SECTION_PAGE_URL'] ?>" class="megamenu__link <?= !empty($category['children']) ? 'has-children' : '' ?>" <?php if (!empty($category['children'])): ?> data-panel="cat-<?= $category['ID'] ?>" aria-haspopup="true" <?php endif ?>> <?= htmlspecialchars($category['NAME']) ?> <?php if (!empty($category['children'])): ?> <svg class="megamenu__arrow" aria-hidden="true" width="16" height="16"> <path d="M6 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5"/> </svg> <?php endif ?> </a> </li> <?php endforeach ?> </ul> </div> <?php foreach ($arResult['MENU'] as $category): ?> <?php if (!empty($category['children'])): ?> <div class="megamenu__panel" id="panel-cat-<?= $category['ID'] ?>" data-level="1"> <div class="megamenu__head"> <button class="megamenu__back" aria-label="Назад"> <svg width="16" height="16"><path d="M10 4L6 8l4 4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg> </button> <a href="<?= $category['SECTION_PAGE_URL'] ?>" class="megamenu__title"> <?= htmlspecialchars($category['NAME']) ?> </a> </div> <ul class="megamenu__list"> <li> <a href="<?= $category['SECTION_PAGE_URL'] ?>" class="megamenu__link megamenu__link--all"> Все товары раздела </a> </li> <?php foreach ($category['children'] as $sub): ?> <li> <a href="<?= $sub['SECTION_PAGE_URL'] ?>" class="megamenu__link"> <?php if ($sub['MENU_IMAGE_SRC']): ?> <img src="<?= $sub['MENU_IMAGE_SRC'] ?>" alt="" width="40" height="40" loading="lazy"> <?php endif ?> <?= htmlspecialchars($sub['NAME']) ?> </a> </li> <?php endforeach ?> </ul> </div> <?php endif ?> <?php endforeach ?> </nav> , WebP דרך /* === Мобильные (до 1024px) === */ .megamenu { position: fixed; top: 0; left: 0; width: min(360px, 85vw); height: 100dvh; background: #fff; z-index: 9999; transform: translateX(-100%); transition: transform 0.3s cubic-bezier(.4,0,.2,1); overflow: hidden; } .megamenu.is-open { transform: translateX(0); } .megamenu__backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: -1; opacity: 0; pointer-events: none; transition: opacity 0.3s; } .megamenu.is-open .megamenu__backdrop { opacity: 1; pointer-events: auto; } .megamenu__panel { position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain; background: #fff; transform: translateX(100%); transition: transform 0.25s ease; } .megamenu__panel.is-active { transform: translateX(0); } .megamenu__panel--root { transform: translateX(0); } .megamenu__panel--root.slide-out { transform: translateX(-30%); } /* === Десктоп (от 1024px) === */ @media (min-width: 1024px) { .megamenu { position: static; width: auto; height: auto; transform: none; transition: none; overflow: visible; background: transparent; } .megamenu__backdrop, .megamenu__close, .megamenu__back, .menu-toggle { display: none; } .megamenu__list { display: flex; gap: 0; } .megamenu__panel { position: absolute; top: 100%; left: 0; width: 100vw; max-width: 1200px; transform: none; display: none; background: #fff; box-shadow: 0 8px 24px rgba(0,0,0,.1); border-top: 2px solid var(--color-primary); } .megamenu__item:hover .megamenu__panel, .megamenu__item:focus-within .megamenu__panel { display: block; } } , גודל 40×40
  • אנימציות רק באמצעות CSS class MegaMenu { constructor(nav) { this.nav = nav; this.toggle = document.querySelector('.menu-toggle'); this.panels = nav.querySelectorAll('.megamenu__panel'); this.stack = []; this.bindEvents(); } bindEvents() { this.toggle?.addEventListener('click', () => this.open()); this.nav.querySelector('.megamenu__close') ?.addEventListener('click', () => this.close()); this.nav.querySelector('.megamenu__backdrop') ?.addEventListener('click', () => this.close()); this.nav.querySelectorAll('.has-children').forEach(link => { link.addEventListener('click', e => { if (window.innerWidth < 1024) { e.preventDefault(); this.goTo(link.dataset.panel); } }); }); this.nav.querySelectorAll('.megamenu__back').forEach(btn => { btn.addEventListener('click', () => this.goBack()); }); document.addEventListener('keydown', e => { if (e.key === 'Escape') this.close(); }); } open() { this.nav.classList.add('is-open'); this.nav.setAttribute('aria-hidden', 'false'); this.toggle?.setAttribute('aria-expanded', 'true'); document.body.style.overflow = 'hidden'; } close() { this.nav.classList.remove('is-open'); this.nav.setAttribute('aria-hidden', 'true'); this.toggle?.setAttribute('aria-expanded', 'false'); document.body.style.overflow = ''; setTimeout(() => this.resetPanels(), 300); } goTo(panelId) { const root = this.nav.querySelector('.megamenu__panel--root'); const target = this.nav.querySelector(`#panel-cat-${panelId}`); if (!target) return; root.classList.add('slide-out'); target.classList.add('is-active'); this.stack.push(panelId); } goBack() { this.stack.pop(); const root = this.nav.querySelector('.megamenu__panel--root'); this.panels.forEach(p => { if (!p.classList.contains('megamenu__panel--root')) { p.classList.remove('is-active'); } }); root.classList.remove('slide-out'); if (this.stack.length > 0) { this.goTo(this.stack[this.stack.length - 1]); } } resetPanels() { this.stack = []; const root = this.nav.querySelector('.megamenu__panel--root'); root.classList.remove('slide-out'); this.panels.forEach(p => { if (!p.classList.contains('megamenu__panel--root')) { p.classList.remove('is-active'); } }); } } document.addEventListener('DOMContentLoaded', () => { const nav = document.getElementById('site-nav'); if (nav) new MegaMenu(nav); }); ו-loading="lazy" — GPU, ללא reflow
  • <picture> — הפאנל לא גורם לגלילת הגוף
  • transform — גובה נכון בהתחשב בשורת הכתובת של הדפדפן
הגדרת מטמון Bitrix
// В файле .settings.php добавляем тегированный кэш для меню 'cache' => [ 'type' => [ 'class' => '\Bitrix\Main\Data\Cache\Engine\Files', 'settings' => [ 'cache_dir' => '/bitrix/cache', ], ], 'managed' => true, ], 

ברכיב התפריט השתמש ב-opacity עם פרמטר overscroll-behavior: contain => height: 100dvh.

מה כלול בעבודה

אנו מספקים חבילה מלאה: תיעוד אינטגרציה, הוראות לעדכון התפריט ב-Bitrix, גישה למאגר עם קוד, הדרכה למנהלי תוכן וחודש תמיכה לאחר ההשקה. אופציונלית, הגדרת מטמון מתויג לטעינה מהירה יותר.

לוחות זמנים ועלות

תצורה לוח זמנים
Drawer + ניווט החלקה (מובייל) 3–4 ימים
+ תבנית יחידה למובייל/דסקטופ 5–7 ימים
+ אנימציות, מחוות החלקה, נגישות +2–3 ימים

העלות מחושבת באופן אישי לפי גודל הקטלוג ודרישות העיצוב. נבחן את הפרויקט שלך — צור קשר.

טעויות נפוצות ביישום עצמי

  • טיפול שגוי במטמון: התפריט לא מתעדכן לאחר שינוי מבנה הסעיפים. השתמש במטמון מתויג עם תג // В файле .settings.php добавляем тегированный кэш для меню 'cache' => [ 'type' => [ 'class' => '\Bitrix\Main\Data\Cache\Engine\Files', 'settings' => [ 'cache_dir' => '/bitrix/cache', ], ], 'managed' => true, ], .
  • התעלמות מנגישות: חסרים תכונות ARIA פוגעים בקוראי מסך. אנו מוסיפים $APPLICATION->IncludeComponent, CACHE_TAG, menu.
  • גובה פאנל קבוע: במכשירים שונים שורת הכתובת מתנהגת אחרת. אנו משתמשים ב-menu.

המהנדסים שלנו מוסמכים "1C-Bitrix" ויש להם למעלה מ-10 שנות ניסיון ביישום פתרונות ניווט מורכבים. הזמינו פיתוח תפריט מגה אדפטיבי לחנות המקוונת שלכם — שפרו את ההמרה במובייל היום. קבלו ייעוץ.