تخطَّ إلى المحتوى

breadcrumb مسار التنقل —— تنقل

مسار التنقل هو مؤشر المسار الذي يجيب عن «أين أنا وكيف وصلت إلى هنا»: الرئيسية / الإعدادات / الأمان / التحقق بخطوتين. وهو أخفّ من القائمة——فيعبّر عن مسار التسلسل الهرمي فقط ولا يحمل التنقّل الرئيسي؛ وأضعف من شريط الخطوات——فلا يعبّر عن تدفّق متسلسل، بل عن علاقة احتواء. وعندما يصبح التسلسل الهرمي عميقًا يطول المسار، وكان الطيّ هو خوارزميته الجوهرية.

  • لتطبيق <LhBreadcrumb> / <LhBreadcrumbItem>: مسار التسلسل الهرمي في أنظمة الإدارة، ومسار تصنيف موقع التوثيق، ومسار تصنيف المنتجات.
  • السيناريوهات التي تحتاج إلى تحديد الموضع الحالي وتوفير مدخل للرجوع درجة درجة.
  • لا ينبغي استخدامه: التنقّل الرئيسي (استخدم menu)؛ تدفّق الخطوات (استخدم steps)؛ تبديل المحتوى من نفس المستوى (استخدم tabs)؛ المسارات ذات المستوى الواحد (هذه ليست مسار تنقّل، بل عنوان صفحة).
import {
getBreadcrumbItemClassNames,
getEllipsisBeforeIndex,
getCollapsedHiddenIndexes,
getBreadcrumbItemAria,
} from '@lh-ui/share/core/breadcrumb'
import type { LhBreadcrumbItemState, LhBreadcrumbCollapseState } from '@lh-ui/share/core/breadcrumb'

الطيّ يحتفظ بالعنصر الأول: قاعدة getEllipsisBeforeIndex هي «العنصر الأول + علامة الحذف + آخر عناصر maxItems-1». يبقى العنصر الأول دائمًا——فهو مرساة «العودة إلى المستوى الأعلى» (غالبًا «الرئيسية»)، وحذفه يحرم المستخدم من القدرة على العودة إلى الجذر. وهذا الانتداب في الأهمية يماثل «الاحتفاظ بالعنصر الأخير» (الموضع الحالي).

أمام أي عنصر توضع علامة الحذف: ما يُرجع هو فهرس أول عنصر مرئي بعد علامة الحذف (total - (maxItems - 1))، وتُدرج طبقة واجهة المستخدم عنصر علامة الحذف أمام هذا الموضع. وعند عدم الطي يُرجع -1——لاحظ أن -1 هي قيمة حارسة تعني «لا طيّ»، وليست فهرسًا صالحًا.

maxItems < 2 لا يُطوي: يجب عرض العنصر الأول + عنصر واحد تالٍ على الأقل ليكون للطيّ معنى. عند maxItems: 1 أو أقل يُرجع -1——وهذا تصميم دفاعي لمنع انطواء مسار التنقّل إلى علامة حذف واحدة عند تكوين قيمة خاطئة.

علاقة getCollapsedHiddenIndexes بفهرس علامة الحذف: ما يُخفى هو «العناصر بين العنصر الأول وعلامة الحذف»، أي نصف المجال المفتوح [1, ellipsisIndex)——يُحتفظ بالعنصر الأول (الفهرس 0) وبكل العناصر بعد موضع علامة الحذف. وتُستعمل الدالتان معًا: يُؤخذ موضع علامة الحذف أولًا، ثم تُحسب مجموعة العناصر المخفية.

العنصر الأخير aria-current=“page”: العنصر الأخير هو «الصفحة الحالية»، وaria-current="page" هي الدلالة المعيارية في WAI-ARIA——يُعنون قارئ الشاشة «الصفحة الحالية»، وهو أدقّ من تلميح نصي. ولا تُخرج العناصر غير الأخيرة أي سمات aria (تحمل روابط <a> الأصلية دلالة الرابط).

