iframe 内部的 focus 事件导致 tabs 组件显示错误

发布于 2022-09-11 21:33:38 字数 393 浏览 21 评论 0

背景:

vue 项目,使用的 iview 组件库,tabs 组件,每个 tab 下有个 iframe,不跨域。
我想要实现 iframe 的预加载,在第一个 iframe onload 之后加载第二个。

遇到的问题:

本来预加载第二个 iframe 的时候第二个该隐藏的,还是显示第一个,但是由于 iframe 内部执行了 focus 事件导致聚焦的元素跑到了屏幕中心,tab 显示错位。此时获取 iframe 的 dom 元素,并执行 contentWindow.blur() 之后并不能使 tab 回到正确的位置。请问有没有办法可以阻止 iframe 执行 focus 事件?

有其他思路的同学欢迎提出不同想法~谢谢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉城 2022-09-18 21:33:38

找到解决方法了,写给后来人。

我们在执行focus事件的时候其实还可以传一个参数的:

ele.focus({ preventScroll: false })

preventScroll:一个布尔值。如果是 true 的话,在视口外部的元素获得焦点之后不会自动滚动到视口中。如果是 false,则元素获得焦点后会自动滚动到视口中。默认情况下,直接调用focus()等于focus({ preventScroll: false })

所以想让页面正常显示,有两个方法:

  1. 获取焦点时传参,不让页面滚动;
  2. 监听滚动事件,发生滚动时让元素再滚回去。

因为我们项目内部嵌套的 iframe 不是自己项目的,所以只能监听scroll事件了,但是一般情况下focus事件的scroll是监听不到的,参考这个回答:stackoverflow.

// 想要监听 focus 的 scroll,addEventListener 需要传第三个参数
window.addEventListener('scroll', function(e){...}, true)

所以最终的解决方案:

// iframe 子组件
created () {
  window.addEventListener('scroll', function (e) {
    if (e.target.className === 'tableauWrapTabSty ivu-tabs') {
      // console.dir(e.target)
      e.target.scrollLeft = 0
    }
  }, true)
},
destroyed () {
  window.removeEventListener('scroll', function (e) {
    console.dir(e.target)
  })
}

参考:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文