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

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

回答

收藏

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

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

本帖最后由 riyad 于 2025-2-23 19:38 编辑
& C$ z+ A+ v9 U, }9 J* h/ B/ k$ X
& `7 W. L+ _' ^  vBrowserNavigator

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


) w! H- Q, M# q构造函数

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

  1. import { BrowserNavigator } from '@telegram-apps/sdk';. S- g# y. Q% k1 w: [) i5 K

  2. 1 B/ @( i" V4 ^8 Y$ _+ A
  3. new BrowserNavigator(['/index'], 0);
    % ]1 ?7 ?( T" K* [# [% C
  4. new BrowserNavigator([{ pathname: '/a' }, { pathname: '/b' }], 1);
复制代码

WARNING

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

postEvent

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

  1. const n = new BrowserNavigator(['/'], 0, {2 F; n. t, E/ h6 s8 e! k8 u4 H
  2.   postEvent(method, payload) {
    + c' b; M4 T: r3 b+ R  p5 P
  3.     console.log('postEvent:', method, payload);$ K" t0 D0 C+ V1 B: T8 ]2 ~' ~
  4.   },
    8 L- N1 R/ Z; U3 K
  5. });
复制代码
hashMode

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

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

  1. const n = new BrowserNavigator(['/'], 0, {
    % y9 K3 {) ]0 N& X! B2 o
  2.   hashMode: 'slash'
    : h; N6 {1 R& j; P( v: B. Z: u
  3. });
复制代码
base

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

  1. const n = new BrowserNavigator(['/'], 0, {
    ) g5 ]$ j! L8 m# f
  2.   hashMode: null,7 V( g5 \% e, O: x
  3.   base: '/solidjs-template',( `' d/ ~. b8 m! D( f5 q( u& n
  4. });- i" I- g* R6 Y6 L9 ~) k
  5. . g8 u, C5 J" Y$ O; ?. Q
  6. n.renderPath('/home'); // -> /solidjs-template/home
复制代码

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

6 t. Y3 N( }" e0 {; K/ F+ e
createBrowserNavigatorFromLocation

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

  1. import { createBrowserNavigatorFromLocation } from '@telegram-apps/sdk';' `+ R: e, p* c: S  d! O

  2. * i6 q7 W# V) r" ~3 G. i
  3. const navigator = createBrowserNavigatorFromLocation({7 m# ?% J3 z% R4 {7 ~4 I
  4.   hashMode: 'slash',: N, G+ Z: R9 r. D7 q% g; j
  5. });