الدالة التوقيع الناتج الدور
getBreadcrumbItemClassNames (state: LhBreadcrumbItemState) => string[] أسماء الأصناف حالة الرابط + العنصر الأخير
getEllipsisBeforeIndex (state: LhBreadcrumbCollapseState) => number فهرس / -1 موضع علامة الحذف
getCollapsedHiddenIndexes (state: LhBreadcrumbCollapseState) => number[] مجموعة فهارس مخفية عناصر الطيّ المخفية
getBreadcrumbItemAria (isLast: boolean) => LhAriaAttrs حزمة aria aria-current للعنصر الأخير
export interface LhBreadcrumbItemState {
isLast: boolean // هل هو العنصر الأخير (الصفحة الحالية)
isLink: boolean // هل يُصرَّر كرابط (يُمرَّر to وليس العنصر الأخير)
}
export interface LhBreadcrumbCollapseState {
total: number // إجمالي عدد العناصر
maxItems: number // أقصى عدد عناصر مرئية (شامل علامة الحذف)؛ أقل من 2 يعني عدم الطيّ
}
getBreadcrumbItemAria(true) // { 'aria-current': 'page' }
getBreadcrumbItemAria(false) // {}
  • aria-current=“page” فقط للعنصر الأخير: العناصر الوسيطة روابط قابلة للنقر، ولا تحتاج إلى وسم current. وعند دخول الصفحة ينطق قارئ الشاشة «الرئيسية، رابط / الإعدادات، رابط / الأمان، رابط / التحقق بخطوتين، الصفحة الحالية»——فيُنقل المسار والموضع دفعة واحدة كاملًا.
  • استخدم <a> الأصلي لا قفز JavaScript: عندما يكون العنصر الوسيط رابطًا حقيقيًا استخدم <a href="...">——يدعم الفتح في نافذة جديدة بزر الماوس الأوسط، ونسخ الرابط بزز اليمين، والعمل بدون JavaScript. ويُعترض النقر لتنفيذ التوجيه من جهة العميل في طبقة واجهة المستخدم (@click.prevent) مع الاحتفاظ بـ href. ويوضّح تعليق getBreadcrumbItemAria هذه النقطة: عندما يكون هناك رابط، تحمل عنصر a الأصلي دلالة role، فلا حاجة لإخراجها من الدالة.
  • إمكانية الوصول لزر علامة الحذف: علامة الحذف بعد الطيّ تكون عادةً قابلة للنقر لتوسيع المسار كاملًا. وهي عنصر تحكّم يحتاج إلى aria-label="توسيع المسار كاملًا" (أو aria-expanded للتعبير عن حالة التوسيع)——وإلا فستكون زرًا بلا اسم.
  • تغليف nav + aria-label: يُستحسن لمسار التنقّل <nav aria-label="مسار التنقّل">——إذ قد يكون في الصفحة عدة عناصر nav (التنقّل الرئيسي، تنقّل الترقيم)، فيميّزها aria-label.
  • الفواصل تزيينية: الفاصل / أو » زخرفة خالصة، فليُجعل aria-hidden أو يُنفَّذ بعنصر CSS الزائف، لتفويت قراءة كل فاصل على حدة من قارئ الشاشة.
