按钮链接和JS链接会稀释网站权重吗——4 种链接形态对 SEO 的真实影响与改造案例

按钮链接和JS链接会稀释网站权重吗——4 种链接形态对 SEO 的真实影响与改造案例

把 button onclick、JS 跳转、a href javascript:void(0) 与传统 a 链接放在一起,从抓取层、权重层、可访问性层、UX 层四个维度拆开分析。配 2.4 万 SKU 电商站全 button 改 a 后收录率从 38% 涨到 81% 的实测数据,给出具体的链接形态决策表。

更新 24 分钟阅读 7,302 阅读

"我们站点上线了一批活动页,导航全用 button 触发 JS 跳转,落地页排名一直上不去——这些按钮算不算链接?会不会稀释权重?" 这是 2024 年我接到的一个真实咨询。客户站点的导航、产品入口、面包屑全部是 <button onclick="window.location.href=..."> 的写法,整个站点对 Googlebot 而言几乎"无内链"。本文把按钮链接、JavaScript 跳转链接与传统 <a> 链接放在一起,从抓取层、权重层、用户体验层、可访问性层四个维度拆开来讲,最后给出一份我自己写过、复用了 5 年以上的"链接形态决策表",帮你在内链布局时不再纠结到底该用哪种形态。

什么是按钮链接和 JS 链接,本质区别在哪里

很多人把这两类东西混为一谈。但从浏览器渲染、HTML 语义、搜索引擎抓取三个角度看,它们彼此差异不小。

传统 a 链接:HTML 一等公民

<a href="..."> 是 HTML 规范里唯一的"链接"原生元素。浏览器对它有内置语义:右键菜单"在新标签打开"、"复制链接地址"、Ctrl+点击新窗口、悬停显示 URL、键盘 Tab 获焦后回车跳转——所有这些都是浏览器层面免费提供的。Googlebot 抓取时也是直接从 a 标签的 href 属性提取链接图。它不需要执行 JavaScript,不依赖事件绑定,是搜索引擎抓取链接最稳妥的形态。

按钮链接:button 元素加 onclick 跳转

实际项目里很常见的写法:

<button onclick="window.location.href='https://example.com/product/123';">查看详情</button>
<button type="button" onclick="location.assign('/category/shoes')">鞋类</button>
<input type="button" value="跳转" onclick="navigateToPage()" />

这类元素在 HTML 语义上代表"可点击的操作按钮",并不是链接。浏览器不会把它当成链接处理:右键没有"在新标签打开"、Ctrl+点击不会开新窗口、悬停不显示 URL。它属于"行为层"——按钮触发行为,行为里恰好是一次跳转。

JavaScript 链接:href="javascript:" 与 onclick 函数

狭义的 JS 链接指 <a href="javascript:void(0)" onclick="goSomewhere()"> 或者 <a href="#" onclick="return false;"> 这种用 a 标签做壳但 href 里没有真实 URL 的写法。广义还包括纯 JS 注入到 DOM 的链接元素、SPA 路由的 history.pushState 跳转、React Router 的 Link 组件渲染出来的实际是 a 但点击行为被 preventDefault 接管。这些都属于"链接的形态被 JS 接管或承载"的场景。

三者本质差异速览

从渲染、抓取、权重传递三个维度对比:

维度a 链接button 链接JavaScript 链接
HTML 语义链接元素操作按钮视写法而定
无 JS 时是否可用可用不可用不可用
Googlebot 是否能抓到 URL稳定不稳定视情况
权重(PageRank)传递传递不传递或弱传递不传递或弱传递
右键打开新标签支持不支持不支持
悬停显示目标 URL支持不支持不支持
无障碍读屏可识别识别为链接识别为按钮视 ARIA 而定

搜索引擎到底能不能抓 button 和 JS 链接

Googlebot 的渲染分两阶段

当前 Googlebot 已经基于 Chromium 内核做完整 JavaScript 渲染(Web Rendering Service,WRS)。它的工作分两个阶段:第一阶段抓取原始 HTML 提取所有 a[href] 链接,第二阶段把页面送入渲染队列执行 JS、解析最终 DOM。第一阶段几乎是同步且消耗低的,第二阶段是异步且消耗高的。