复制代码
initNavigator

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

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

  1. import { initNavigator } from '@telegram-apps/sdk';2 P3 S/ |* {! W! b8 T: C
  2. - d3 g/ U! a, U
  3. const n = initNavigator('app-navigator-state', {2 Q9 w1 D1 O( Q
  4.   hashMode: 'slash',' L5 h6 m% @4 r, R+ O& t
  5. });
复制代码

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

. x3 h5 K6 ~2 M1 v8 N2 `" M. ^: N
连接

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

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

  1. import { BrowserNavigator } from '@telegram-apps/sdk';2 \1 E- `* Z# M/ }/ `! _- T* z- g

  2. ! R" T5 A; Y9 s) H" S0 F
  3. const navigator = new BrowserNavigator(...);/ z( z7 e; J1 n3 U0 |4 S& Q- K
  4. 8 D' w1 h( u5 U3 U7 K, ?; J5 |; a1 q
  5. navigator.attach().then(() => {
    6 [8 B- M' O3 y3 D8 Y
  6.   console.log('Attachment completed');
    / B) w7 ~2 s% b& s1 A: a: c4 ^
  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: w' a4 _: G9 Q
  2. navigator.go(-3);! ?, g- Z- ^8 c3 ~' ^

  3. # i4 u+ i" i' ]" M% J+ b& z1 C7 P
  4. // Will surely do nothing in real-world applications.) ^) ^1 v& }8 E8 N  A
  5. navigator.go(-100000);
    5 L* E$ L4 v" l
  6. & p- u# o7 O+ }" G) z
  7. // Will go back to the oldest entry.- K) ^% `$ K0 a2 W8 ~' D' L7 Q- P
  8. navigator.go(-100000, true);/ h$ o! e1 ?, c2 G! w- w) d9 C, H( I1 T

  9. : s& K& t' I+ V) t/ R; Q/ n
  10. // Will go forward to the newest entry.# u' r3 v( ~8 @' r
  11. navigator.go(100000, true);
复制代码
goTo

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

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

  1. // Will do nothing.
    2 F! G; ]: J7 K# T6 Y
  2. navigator.goTo(-1);2 }. O/ {! y$ G" p* Z$ N( \

  3. + k: E! C" l, x$ V) s' ~' |6 h
  4. // Will go to the oldest entry.$ f( Z- U  _: @  h0 V
  5. navigator.goTo(0);4 Q9 B* Y, T& h% g+ ?* r7 C# M

  6. 4 F- d5 u5 W6 Z+ ~! D. o
  7. // Will surely do nothing in real-world applications.. u. C. u/ \# w. k0 C
  8. navigator.goTo(100000);/ p/ Z3 u7 k. x9 j1 I! ?

  9. 2 E, p# U4 ^% u( J
  10. // Will go back to the oldest entry.
    ! \. V; Q' L7 _% R; r4 Y, F/ x
  11. navigator.goTo(-100000, true);6 M0 L2 M/ G+ {, j& o; F  O

  12. ! V) g6 k$ u9 o) W
  13. // Will go forward to the newest entry., Y1 l, @8 i1 b
  14. navigator.goTo(100000, true);
复制代码
push

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

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

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

绝对路径名

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

  1. navigator.push('/database');
    9 g5 p: ^, D; T$ B6 k- `$ p! A5 Q
  2. // or
    . d' p, k0 i* j, Q5 D# E
  3. navigator.push({ pathname: '/database' });
    5 @  ]  W* r  ~0 R( c& j+ @: i6 j, I
  4. // Navigator will add a new entry, and the current one becomes /database
复制代码
相对路径名

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

  1. navigator.push('license');
    $ X, g4 W& a' u8 M  z3 o
  2. // or7 f2 T4 L& L4 R6 \% p! I1 I
  3. navigator.push({ pathname: 'license' });) e8 H$ Z8 e2 C2 i# r; |/ q- o' N
  4. // Navigator will add a new entry, and the current one becomes /home/license
复制代码
搜索

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

  1. navigator.push('?id=1');
    ) B! B  y* n: W8 A  e, x8 r) w
  2. // or# K6 O6 {" [/ d* }; z! |
  3. navigator.push({ search: '?id=1' });
    " I" C: t# ^/ l$ w1 z% A
  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');/ z3 e8 R8 W; N. E
  2. // or
    ' }- J$ |6 h) y0 f, _
  3. navigator.push({ hash: '#introduction' });+ M) C. p% x; Z6 X
  4. // Navigator will add a new entry, and the current
    # b) \  f2 u* f: c$ V
  5. // one becomes /home/blog#introduction
复制代码
replace

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

属性index

当前历史光标。

  1. const navigator = new BrowserNavigator(['/'], 0);
    . s4 }& n7 i$ h7 w  h' i
  2. navigator.index; // 0
复制代码
id

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

  1. const navigator = new BrowserNavigator(['/'], 0);0 ], [1 x5 w. h: e# I% M
  2. navigator.id; // 'abb721'
    " u! T) S# C6 ~, J
  3. , Q/ s* ?9 Y; f" U
  4. const navigator2 = new BrowserNavigator([{ id: 'a', pathname: '/' }], 0);8 g. `1 h0 _$ L9 r
  5. navigator2.id; // 'a'
复制代码
hash

当前历史项目哈希值。

  1. const navigator = new BrowserNavigator(['/#jungle'], 0);
    + A6 @6 ?5 v9 m4 c
  2. navigator.hash; // "#jungle"
复制代码
hasPrev

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

  1. const navigator = new BrowserNavigator(['/'], 0);
    ; d$ f- ~% `+ O7 w8 `3 F) P& r
  2. navigator.hasPrev; // false3 g3 Z+ f/ o) m4 k+ o

  3. 4 L! s0 B4 W+ t9 Z3 S3 q: ]
  4. const navigator2 = new BrowserNavigator(['/a', '/b'], 1);
    4 o9 `- O1 O+ m* h% A4 K  {
  5. navigator2.hasPrev; // true
复制代码
hasNext

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

  1. const navigator = new BrowserNavigator(['/'], 0);/ J* ?3 e1 E) [, d( U2 I- T
  2. navigator.hasNext; // false5 |2 z/ {* S. \; y  R3 y
  3. ' P' W. w6 v9 P# V
  4. const navigator2 = new BrowserNavigator(['/a', '/b'], 0);( j' }& M# K" d7 x
  5. navigator2.hasNext; // true
复制代码
history

安全修改导航历史记录。

  1. const navigator = new BrowserNavigator(['/a#a-hash', '/b?b-query=1'], 0);1 J) ?3 c% z' l% k
  2. navigator.history;
    % ^/ M0 u1 A4 v+ v+ }
  3. // [0 S+ E+ T+ X) g0 X
  4. //   { pathname: '/a', hash: '#a-hash', search: '', id: 'ahJJ123' },
    4 i& O" i* K. Z+ T
  5. //   { pathname: '/b', hash: '', search: '?b-query=1', id: 'dd82' },
    7 p3 _$ ^. R' Z+ J3 E
  6. // ]
复制代码
path

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

  1. const navigator = new BrowserNavigator([{
    ; q( o( ^& w' J* J8 z  }; H
  2.   pathname: '/a',
    ' M2 a+ m1 n- A, f* J
  3.   hash: '#mama',
    " T/ u- k- W/ }; G
  4.   search: '?joe',, F( T; U) j& Z
  5. }], 0);
    1 P2 [" o9 ^% q- |& f7 [2 {9 ~
  6. navigator.path; // '/a?joe#mama'
复制代码
pathname

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

  1. const navigator = new BrowserNavigator([{% c8 g1 Z9 X% V6 {  {
  2.   pathname: '/a',
    1 l/ [0 R; X* D$ C" K7 U8 A3 e' c
  3.   hash: '#mama',/ x  R: @  _, L
  4.   search: '?joe',
    % S* H! Y& z; i* x! ?" J' [) L
  5. }], 0);
    3 @; a& u# i5 ^+ ]  b5 _5 v
  6. navigator.pathname; // '/a'
复制代码
search

当前查询参数。

  1. const navigator = new BrowserNavigator([{
    ; v5 W+ s* \. w
  2.   pathname: '/a',
    + |- ~  O# N7 |7 P
  3.   hash: '#mama',* Q$ m9 m9 e$ P' V2 }# @
  4.   search: '?joe',
    % N, o  r; L/ ]
  5. }], 0);4 m+ v% E7 {- A
  6. navigator.search; // '?joe'
复制代码
' Y+ O& b& |4 s- a
state

当前历史项目状态。

  1. const navigator = new BrowserNavigator([{ state: 'test' }], 0);* p/ |' T7 y) U' u! `/ D

  2. ' k: M: o# ?, f2 a1 T' }
  3. , E/ F. M7 B& t' V8 f, T8 Z
  4. navigator.state; // 'test'