import {
getEllipsisBeforeIndex, getCollapsedHiddenIndexes, getBreadcrumbItemAria,
} from '@lh-ui/share/core/breadcrumb'
getEllipsisBeforeIndex({ total: 6, maxItems: 4 }) // 3 (تُدرج علامة الحذف أمام الفهرس 3)
getEllipsisBeforeIndex({ total: 4, maxItems: 4 }) // -1 (الإجمالي <= maxItems، لا طيّ)
getEllipsisBeforeIndex({ total: 6, maxItems: 1 }) // -1 (maxItems < 2 لا يُطوي)
getEllipsisBeforeIndex({ total: 6, maxItems: 2 }) // 5 (يُحتفظ بالعنصر الأول + آخر عنصر)
getCollapsedHiddenIndexes({ total: 6, maxItems: 4 }) // [1, 2] (بين العنصر الأول وعلامة الحذف)
getCollapsedHiddenIndexes({ total: 4, maxItems: 4 }) // [] (لا طيّ)
// طبقة واجهة المستخدم: تصيير الطيّ (تتحكم حالة محلية في التوسيع)
const expanded = ref(false)
const items = ['الرئيسية', 'النظام', 'الإعدادات', 'الأمان', 'الحساب', 'التحقق بخطوتين']
const ellipsisIndex = computed(() =>
getEllipsisBeforeIndex({ total: items.value.length, maxItems: props.maxItems ?? 4 }),
)
const hidden = computed(() =>
expanded.value ? [] : getCollapsedHiddenIndexes({ total: items.value.length, maxItems: props.maxItems ?? 4 }),
)
<!-- Vue3 -->
<template>
<nav aria-label="مسار التنقّل">
<LhBreadcrumb :max-items="4">
<LhBreadcrumbItem to="/">الرئيسية</LhBreadcrumbItem>
<LhBreadcrumbItem to="/system">النظام</LhBreadcrumbItem>
<LhBreadcrumbItem to="/system/security">الأمان</LhBreadcrumbItem>
<LhBreadcrumbItem>التحقق بخطوتين</LhBreadcrumbItem>
</LhBreadcrumb>
</nav>
</template>
// React: تُشتق بيانات المسار عادةً من جدول التوجيه (useMatches / route meta مخصص)،
// بدلاً من الإعلان اليدوي عن كل عنصر——فمراسلة مسار التنقّل بالتوجيه عقد عمل
// uniapp: `<navigator>` مكوّن القفز الأصلي؛ ولا يوجد دلالة `<nav>` في جانب التطبيقات
// المصغّرة، واستخدام view + aria-label لا يجدي (نظام قارئ الشاشة في التطبيقات المصغّرة
// مختلف)——وهذا مقبول، فالمهم الحفاظ على بنية DOM نفسها
اسم الصنف الدلالة
.lh-breadcrumb الحاوية (inline-flex)
.lh-breadcrumb__item عنصر واحد
.lh-breadcrumb__item--link حالة الرابط (يتغيّر لونه عند hover)
.lh-breadcrumb__item--last العنصر الأخير (الصفحة الحالية، عريض أو باللون الأساسي)
.lh-breadcrumb__separator الفاصل (عادةً عنصر CSS زائف)
.lh-breadcrumb__ellipsis علامة الحذف (قابلة للنقر للتوسيع)

لون النص --lh-text-regular، ولون الرابط عند hover --lh-primary-color، والعنصر الأخير --lh-text-primary؛ وحجم الخط --lh-font-size-base.

  • maxItems يشمل علامة الحذف: يُعرض عند maxItems: 4 فعليًا «العنصر الأول + علامة الحذف + آخر 3 عناصر» = 5 عناصر، وعدد العناصر النصية المرئية 4. عيّن القيمة وفق العناصر النصية المرئية.
  • ديناميكية الطيّ: يتغيّر طول المسار مع عمق التنقّل (total الخاص بـ getEllipsisBeforeIndex ديناميكي)، بينما يكفي تثبيت maxItems——فلا حاجة للحكم يدويًا متى يُطوي، إذ تتولّى الدالة ذلك تلقائيًا.
  • تفاعل توسيع علامة الحذف: طريقتان شائعتان——① النقر على علامة الحذف للتوسيع في الموضع (تبديل حالة expanded)؛ ② النقر لعرض popover يسرد العناصر المخفية. الأولى أبسط والثانية توفر المساحة، فاختر وفق عمق المسار.
  • مصدر بيانات المسار: يُشتق مسار التنقّل عادةً من جدول التوجيه لا يُكتب يدويًا——يُكوَّن title في meta لكل مسار، وتجمع طبقة المكوّن meta الخاص بمسارات الأسلاف للمسار الحالي. وcore تهتم بخوارزمية التصيير فقط، أما تكامل التوجيه فمن شأن طبقة واجهة المستخدم.
  • العنصر الأخير لا يُصرَّر كرابط: لا معنى لإشار الصفحة الحالية إلى نفسها (وisLink: false). ولاحظ أن صنف --link الخاصة بـ getBreadcrumbItemClassNames يتحكم بها isLink، فالعنصر الأخير يحرم منها بطبيعة الحال.
  • حذف العناوين طويلة جدًا: عندما يكون عنوان مستوى واحد طويلًا جدًا استخدم text-overflow: ellipsis في CSS (أنماط طبقة واجهة المستخدم)، وهذا «حذف» مختلف عن طيّ المسار—— الطيّ يقلّل عدد المستويات، وCSS تقلّص عرض مستوى واحد.
  • لا تستخدم مسار التنقّل كتنقّل رئيسي: هو وسيلة تحديد موضع مساعدة، ويبقى القائمة المدخل الرئيسي. وعلى الهاتف حيث المساحة محدودة يُحذف مسار التنقّل غالبًا أو يُحتفظ فقط بزر «رجوع».
@lh-ui/share/core/breadcrumb → getEllipsisBeforeIndex( )
返回值
(填好参数后点运行)

Copyright © 2024-2026 FengMo WenXue