这意味着:a 链接在第一阶段就被发现,几乎"免费"加入抓取队列。而 button onclick 里的跳转 URL,要等到第二阶段渲染完成、Google 模拟点击或扫描事件回调后才可能被发现——这个"可能"很关键。

Google 官方文档怎么说

Google 在《Make your links crawlable》里写得非常明确:

Googlebot can only follow links that are an a HTML element with an href attribute. Links using other formats won't be followed by Googlebot's crawlers. Googlebot can't follow links without an href attribute or other tags that perform as links because of script events.

原文意思就是:Googlebot 只稳定跟踪 <a href="..."> 这一种形式。其他形态(button onclick、div onclick、JS 触发的 location.href、伪 a 标签 href="javascript:")都不在保证范围内。"不在保证范围"不等于"绝对抓不到",但等于"你不能依赖它做内链布局"。

实测:Search Console URL 检查工具

我在多个客户项目上做过同样的实验:用 Search Console 的"URL 检查 → 已渲染的 HTML"看 Googlebot 实际看到的内容。结论是:

  • 静态 a 标签的 href:100% 出现在已渲染 HTML 里,可被 Google 跟踪。
  • JS 在页面加载后注入的 a 标签:大部分能在已渲染 HTML 里看到,但延迟入索引。
  • button onclick 里的 URL 字符串:在已渲染 HTML 里能看见 onclick 属性的字面量,但 Google 不会主动模拟点击触发跳转。
  • 事件代理(document.addEventListener('click', ...))里通过判断 target 决定跳转的:URL 完全藏在 JS 闭包里,已渲染 HTML 看不到。

Bing、百度、Yandex 的差异

如果只看 Google 一家就低估了问题:

  • 百度蜘蛛对 JS 的渲染能力远弱于 Googlebot。我在一个 SPA 站点上观测到,百度索引的页面只有 a[href] 形态的链接能被传递权重,所有 JS 跳转都基本被忽略。
  • Bingbot有 JS 渲染但触发频率低。Bing 官方文档建议尽量提供 SSR 后的静态链接。
  • Yandex的 JS 渲染受站点 robots.txt 限制更敏感,禁掉 JS/CSS 抓取它就完全不渲染。

所以"按钮链接现在 Google 能抓"不能直接推广为"按钮链接对 SEO 没影响"——你的目标搜索引擎覆盖面越广,就越不能依赖 JS。

权重稀释到底是怎么发生的

PageRank 在内部页面间的流动模型

简化模型:每个页面有一个权重值 PR,它会均分给页面上所有出站链接。如果一个产品详情页有 60 个 a 链接,权重就被切成 60 份分别流出去。如果其中一半改成 button 形态,相当于 30 个 a 链接 + 30 个"不传递权重"的元素——理论上每个 a 链接拿到的份额从 1/60 涨到 1/30。这听起来好像变好了?

但反过来看:原本要靠那 30 个 button 把权重传给被指向页面的,现在传不到了。被指向页面(比如冷门分类)失去了一条权重输入路径,可能从此进入"低权重死循环"。

真实案例:导航全 button 化的电商站

我处理过一个 2.4 万 SKU 的电商客户,主导航全是 <button data-link="/category/xxx">,用 JS 监听 click 跳转。表现:

  • Search Console 显示 Googlebot 抓取的"内部链接图"里,只有首页能看到一级分类,二三级分类几乎没有内部链接指向。
  • 所有分类页平均收录率 38%,远低于行业基准 70%+。
  • 把按钮全部换成 <a href="/category/xxx"> 同时保留原视觉样式(用 CSS 把 a 标签做成按钮形态),3 个月后收录率回到 81%。
  • 同期主关键词排名平均上升 7 位,长尾词数量增长 240%。

这就是典型的"权重稀释"——不是按钮"分走了"权重,而是按钮"挡住了"权重流通路径,让被指向页面变成孤岛。

什么场景下"稀释"是错觉

有些人会担心:"首页的按钮跳购物车、跳登录页,会不会稀释外链买来的权重?" 这种担心其实是错觉:

  • 购物车页、登录页通常是 noindex,本来不参与索引和排名。
  • 这些页面对站内 SEO 没意义,权重传不传过去都无所谓。
  • 用 button 触发反而更合理,因为视觉和语义都是"操作"而非"导航"。

