网站分享插件Share.js微信分享图片缺少alt属性完美修复方法
事情是这样的。
前阵子在搞一个网站,接入了 Share.js 这个分享插件,微博、QQ、微信、豆瓣这些渠道都挺顺畅的,分享出去链接也都能正常跳转。
结果那天无聊,跑了一下 Google Lighthouse 做无障碍检测,好家伙,给我弹出来一个警告。
图片缺少 alt 属性。
点进去一看,是微信分享弹窗里那张二维码图片,一张 base64 生成的二维码,src 长得要命,但 alt 属性。空的。啥也没有。
我当时就愣住了。
不是,这玩意怎么会没 alt 呢?无障碍访问是最基本的 web 标准啊,视障用户靠屏幕阅读器读网页的时候,读到一张没 alt 的图片,它只能说「图片」,用户压根不知道这是啥。
这不行。
于是就钻进去看了一下 Share.js 的源码,搞清楚了这个问题的根因,顺便给修了。如果你也在用这个插件,大概率也会遇到同样的问题,这篇文章就把排查过程和修复方法完整走一遍。

Share.js 是怎么生成微信二维码的
先简单说一下 Share.js 的微信分享机制。
其他渠道(微博、QQ、豆瓣这些)都是直接拼一个分享链接,打开新窗口完事。但微信比较特殊,它没有开放网页端的分享 API,所以 Share.js 的做法是。
在页面上弹一个浮层,里面放一张二维码图片,用户拿微信扫这个码就能把链接分享出去。
这套逻辑在 jquery.share.min.js 里,核心代码大概是这样的,
e.append(
'<div class="wechat-qrcode">' +
'<h4>' + t.wechatQrcodeTitle + '</h4>' +
'<div class="qrcode"></div>' +
'<div class="help">' + t.wechatQrcodeHelper + "</div>" +
"</div>"
),
e.find(".qrcode").qrcode({
render: "image",
size: t.wechatQrcodeSize,
text: t.url
})
它先拼了一个 HTML 结构出来,然后调用 qrcode() 方法在 .qrcode 这个 div 里生成一张二维码图片。render 设成 "image",意思是不要用 canvas 画,也不要拼 div 像素矩阵,直接输出一个 <img> 标签。
问题就出在这个 <img> 标签的生成逻辑上。
根因在哪里
追到 qrcode() 的 image 渲染分支,代码是这样的,
function(r) {
return d("<img/>").attr("src", t(r)[0].toDataURL("image/png"))
}(r)看到了吧。
用 canvas 把二维码画出来,转成 dataURL,然后直接 d("<img/>").attr("src", ...),只设了 src,完全没有管 alt。
你肯定会想,那是不是 createImgTag 那个方法有 alt 参数但没传?
确实。Share.js 内置的 QR 码库还有一个 createImgTag 方法,是走 GIF base64 路线的,
A = function(r, t, e, n) {
// ...生成 base64...
n && (l += ' alt="', l += n, l += '"')
// ...
}
第四个参数 n 就是 alt 文本。但问题是,调用它的地方只传了两个参数,
f.createImgTag = function(o, r) {
o = o || 2, r = void 0 === r ? 4 * o : r;
return A(t, t, function(r, t) { ... }) // 没传 alt
}
alt 参数永远是 undefined,分支永远不走。
而且微信分享走的是 render: "image" 路径,根本就不会调 createImgTag。所以不管哪个分支,最终生成的这张微信二维码图片,alt 属性就是空的。
这就是完整的根因。两个生成路径,都没有处理 alt。

修复步骤
搞清楚问题之后,修起来其实非常简单。总共就一步。
找到 jquery.share.min.js 里微信二维码生成的那段代码,在 .qrcode() 调用后面,链式追加上 alt 属性。
修改前,
e.find(".qrcode").qrcode({
render: "image",
size: t.wechatQrcodeSize,
text: t.url
}), e.offset().top < 100 && e.find(".wechat-qrcode").addClass("bottom")修改后,
e.find(".qrcode").qrcode({
render: "image",
size: t.wechatQrcodeSize,
text: t.url
}).find("img").attr("alt", "微信分享二维码"), e.offset().top < 100 && e.find(".wechat-qrcode").addClass("bottom")
就多了一行 .find("img").attr("alt", "微信分享二维码")。
原理很简单,.qrcode() 执行完之后,.qrcode 这个 div 里面就已经有了一张 <img> 标签,直接 find("img") 找到它,用 attr() 把 alt 补上就行了。
alt 的内容我写死了「微信分享二维码」,如果你想让用户自定义文字,也可以读插件的配置项,比如之前已经有 wechatQrcodeTitle 这个参数,默认值是「微信扫一扫:分享」,
.find("img").attr("alt", t.wechatQrcodeTitle || "微信分享二维码")
这样如果你在初始化 .share() 的时候传了自定义的 wechatQrcodeTitle,alt 也会跟着变。想灵活一点就这么写,想简单一点直接写死也完全没问题。
验证
改完之后刷新页面,打开微信分享的二维码弹窗,右键检查元素,你应该能看到 img 标签上多了一个 alt="微信分享二维码"。
再跑一下 Lighthouse 的无障碍检测,alt 缺失的警告就消失了。
屏幕阅读器读到这张图片的时候,会播报「微信分享二维码」,用户立刻知道这是什么。
结尾
说实话,这是个特别小的问题。
就一行代码的事儿。
但它背后反映的是,很多前端插件在开发的时候,无障碍访问几乎是被遗忘的角落。alt 属性、ARIA 标签、键盘导航、焦点管理,这些对普通用户可能感知不到,但对视障用户来说就是能不能正常使用一个网站的分界线。
web 标准写了这么多年,WAI-ARIA 规范也推了这么多年,但实际落地的时候,连一个几万 star 的分享插件都能漏掉 alt。
以前我也没注意过这个问题,也是那次跑 Lighthouse 才发现的。修完之后就顺手记录下来了。
如果你也在用 Share.js 或者类似的前端分享插件,有空跑一下无障碍检测,大概率能发现一些类似的小细节。修起来都不难,但修完之后的用户体验提升,对那一部分用户来说是实打实的。
以上。
版权及免责申明:本文由@fuwa原创发布。该文章观点仅代表作者本人,不代表本站立场。本站不承担任何相关法律责任。
如若转载,请注明出处:https://www.fuwa.org/tutorials/sharejs-wechat-img-alt-fix.html