复制代码

: ^3 Q1 d( m! h事件

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

  • navigator: BrowserNavigator: 相关导航器实例。
  • delta: number: 当前活动项目光标的 delta。
  • from: { pathname: string; hash: string; search: string; id: string; state?状态 }: 以前活动的历史项目。
  • to:结构与 from 相同的对象,代表当前活动的历史项目。
    & B0 V+ u- h8 M/ N  R( J+ ?

) l' N9 W4 s7 F添加事件监听器

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

  1. const removeEventListener = navigator.on('change', (ev) => {
    0 G* A4 |1 a. X. f0 g2 x; J' B9 @
  2.   console.warn('Navigation state changed', ev);
    % T0 W% \2 q: N$ T/ ]
  3. });
复制代码
删除事件监听器

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

  1. removeEventListener();
复制代码
或者,您也可以使用导航器的 off 方法:$ c4 U8 K6 E* ~
  1. function listener(ev) {
    2 p- N# e2 t' H- V* w2 q6 o+ q
  2.   console.warn('Navigation state changed', ev);- c8 ?/ `# L; i' b" }# M: x8 m9 ^' e
  3. }
    " l. z: z% b5 s. s
  4. navigator.on('change', listener);
    $ U) B" z, J9 ~; s- K8 `
  5. navigator.off('change', listener);
复制代码
其他方法renderPath

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

  1. const n = new BrowserNavigator(['/'], 0, {
    + Q) V  n9 x. d, k, Y6 X! u! P
  2.   hashMode: 'slash',
    ) T- Y1 G) s' [+ i
  3. });
    % e) O4 d% I$ I
  4. n.renderPath('/test'); // '#/test'" |; u4 Y5 r! W6 j) Y

  5. : S) q$ g& a9 ~# p
  6. const n2 = new BrowserNavigator(['/'], 0, {
    9 P7 N; q* R/ Y# A' I
  7.   base: '/my-base',4 y& j  N7 j2 x! C  |% y) r* }9 \
  8.   hashMode: 'slash',4 v# }% E  i1 a6 o- a5 a; c1 d% y
  9. });: p* R: w- D( y& b
  10. n2.renderPath('/test'); // '#/my-base/test'
    2 I) [1 W5 k  i
  11. # J1 |  X2 m% e3 O
  12. const n3 = new BrowserNavigator(['/'], 0, {
    ( t- S- V! K) H8 f/ h2 T
  13.   base: '/my-base',
    ; {0 K: v) Y" N& Y9 f
  14.   hashMode: null,
    , W4 v4 K% S$ R* [" x9 S
  15. });
    ' z- O) I3 a. t3 O0 j, L( S
  16. n3.renderPath('/test'); // '/my-base/test'
复制代码
parsePath

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


; h6 y. N$ s8 W7 y0 P
  1. const n = new BrowserNavigator(['/'], 0);
    0 m5 `! D7 f  @1 l7 C& \
  2. n.parsePath('/test');$ g" s9 X) S9 A6 }
  3. // { pathname: '/', search: '', hash: '' }
    3 {4 z: w/ }; m& r4 r+ L
  4. # _' C6 E+ P- i* h% m5 T
  5. n.parsePath('/test#abc');
    , h# L, P; k% d1 b
  6. // { pathname: '/abc', search: '', hash: '' }, k) b' y/ H$ ]+ a( q  q; F- T
  7. 0 ?8 s/ F( {+ I2 s- K/ X* g+ e
  8. n.parsePath('/test#abc?query#some-hash');
      B, _! U! E5 F+ _( C
  9. // { pathname: '/abc', search: '?query', hash: '#some-hash' }: k8 v# \7 x; _7 n3 z* W

  10. 1 e7 x% T4 |. ]) H: F* g
  11. const n2 = new BrowserNavigator(['/'], 0, { hashMode: null });
    * w' M+ w# k+ H* T6 J, U
  12. n2.parsePath('/test');
      ^" P8 N* [, h: O& |" E" l
  13. // { pathname: '/test', search: '', hash: '' }  k0 J3 e& x& `% L- ?/ _7 X; {" l
  14. , |5 a. g5 Z2 O; C
  15. n2.parsePath('/test#abc');: `& q% B9 u2 A+ L  M
  16. // { pathname: '/test', search: '', hash: '#abc' }9 ?8 f2 A& ~! Y2 E& l
  17. $ U8 I3 m: H; `# @* c0 Z5 T
  18. n2.parsePath('/test?query#abc');1 i& g3 N3 y; p8 ^
  19. // { pathname: '/test', search: '?query', hash: '#abc' }
复制代码
, Z3 e6 R) e4 o5 L) i" [. L* h, Y
$ t2 ~$ @5 Q( h

8 U3 L* L* Y8 f* M& m) g& |
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则