所以 button 形态本身不是错——错在用 button 替代了应该用 a 的链接,比如分类导航、面包屑、相关推荐、文章内的引用链接。

HTTPS、可访问性、用户体验三层叠加成本

无障碍辅助技术读屏

NVDA、JAWS、VoiceOver 这些读屏软件对 a 和 button 区分非常严格。当用户用 Tab 键浏览时:

  • 遇到 a 元素读屏会念"链接,跳转到 example.com"。
  • 遇到 button 元素读屏会念"按钮"。
  • 遇到 div onclick 读屏直接跳过——无法识别为可交互元素。

用 button 替代 a 会让所有依赖读屏软件的用户(视障用户、运动障碍用户、依赖键盘导航的用户)失去"这是个跳转链接"的语义提示。WCAG 2.1 Success Criterion 4.1.2 明确要求交互元素必须有正确的 role 和 name。

键盘导航行为差异

用键盘 Tab 到某个元素后按回车键的默认行为:

  • a 元素:触发跳转。
  • button 元素:触发 click 事件(在 form 里还会触发提交)。
  • div onclick:什么都不做(除非显式监听 keydown)。

如果你用 div 或 span 做"伪按钮",必须手动加 tabindex="0" 让它可获焦,再监听 keydown 处理 Enter 和 Space 键,并用 ARIA role 标注。漏掉任何一项都是无障碍 bug。

右键与新标签打开

很多用户的浏览习惯是"中键点击 = 在新标签打开"。这是浏览器对 a 标签的内置行为:

  • a 元素:中键点击、Ctrl+点击、Cmd+点击 = 后台新标签打开。
  • button 元素:中键、Ctrl+点击 = 没有反应(因为 onclick 跑的是 location.href,浏览器把它当作脚本主动跳转,不会响应修饰键)。

这一点对 SEO 间接相关但对 UX 影响很大。一个被习惯了"右键打开新标签看商品"的用户在你的站点上发现这操作没用,跳出率会显著上升,间接拉低 dwell time 等行为信号。

悬停预览 URL

浏览器会在状态栏显示 a 标签悬停时的目标 URL,这是用户判断链接是否可信的最后一道防线(防钓鱼)。button 不显示 URL,等于把这道防线拆了。在跨域跳转、第三方支付、邮件确认等场景,少了 URL 预览会让一部分谨慎用户直接放弃点击。

合理用法:把链接形态当成工具箱

什么时候该用 a 链接

判断标准很简单——用户感知上是"跳转到另一个页面/资源",就用 a。包括:

  • 主导航和子导航:所有可索引的分类、Tag 页、专题页。
  • 面包屑:每一级祖先链接都是 a。
  • 文章内的内链推荐、相关阅读、引用来源。
  • 分页器:上一页、下一页、首页、末页、跳页都是 a。
  • 站点底部的友情链接、备案链接、版权页。
  • 登录/注册入口(即便目标页 noindex 也用 a,因为是"跳转")。
  • 下载链接(指向资源 URL 的)。
  • 邮箱(mailto:)、电话(tel:)。

什么时候该用 button

判断标准:用户感知上是"提交一个动作 / 触发当前页面的状态变化",就用 button:

  • 表单提交:<button type="submit">。
  • 表单重置:<button type="reset">。
  • 添加购物车(这是个操作,不是跳转)。
  • 展开/收起折叠区块。
  • 切换 Tab 标签。
  • 打开/关闭弹窗、抽屉。
  • 分页加载更多(在不变 URL 的前提下)。
  • 视频播放/暂停、收藏、点赞。

SPA 与 Next.js / Nuxt / Astro 等场景

现代框架的 Link 组件(React Router Link、Next.js Link、Nuxt NuxtLink、Astro a)默认会渲染成真实的 <a href="...">,只是点击时用 JS 接管避免整页刷新。这种写法对 SEO 是友好的——SSR/SSG 输出 HTML 后 a[href] 已经在初始 HTML 里,搜索引擎一阶段就能抓到。

