English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french

简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE คนไทย Français русский

回答

收藏

Telegram 小程序 | TypeScript @telegram-apps/sdk @1.x | 导航 | BrowserNavigator

开源社区 开源社区 3351 人阅读 | 0 人回复 | 2025-02-23

本帖最后由 riyad 于 2025-2-23 19:38 编辑
) g0 U0 I- P! ]5 ~8 N
: d. \5 d4 Y: WBrowserNavigator

BrowserNavigator 是一个使用浏览器历史 API 实现导航的类。 导航器对标准导航器进行了扩展,提供了基本的导航功能和专门用于 浏览器历史记录的逻辑。

8 ?- h; R0 `7 Q3 U6 ~
构造函数

要创建该类的实例,开发人员可以使用该类的构造函数,该构造函数接受历史 项、指向历史项列表条目的光标(索引)以及其他选项:

  1. import { BrowserNavigator } from '@telegram-apps/sdk';# H/ D: ]3 F( o3 x- j9 X

  2. & M4 F. i7 z- f/ m; Z/ T- T
  3. new BrowserNavigator(['/index'], 0);
    8 z) ?8 O2 w0 T/ I& b+ }( }
  4. new BrowserNavigator([{ pathname: '/a' }, { pathname: '/b' }], 1);
复制代码

WARNING

如果传入的历史项目列表为空,或者游标指向一个不存在的项目, 构造函数将抛出一个适当的错误。

postEvent

postEvent 函数允许替换代表 导航器调用 Mini Apps 方法的函数。

  1. const n = new BrowserNavigator(['/'], 0, {
    + v( h6 O0 d- w
  2.   postEvent(method, payload) {
    1 E  d5 c( |% `6 M% s5 n9 J$ W
  3.     console.log('postEvent:', method, payload);. I& Y# g7 m& D  }2 @8 S
  4.   },5 L* p* x. g( R! s
  5. });
复制代码
hashMode

hashMode 属性允许开发人员设置导航器使用的导航模式。 允许的值有:classic(#pathname)、slash(#/pathname)和null。 传递 null 值 会将导航器从 SPA 模式切换到 MPA 模式,使用整个 href 而不是位置的哈希部分 。

默认情况下,导航器使用 classic 模式。

  1. const n = new BrowserNavigator(['/'], 0, {( f& H, _& q) ^5 N- y2 T) q
  2.   hashMode: 'slash'$ r" z$ ^- D) ?: {4 I/ E
  3. });
复制代码
base

base 属性负责解析路由和渲染路径,假定它们必须 以指定的 base 值开始。

  1. const n = new BrowserNavigator(['/'], 0, {
    6 A! ]0 E- ?( [
  2.   hashMode: null,/ t# Z, U4 X  q- @7 Z" O" y0 J
  3.   base: '/solidjs-template',
    ! f$ {% ?1 q/ y$ x+ _9 v
  4. });# k9 O- e$ _+ B7 y4 t6 k
  5. + x% Z; `4 t/ a* O
  6. n.renderPath('/home'); // -> /solidjs-template/home
复制代码

该值只有在使用 MPA 模式时才有用。

% s; I7 k) a  f' O& Z- D! Y( R" }
createBrowserNavigatorFromLocation

为了简化创建 BrowserNavigator 的过程,软件包提供了 createBrowserNavigatorFromLocation 方法。 根据所传递的选项(即前面描述的构造函数 选项),它会解析当前位置并创建 一个 BrowserNavigator 实例。

  1. import { createBrowserNavigatorFromLocation } from '@telegram-apps/sdk';/ C7 H. B0 B8 Z+ O# t

  2. ; s+ [% Y# J2 f+ @2 _
  3. const navigator = createBrowserNavigatorFromLocation({
    ; k6 I4 j# M8 ~3 ?8 z) w* T
  4.   hashMode: 'slash',
    . A3 `; T$ R) F  R0 n
  5. });
复制代码
initNavigator

initNavigator 函数负责使用先前保存的导航器状态创建一个 BrowserNavigator 实例 。 它还会自动将其保存在会话存储 中,以便将来恢复状态。

