fix(ui): prevent hash links from jumping to page top#963
Conversation
审阅者指南(在小型 PR 上折叠)审阅者指南更新评论回复和管理员登出链接,避免基于 hash 的导航把页面跳转到顶部,改为通过 Vue 的点击事件处理程序和页面内平滑滚动来处理相关行为。 评论回复链接触发的页面内滚动时序图sequenceDiagram
actor User
participant TkComment
participant Document
participant TargetComment
User->>TkComment: click tk-ruser link (@click.prevent)
TkComment->>TkComment: scrollToPid(pid)
TkComment->>Document: getElementById(pid)
Document-->>TkComment: element
TkComment->>TargetComment: scrollIntoView(behavior, block)
文件级变更
与关联 issue 的对照评估
使用技巧与指令与 Sourcery 交互
自定义你的使用体验访问你的 控制面板 以:
获取帮助Original review guide in EnglishReviewer's guide (collapsed on small PRs)Reviewer's GuideUpdates comment reply and admin logout links to prevent hash-based navigation from jumping the page to the top, instead handling behavior via Vue click handlers and smooth in-page scrolling. Sequence diagram for in-page scroll on comment reply link clicksequenceDiagram
actor User
participant TkComment
participant Document
participant TargetComment
User->>TkComment: click tk-ruser link (@click.prevent)
TkComment->>TkComment: scrollToPid(pid)
TkComment->>Document: getElementById(pid)
Document-->>TkComment: element
TkComment->>TargetComment: scrollIntoView(behavior, block)
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并留下了一些整体性的反馈:
- 对于你现在通过阻止默认行为处理的
href="#"链接,建议使用更语义化、更易访问的元素(例如<button>,或带有role="button"的<a>),这样键盘操作和屏幕阅读器的行为就能与其实际功能更加一致。 - 在
scrollToPid中,你可能需要对pid进行防御性地转换为字符串,或者在调用getElementById之前确保它是一个合法的 DOM id,以避免在传入非字符串值或包含特殊字符时出现意外。
提供给 AI Agents 的提示
Please address the comments from this code review:
## Overall Comments
- Consider using a more semantic/accessible element (e.g., a `<button>` or `<a>` with `role="button"`) for the `href="#"` links you’re now preventing, so that keyboard and screen-reader behavior is more consistent with their actual function.
- In `scrollToPid`, you may want to defensively cast `pid` to a string or ensure it’s a valid DOM id before calling `getElementById`, to avoid surprises if non-string values or special characters slip through.
## Individual Comments
### Comment 1
<location path="src/client/view/components/TkAdmin.vue" line_range="46" />
<code_context>
<div class="tk-panel-title">
<div>{{ t('ADMIN_TITLE') }}</div>
- <a class="tk-panel-logout" href="#" @click="onLogout">{{ t('ADMIN_LOGOUT') }}</a>
+ <a class="tk-panel-logout" href="#" @click.prevent="onLogout">{{ t('ADMIN_LOGOUT') }}</a>
</div>
<div class="tk-tabs">
</code_context>
<issue_to_address>
**suggestion:** Consider using a button or role attribute for the logout control for better semantics.
Since this element now only triggers an action with `@click.prevent` and no longer represents navigation, it should be exposed as a button for accessibility. Either switch to a `<button>` styled like a link, or keep the `<a>` but add `role="button"` (and any needed ARIA/state) so assistive technologies interpret it as an action control.
```suggestion
<button
type="button"
class="tk-panel-logout"
@click="onLogout"
>
{{ t('ADMIN_LOGOUT') }}
</button>
```
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- Consider using a more semantic/accessible element (e.g., a
<button>or<a>withrole="button") for thehref="#"links you’re now preventing, so that keyboard and screen-reader behavior is more consistent with their actual function. - In
scrollToPid, you may want to defensively castpidto a string or ensure it’s a valid DOM id before callinggetElementById, to avoid surprises if non-string values or special characters slip through.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider using a more semantic/accessible element (e.g., a `<button>` or `<a>` with `role="button"`) for the `href="#"` links you’re now preventing, so that keyboard and screen-reader behavior is more consistent with their actual function.
- In `scrollToPid`, you may want to defensively cast `pid` to a string or ensure it’s a valid DOM id before calling `getElementById`, to avoid surprises if non-string values or special characters slip through.
## Individual Comments
### Comment 1
<location path="src/client/view/components/TkAdmin.vue" line_range="46" />
<code_context>
<div class="tk-panel-title">
<div>{{ t('ADMIN_TITLE') }}</div>
- <a class="tk-panel-logout" href="#" @click="onLogout">{{ t('ADMIN_LOGOUT') }}</a>
+ <a class="tk-panel-logout" href="#" @click.prevent="onLogout">{{ t('ADMIN_LOGOUT') }}</a>
</div>
<div class="tk-tabs">
</code_context>
<issue_to_address>
**suggestion:** Consider using a button or role attribute for the logout control for better semantics.
Since this element now only triggers an action with `@click.prevent` and no longer represents navigation, it should be exposed as a button for accessibility. Either switch to a `<button>` styled like a link, or keep the `<a>` but add `role="button"` (and any needed ARIA/state) so assistive technologies interpret it as an action control.
```suggestion
<button
type="button"
class="tk-panel-logout"
@click="onLogout"
>
{{ t('ADMIN_LOGOUT') }}
</button>
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| <div class="tk-panel-title"> | ||
| <div>{{ t('ADMIN_TITLE') }}</div> | ||
| <a class="tk-panel-logout" href="#" @click="onLogout">{{ t('ADMIN_LOGOUT') }}</a> | ||
| <a class="tk-panel-logout" href="#" @click.prevent="onLogout">{{ t('ADMIN_LOGOUT') }}</a> |
There was a problem hiding this comment.
suggestion: 建议为注销控件使用按钮或添加 role 属性,以获得更好的语义。
由于这个元素现在只是在 @click.prevent 中触发一个操作,并不再表示导航行为,从可访问性角度看,它应该以按钮的形式暴露出来。你可以将其改为外观样式像链接的 <button>,或者保留 <a>,但添加 role="button"(以及必要的 ARIA/状态),这样辅助技术就会将其解释为一个“操作控件”。
| <a class="tk-panel-logout" href="#" @click.prevent="onLogout">{{ t('ADMIN_LOGOUT') }}</a> | |
| <button | |
| type="button" | |
| class="tk-panel-logout" | |
| @click="onLogout" | |
| > | |
| {{ t('ADMIN_LOGOUT') }} | |
| </button> |
Original comment in English
suggestion: Consider using a button or role attribute for the logout control for better semantics.
Since this element now only triggers an action with @click.prevent and no longer represents navigation, it should be exposed as a button for accessibility. Either switch to a <button> styled like a link, or keep the <a> but add role="button" (and any needed ARIA/state) so assistive technologies interpret it as an action control.
| <a class="tk-panel-logout" href="#" @click.prevent="onLogout">{{ t('ADMIN_LOGOUT') }}</a> | |
| <button | |
| type="button" | |
| class="tk-panel-logout" | |
| @click="onLogout" | |
| > | |
| {{ t('ADMIN_LOGOUT') }} | |
| </button> |
Summary
Fixes #832
@click.preventto avoidhref="#"navigationTest plan
Summary by Sourcery
通过在应用内部对哈希链接(hash links)进行处理,使用页面内滚动行为和安全的点击事件处理程序,避免因点击应用内哈希链接导致整页跳转。
Bug 修复:
Original summary in English
Summary by Sourcery
Prevent in-app hash links from causing full-page jumps by handling them with in-page scroll behavior and safe click handlers.
Bug Fixes: