分析问题
先找一下关键词,从里面找一下解决问题的思路。
- ssr
- title
- 默认行为
- seo
- 自定义 tooltip 行为
解决问题
阻止浏览器默认行为(失败了)
event.preventDefault()
可以用来阻止浏览器的默认行为,比如说 onsubmit
表单提交、onkeydown
键盘输入、<a>
页面跳转等等。
那么 title
行为可以阻止吗?在什么事件中可以阻止?
因为我们也不确定什么事件可以,索性我们直接覆盖所有事件。
a = document.createElement('a') // eventList 存放所有可以触发的事件 eventList = []; // 通过 for i 的特性,我们把on开头的全部存起来。 for(var i in a) /^on/.test(i)&&eventList.push(i); // console.log(eventList) // 阻止默认事件 preventDefaultFun = e => {e.preventDefault(),console.log(e.type)}; // 绑定所有事件 eventList.forEach(v=>a[v]=preventDefaultFun) // 增加内容,追加到 DOM 中测试 a.title = 'www.lilnong.top' a.innerText = '微信公众号:前端linong' document.body.appendChild(a)
可以看到,title 的默认行为还是触发了,所以通过事件阻止默认行为失败了。
css 阻止
shadow DOM
我们通过这个可以实现一些效果,隐藏<video>
的下载功能,隐藏<input type="number">
的右侧按钮。但是 title 不属于这部分,所以无法控制。
pointer-events
通过设置为none
的确可以阻止 title ,但是也无法接收事件了。
js 阻止
js 方案肯定是兼容性最好的方法,我们再来看看题目,Vue 的 ssr 为了 seo 给标签增加了 title。
那么我们可以有针对性的提出几个方案:
- 钩子函数移出 title 属性。
- 实现 hover 效果,移除 title 属性。
- 覆盖标签、或者标签替换等方案。
SSR 的生命周期钩子函数
生命周期钩子函数中,只有 beforeCreate
和 created
会在服务器端渲染 (SSR) 过程中被调用。其他生命周期钩子函数中的代码(例如 beforeMount
或 mounted
),只会在客户端执行。
SEO 抓取 & 搜索引擎的蜘蛛
有个常识性的东西:抓取的只是静态的 HTML。
不知道有杠精没,我简单说一下吧:因为只抓取静态的,所以我们普通的 Vue 渲染的页面是不会抓取的,所以才要使用 SSR 服务端渲染这个方案。
基于这个常识,我们 js 操作 DOM 不会影响 SEO。
实现方案(mounted 钩子移除)
基于上面的逻辑,那么我们就可以在 mounted
中把所有 title
隐藏就好了。
这样用户使用的时候就是一个没有 title 属性的标签,也就不会有默认效果了。
<a :title="isShowTitle&&title"></a> data: { isShowTitle: true, title: 'https://www.lilnong.top' }, mounted(){ this.isShowTitle = false }
实现方案(hover 效果)
mouseenter、mouseleave 动态的移除和添加 title 属性。
如果觉得绑定事件太复杂,可以用原生使用事件委托来搞。
实现方案(jquery&原生 用选择器来移除)
$('[title]')
和 document.querySelectorAll('[title]')
就可以获取到所有存在 title 属性的标签。然后遍历把title属性移除就可以