该函数接受会话存储密钥名称(其中将包含导航器状态)和 可选对象(代表导航器构造器选项)。

  1. import { initNavigator } from '@telegram-apps/sdk';
    & u- l6 g. F6 d, A( I4 e

  2. ; V& ?8 Z3 n, j  X1 k+ V
  3. const n = initNavigator('app-navigator-state', {9 @% x9 L0 s8 a
  4.   hashMode: 'slash',
    . y9 R9 U. O) j2 l9 D9 b
  5. });
复制代码

如果函数无法使用会话存储恢复导航器,它将 使用 createBrowserNavigatorFromLocation 函数。

9 X7 M+ J5 J1 q2 L: {
连接

创建 BrowserNavigator 实例并使用其方法不会自动更新 浏览器历史记录。 要做到这一点,开发人员应将其附加到系统中。 在此之前, 导航器只会更新其内部状态,并通知所有订阅者有关更改。 手动 附件是必要的,以防止出现创建多个此类导航器的情况,即 每个导航器都试图用其内部状态控制浏览器历史记录。

为了让导航器控制浏览器的历史记录,需要通过 attach方法来附加历史记录:

  1. import { BrowserNavigator } from '@telegram-apps/sdk';, p( P' j2 V( n4 g' ^" |* X0 X

  2. ; x( s' Q6 h' G; S7 l. t
  3. const navigator = new BrowserNavigator(...);; m. m3 a* E: L: Z6 d
  4. 0 R5 l; t6 R+ }, N
  5. navigator.attach().then(() => {
    * @  I. {1 v( v4 c" u  J7 y
  6.   console.log('Attachment completed');; {$ c  ?6 n3 l' _1 ~; y
  7. });
复制代码

该方法返回一个承诺,当附件完成时,该承诺将被解析。

要阻止导航器修改浏览器的历史记录,请使用 detach 方法:

  1. navigator.detach();
复制代码
导航

导航器为开发人员提供了一系列操作导航历史记录的方法。

back

历史倒退 1.

  1. navigator.back();
复制代码
forward

历史向前推移 1.

  1. navigator.forward();
复制代码
go

按指定的 delta 值更改当前活动的历史项目索引。 如果更新后的索引指向一个不存在的历史项,该方法不会更改 索引。 在指定 fit 参数之前, 。 如果指定了它,该方法会调整传入的 delta,使 适合[0, history.length - 1]范围。

  1. // Goes back in history by 3 entries.
    # u, ]  V/ S0 v- V+ [- O
  2. navigator.go(-3);: K1 [: T# }( ]

  3. : n. h5 v( s' p. b! J1 [
  4. // Will surely do nothing in real-world applications.
    : l, ^# e8 I2 N
  5. navigator.go(-100000);
    # P" G& y: ~8 ^- f

  6. $ Y/ e; ^) N3 ^6 c9 `
  7. // Will go back to the oldest entry.
    5 H. V! Y/ G1 T# l
  8. navigator.go(-100000, true);
    - N" a# C' \) _

  9. 7 E- F4 E2 A; k8 {
  10. // Will go forward to the newest entry.
    ) T3 D( O9 Z2 t, U
  11. navigator.go(100000, true);
复制代码
goTo

转到指定的索引。 如果传递的索引超出范围,该方法将不起任何作用。

如果指定了 fit 选项,并且索引超出了界限,那么它将被调整为最接近 的界限。

  1. // Will do nothing.; F+ X# y. b$ o# p6 Q: g
  2. navigator.goTo(-1);
    + C: P0 x  O1 m  F6 d8 X, n9 M# U

  3. ) W" T8 R; `* ?# U% k
  4. // Will go to the oldest entry.
    % p6 L5 ~5 v* q9 w/ J
  5. navigator.goTo(0);/ L5 \2 s1 q+ g

  6. $ e3 f8 w9 a( C5 z7 L
  7. // Will surely do nothing in real-world applications.
    ! `+ M) W# R8 l7 X
  8. navigator.goTo(100000);2 {# \# W1 p; {4 _9 C; P4 ?+ p

  9. # z0 T' ~1 |6 g" I1 F. ]
  10. // Will go back to the oldest entry.% `* T' q* l7 ^" Y5 o6 G
  11. navigator.goTo(-100000, true);
    0 K+ V* h3 F: {  H7 t6 _

  12. 5 _" h. O: y) b1 y
  13. // Will go forward to the newest entry.
    0 _5 O& c: w+ w
  14. navigator.goTo(100000, true);
复制代码
push

推送新的历史项目。 该方法用 推送的条目替换当前条目之后的所有条目。 请注意,传递的项目总是相对的。 如果要将其用作绝对值,请使用 / 前缀。 例如:/absolute, { pathname: '/absolute' }.

要创建最终路径,导航器会使用 URL 类构造函数中的一种方法,根据当前路径解析 路径。

在接下来的示例中,我们假设当前条目为 /home/blog。

绝对路径名

指定绝对路径不会将其与当前路径合并,而是使用 的完整路径:

  1. navigator.push('/database');5 M  X: F5 Q. q  l
  2. // or5 w$ p( }, S7 S3 Z: _4 V
  3. navigator.push({ pathname: '/database' });
    9 x. c& T7 @. @5 \9 f% @; `
  4. // Navigator will add a new entry, and the current one becomes /database
复制代码
相对路径名

指定相对路径名的行为与浏览器中的行为相同:

  1. navigator.push('license');* {( @, J& M# A' ~, O8 t$ g
  2. // or" |; Z; [; [. _" U$ {- k
  3. navigator.push({ pathname: 'license' });
    3 E& Y; [" M% H/ L9 t
  4. // Navigator will add a new entry, and the current one becomes /home/license
复制代码
搜索

要添加带查询参数的条目,请使用问号 (?) 或 search 条目属性:

  1. navigator.push('?id=1');+ ]. ?* L5 s9 e! H8 V9 s
  2. // or' M2 ^; r/ G% G" C  e  G
  3. navigator.push({ search: '?id=1' });
    9 x) f) h/ d* I+ p' d1 E+ E* r
  4. // Navigator will add a new entry, and the current one becomes /home/blog?id=1
复制代码

INFO

推送带有不同查询参数或缺少查询参数的新路径名将导致当前 查询参数丢失。 为防止出现这种情况,开发人员应再次通过它们。

Hash

添加条目的散列部分的逻辑与 search相同,但使用的是 hashtag (#) 和 hash 条目属性。

  1. navigator.push('#introduction');
    " W$ F! ?3 C. y2 K# m
  2. // or
    ' f& g7 \9 C2 C9 b" o1 {
  3. navigator.push({ hash: '#introduction' });
    - Z/ i+ R; j' s; x+ t6 ~( ~; X
  4. // Navigator will add a new entry, and the current
    : S' S# T7 [+ j- H8 m
  5. // one becomes /home/blog#introduction
复制代码
replace

replace 方法的功能与 push 方法类似,但它不会创建新的 条目。 相反,它取代了当前的版本。

属性index

当前历史光标。

  1. const navigator = new BrowserNavigator(['/'], 0);
    0 U* B/ t7 r/ y0 v
  2. navigator.index; // 0
复制代码
id

当前历史项目标识符。 如果没有明确指定 id,导航器会自行生成。

  1. const navigator = new BrowserNavigator(['/'], 0);
    2 l0 G3 b/ S1 E# v) f( Q5 {
  2. navigator.id; // 'abb721'; h* j# _( d( S' I4 s( \
  3. % d5 N. u+ _0 G' L1 i3 Y) G1 s" _
  4. const navigator2 = new BrowserNavigator([{ id: 'a', pathname: '/' }], 0);7 u; v3 Z2 {  U( U, ?6 `/ F# B
  5. navigator2.id; // 'a'
复制代码
hash

当前历史项目哈希值。

  1. const navigator = new BrowserNavigator(['/#jungle'], 0);
    1 T( b! X& a6 P8 R  D, S
  2. navigator.hash; // "#jungle"
复制代码
hasPrev

如果导航器在当前项目之前有项目,则为 True。

  1. const navigator = new BrowserNavigator(['/'], 0);4 a6 k! u! |# c9 y& q5 W# O
  2. navigator.hasPrev; // false* a9 a& O. g, C9 ]8 }
  3. 2 i; J: \9 `2 A5 F
  4. const navigator2 = new BrowserNavigator(['/a', '/b'], 1);
    1 H3 B- \/ d: k9 f5 y' x) _
  5. navigator2.hasPrev; // true
复制代码
hasNext

如果导航器在当前项目之后还有项目,则为 True。

  1. const navigator = new BrowserNavigator(['/'], 0);
    2 Z& i+ j3 d- v6 K' d7 n) \  G
  2. navigator.hasNext; // false
    / n8 Q2 b: O  u) O2 w- j

  3. 0 M1 b$ U4 R6 J' ~) N
  4. const navigator2 = new BrowserNavigator(['/a', '/b'], 0);0 ^! D9 b+ [! g% D: q& y
  5. navigator2.hasNext; // true
复制代码
history

安全修改导航历史记录。

  1. const navigator = new BrowserNavigator(['/a#a-hash', '/b?b-query=1'], 0);: [+ f! f9 W# _9 }( t# U8 l
  2. navigator.history;, w: @* `2 `. \* E$ b; r# ]
  3. // [
    0 g. p, }) R# O' X
  4. //   { pathname: '/a', hash: '#a-hash', search: '', id: 'ahJJ123' },
    - p# I. E3 T# e" k5 O
  5. //   { pathname: '/b', hash: '', search: '?b-query=1', id: 'dd82' },
    3 w% i, }/ s- q: ^( N# S
  6. // ]
复制代码
path

路径,包括路径名、搜索和哈希值。

  1. const navigator = new BrowserNavigator([{2 G8 G6 h' A! v% s4 P$ C* D
  2.   pathname: '/a',: s1 U( E% C6 E9 z9 H, a
  3.   hash: '#mama',6 F! |* }5 S; j* x" D" r) A
  4.   search: '?joe',$ V1 V4 o) T! O3 Q, S# q2 y
  5. }], 0);
    / N6 ~5 U! C: d! l" f6 ]5 O
  6. navigator.path; // '/a?joe#mama'
复制代码
pathname

当前路径名。 总是以斜线开头。

  1. const navigator = new BrowserNavigator([{/ U  G4 F" }. f9 e1 j4 M( o8 j
  2.   pathname: '/a',
      x4 N* e# G$ z, S0 }7 a
  3.   hash: '#mama',
    # v5 ^; o" o0 |) t% C  Q1 h
  4.   search: '?joe',& p* ?2 ]5 k4 E7 H
  5. }], 0);
    # `) E& f$ `2 O. I. L
  6. navigator.pathname; // '/a'
复制代码
search

当前查询参数。

  1. const navigator = new BrowserNavigator([{
    7 ]0 ^3 n+ H( d! p+ W+ |  ]
  2.   pathname: '/a',; Y* ]. Y. f7 }4 \1 e0 B5 {
  3.   hash: '#mama',
    0 S9 X+ r& f* l% _2 Y0 Z
  4.   search: '?joe',
    + C" M8 w9 k, u* I$ U9 b
  5. }], 0);
    " X' Y5 Z, Y. Y% M$ o
  6. navigator.search; // '?joe'
复制代码

- i" c& A+ d" |; g& Dstate

当前历史项目状态。

  1. const navigator = new BrowserNavigator([{ state: 'test' }], 0);
    - h" J6 u) J# G9 v
  2.   y; J! O$ Y3 k  t* p  C

  3. . L5 t+ q+ x! d9 X9 A1 W* ~' V
  4. navigator.state; // 'test'
复制代码
7 ~' ~& Z. }9 F, @  x6 t
事件

BrowserNavigator 提供了 on 和 off 方法来管理事件监听器。 目前,可用于监听的 事件只有 change。 change 事件的有效载荷是一个对象,包含 以下属性:

  • navigator: BrowserNavigator: 相关导航器实例。
  • delta: number: 当前活动项目光标的 delta。
  • from: { pathname: string; hash: string; search: string; id: string; state?状态 }: 以前活动的历史项目。
  • to:结构与 from 相同的对象,代表当前活动的历史项目。( e+ i0 q% v( h& m+ c5 A
& U/ [- [0 L  h3 T
添加事件监听器

要为 change 事件添加事件监听器,请使用 on 方法:

  1. const removeEventListener = navigator.on('change', (ev) => {
    , K+ G6 C* Q+ O
  2.   console.warn('Navigation state changed', ev);' O2 W3 R3 n, U$ Q, g+ S; b( S
  3. });
复制代码
删除事件监听器

要移除事件监听器,请调用 on 方法返回的函数:

  1. removeEventListener();
复制代码
或者,您也可以使用导航器的 off 方法:
3 z! f  V9 ]0 @- o5 M& q! w5 U3 |
  1. function listener(ev) {
    " x; W1 |- ^" t1 w
  2.   console.warn('Navigation state changed', ev);
    9 T/ x+ W. J, o5 m; b" u2 h4 V6 S% _
  3. }
    - N. ]3 Q+ v; M! O% X" q2 _
  4. navigator.on('change', listener);
    : l1 B1 E& F5 O6 V# s/ n$ `5 K
  5. navigator.off('change', listener);
复制代码
其他方法renderPath

renderPath 方法将导航器的 base 属性与给定的路径数据相结合,并应用 导航器的导航模式。 该方法以字符串形式返回完全渲染的路径。

  1. const n = new BrowserNavigator(['/'], 0, {: M  n; J" {/ G
  2.   hashMode: 'slash',
    * B1 v9 Q2 b( ]5 A% }. V0 W5 {. m3 g
  3. });7 f$ L$ F0 R/ k) e( }
  4. n.renderPath('/test'); // '#/test'- e, U' i8 f' D0 e% h

  5. 5 Z0 u- \( \7 W! W
  6. const n2 = new BrowserNavigator(['/'], 0, {0 d$ q/ V* p% ?$ b3 `5 _; I
  7.   base: '/my-base',' _+ p# l" C1 r/ g% y
  8.   hashMode: 'slash',& g0 p* B6 p  h- a" |
  9. });2 b$ o7 Y2 B, ?2 l  t
  10. n2.renderPath('/test'); // '#/my-base/test'
    3 M( d8 D  `$ z5 o/ f: b% m1 P
  11. ( e9 r; E& c* N0 K
  12. const n3 = new BrowserNavigator(['/'], 0, {* F9 _  E% @1 A' @9 }/ {, f! {
  13.   base: '/my-base',
    2 C+ B: l0 J5 \3 a7 T! Y
  14.   hashMode: null,2 k) c) C9 J; X: q
  15. });0 W* ^! k% q" [1 N; ^- t- E
  16. n3.renderPath('/test'); // '/my-base/test'
复制代码
parsePath

parsePath 方法会根据当前导航类型解析所提供的路径,并以对象形式返回 。 这种方法有助于了解导航器如何解释给定路径。

) p: \( E9 \7 V( ~& `) S
  1. const n = new BrowserNavigator(['/'], 0);
    1 E. j! k6 l! x: g
  2. n.parsePath('/test');
    ( A8 `8 E# V9 K8 Q% c6 [& a/ h0 f6 Q
  3. // { pathname: '/', search: '', hash: '' }
    3 c8 p+ ~  g% \  v2 ^2 j& B# ?
  4. 6 U$ k- M' c  K% m. K: T! u, l4 D, y1 R
  5. n.parsePath('/test#abc');
    - y' u3 Q7 ^0 y! j9 \9 u
  6. // { pathname: '/abc', search: '', hash: '' }
    : i! R) Z) H# {- [2 L& k5 w

  7. 4 w  L2 g. E# Z" B$ `4 c' L
  8. n.parsePath('/test#abc?query#some-hash');
    # o; w1 l$ P% M& B. H& i" ]" r) T
  9. // { pathname: '/abc', search: '?query', hash: '#some-hash' }" s; O4 t, `; x7 \/ ^
  10. # L' z' h$ l( _  O
  11. const n2 = new BrowserNavigator(['/'], 0, { hashMode: null });# {: p3 j$ U' |% E" h
  12. n2.parsePath('/test');
    6 E2 O. A: E: F
  13. // { pathname: '/test', search: '', hash: '' }& J9 W/ v- q0 M9 ]0 ?$ ~

  14. $ v8 C! A3 Z/ n% r
  15. n2.parsePath('/test#abc');
    - B% @8 Y: X1 r+ v% k3 b/ A
  16. // { pathname: '/test', search: '', hash: '#abc' }- T/ `* v2 b& i* |& U
  17. 2 w0 |) u0 V3 o: s: x* C) G, @8 L
  18. n2.parsePath('/test?query#abc');; [$ \1 v2 t* q2 |  ~, p7 c
  19. // { pathname: '/test', search: '?query', hash: '#abc' }
复制代码
# G$ B4 Q) F- P; }4 y

5 H* r5 C0 Q% y5 }0 t
# w5 a) r' W* C+ p5 b4 t% _' W" c0 `$ e
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则