反例:用 onClick={() => router.push('/foo')} 写在 button 上,跳过 Link 组件——这样 SSR 出来的 HTML 没有 href,回到了"按钮链接"的坑里。务必用框架提供的 Link 组件。

"看起来像按钮,但其实是链接"的最佳实践

设计师给的设计稿里"主要操作按钮"经常实际上是个跳转。这时正确做法是用 a 标签 + CSS 做成按钮样式,而不是用 button:

<a href="/products" class="btn btn-primary">查看全部产品</a>

CSS 例:

.btn {
  display: inline-block;
  padding: 12px 32px;
  border-radius: 6px;
  background: #2563eb;
  color: #fff;
  text-decoration: none;
  font-weight: 600;
}
.btn:hover { background: #1d4ed8; }

这样视觉上是按钮,语义上是链接,搜索引擎、读屏、键盘、右键全部正常工作。

检查站点链接形态是否健康的实操方法

用 Screaming Frog 抓取出站链接图

Screaming Frog SEO Spider 可以用 JS 渲染模式抓取站点。在 Configuration → Spider → Rendering 选 JavaScript 渲染。抓完后看 Internal → All 标签:每个 URL 的"Inlinks"列就是站内指向它的链接数。如果某个重要页面的 Inlinks 异常低(比如只有 1-2 条),就需要查它本应该被哪些页面链接、为什么没链接到,多半是被 button 或 JS 跳转吃掉了。

用 curl + grep 看裸 HTML

最快的诊断方式:

curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://example.com/ | grep -oE '<a [^>]*href="[^"]*"' | head -50

这是 Googlebot 一阶段能拿到的 a 链接。如果数量远少于你浏览器看到的链接数,说明大量链接是 JS 渲染或 button 形态。

用 Lighthouse 跑 SEO 与无障碍审计

Chrome DevTools 的 Lighthouse → SEO 分类会检查 "Links have descriptive text"、"Document avoids plugins"。无障碍分类会检查 "Buttons have an accessible name"、"Links have a discernible name"。如果你把 a 写成 button,无障碍分会扣,因为 button 没有 href,缺乏跳转目标的语义说明。

用 Search Console 链接报告

Search Console → 链接 → 内部链接:列出每个 URL 被站内多少 URL 链接到。这是 Google 真实统计的数字。把"应该被很多内链指向"的页面挑出来,比对内部链接数,差距大的就是病灶。

常见问题解答

按钮 onclick 跳转 Google 真的完全不抓吗

不是绝对不抓,是不可靠。Google 渲染 JS 后会扫描 DOM,部分情况下可以发现 onclick 里的 URL 字面量。但抓取频率低、延迟入索引、不传递或弱传递 PageRank。Bing、百度、Yandex 抓取概率更低。结论:可以作为"额外的导航辅助",不能作为内部链接图的骨架。

把现有的 button 链接改成 a 链接,权重会立刻回流吗

不会立刻。改完后需要等 Googlebot 重新抓取所有页面、重建链接图、重新计算 PageRank。一般 4-12 周可见效果,热门站点更快、冷门站点更慢。可以主动通过 Search Console 提交关键页面的 URL 加速重新抓取,并更新 sitemap.xml 强制 Google 重新评估。

SPA 框架(React、Vue)写出来的链接对 SEO 友好吗

取决于是否做 SSR 或 SSG。纯 CSR(客户端渲染)的 SPA,初始 HTML 是空 div,所有链接都是 JS 渲染——Googlebot 能渲染但延迟高、其他搜索引擎不一定能渲染。建议用 Next.js / Nuxt / Astro 做 SSR/SSG,让 a[href] 出现在初始 HTML 里。点击交互可以用 JS 接管避免整页刷新,但 href 必须先有。

nofollow 和 sponsored 这些 rel 属性在 button 上能用吗

不能。rel 属性是 HTML 链接(a、area、link)专属的。button 上写 rel 会被浏览器和搜索引擎忽略。需要给某个跳转加 nofollow 标记时,必须先把它改成 a 标签,才能在 a 上加 rel="nofollow"rel="sponsored"

用 a 标签 href="javascript:void(0)" 做点击事件,搜索引擎会怎么处理

这是历史遗留写法,搜索引擎会把 href 值看作 "javascript:void(0)" 字面量,发现这是个伪 URL 直接跳过——既不跟踪也不传递权重。但因为 a 标签本身被识别为链接元素,无障碍读屏会念"链接"误导用户。建议彻底替换为 button 元素或者真正的 a href。

面包屑用 button 实现会有什么后果

三连击:(1) 搜索引擎拿不到面包屑结构化数据里 itemListElement 的 URL,BreadcrumbList 富摘要失效;(2) 用户中键点击不能新开标签返回上层;(3) 读屏识别为"按钮序列"而非"导航路径",无障碍体验崩塌。面包屑必须用 a 标签 + Schema.org BreadcrumbList JSON-LD。

把整站按钮换成 a 标签需要注意什么

三个雷区:(1) 表单内的 button 不要乱改——type="submit"、type="reset"、type="button" 各有用途,改成 a 会破坏表单提交;(2) 改完后样式要测——CSS 选择器里 button 和 a 的伪类、状态略有差异;(3) 事件绑定要测——原来挂在 button click 上的逻辑要确保 a click 也能触发,必要时 e.preventDefault() 阻止默认跳转再走自定义逻辑。建议改造前列一份 inventory,分批替换。

JS 链接对站点速度的影响有多大

取决于实现方式。事件代理(document 上挂一个 listener)开销小,几乎可以忽略。如果是每个按钮单独挂 onclick,DOM 越大解析越慢、内存占用越多。我在一个 5000 个 button 的列表页上观测到,把每个按钮挂 onclick 改成事件代理后,页面 DOMContentLoaded 时间从 2.3s 降到 1.4s,LCP 从 3.1s 降到 2.0s——这一项就足够把 Core Web Vitals 从 Poor 拉到 Good。

移动端深度链接(Universal Link、App Link)该用 a 还是 button

用 a。Universal Link / App Link 的协议要求触发跳转的元素必须是真实的 a[href],浏览器才能识别 URL Scheme 让操作系统决定打开 App 还是 Web。button onclick 里塞跳转代码会被浏览器当作普通 JS 行为,跳不到 App。

给链接形态画一张决策图

实操里我会用这张速查图判断该不该用 a 链接:

  1. 这个元素点击后的目标,对 SEO 索引有意义吗?是 → 用 a。
  2. 用户能在新标签里打开吗?应该能 → 用 a。
  3. 无障碍辅助技术应该把它念成"链接"还是"按钮"?念链接 → 用 a。
  4. 它有独立的 URL 还是只改变当前页面状态?有 URL → 用 a。
  5. 它在分类、面包屑、文章正文、推荐位、分页器里?是 → 用 a。

只要任一项答"是"就用 a。其余场景可以用 button。这套规则比"按钮稀释权重吗"这个模糊问题更实用——直接对应到具体写法。

回到最初那个全 button 站点的客户,我的建议是分四步走:(1) 用 Screaming Frog 把站点抓一遍,导出"应该有大量内链但实际很少"的孤岛页面清单;(2) 优先把面包屑、主导航、分页器、相关推荐这四类组件全部换成 a 标签;(3) 商品列表、分类页、专题页里的卡片用整块 a 包裹(card-link 模式),让整张卡片都是可点击链接;(4) 保留 button 给购物车、收藏、加载更多等真正的"操作"。整改完上线 2 个月后,索引页面数从 4800 涨到 1.7 万,自然流量翻 2.6 倍。这件事的根本道理就一句:链接是信息架构,按钮是行为;别让按钮替信息架构站岗。

分享到
标签
版权声明

本文标题:《按钮链接和JS链接会稀释网站权重吗——4 种链接形态对 SEO 的真实影响与改造案例》

本文链接:https://zhangwenbao.com/will-button-links-and-js-links-dilute-the-authority.html

版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0

继续阅读
3 条评论
  1. 了凡四训 的头像
    #1 中国北京市移动

    学到了啊谢谢

  2. Jeffrey 的头像
    #2 中国广东省深圳市电信

    |´・ω・)ノ

    1. 张文保 的头像
      博主 中国广东省深圳市电信

      doge

发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交