如何从 scrollIntoViewOptions 回退以与 Safari 兼容?

How do I fallback from scrollIntoViewOptions for compatibility with Safari?

我有一个触发此功能的 onclick:

 function thread2M() {
        
  var elmnt = document.getElementById("scroll2");
  elmnt.scrollIntoView({behavior: "smooth", block: "center", inline: "center"});

}

将页面滚动到特定像素(div)并将其居中。当然,scrollIntoViewOptions 在 Safari 中不起作用,所以我想回退到 scrollIntoView() 或 scrollTo()。

我试过:

function thread2M() { 
    var elmnt = document.getElementById("scroll2");
    try {
        elmnt.scrollIntoView({behavior: "smooth", block: "center", inline: "center"});
}    catch {
        elmnt.scrollIntoView(true);
}
}

function thread2M() {
            if (typeof document.body.scrollIntoView === 'function') {
  var elmnt = document.getElementById("scroll2");
  elmnt.scrollIntoView({behavior: "smooth", block: "center", inline: "center"});}

  else {window.scrollTo(782, 280);}
 
}

但没有启动滚动。我什至不了解 JS 的工作原理,所以答案可能与基础知识有关,但我找不到解决方案。我想我只需要测试 scrollIntoViewOptions 是否有效,如果为真,运行 一个脚本,如果为假,运行 另一个。

感谢回答,谢谢。

第一次尝试看起来可行。尝试在控制台中查看发生了什么:

function thread2M() { 
    var elmnt = document.getElementById("scroll2");
    try {
        console.log("Calling scrollIntoView");
        elmnt.scrollIntoView({behavior: "smooth", block: "center", inline: "center"});
    }    catch (error) {
        console.log("Error scrolling: " + error.message);
        elmnt.scrollIntoView(true);
    }
}

(如果您找不到 safari 的日志,您可以将“console.log”替换为“alert”,消息将在屏幕上弹出。)

第二个不会工作,因为 Safari does 有一个 scrollIntoView 功能;它只是不接受其他浏览器接受的选项参数。

您可以尝试其他三个选项。第一个是检查 CSS 滚动行为 属性 的存在(这不是完全相同的东西,但高度相关):

function thread2M() { 
    var elmnt = document.getElementById("scroll2");
    if('scrollBehavior' in document.documentElement.style) {
        elmnt.scrollIntoView({behavior: "smooth", block: "center", inline: "center"});
    } else {
        elmnt.scrollIntoView(true);
    }
}

或者您可以尝试使用 getter 来覆盖 scrollIntoViewOptions 的行为。 (感谢 nlawson 使用它来测试 scrollTo 支持)。在您的 thread2M 函数上方尝试添加:

function testSupportsSmoothScroll () {
  var supports = false
  try {
    var div = document.createElement('div')
    div.scrollIntoView({
      get behavior () {
        supports = true
        return 'smooth'
      }
    })
  } catch (err) {}
  return supports
}

然后将thread2M中的if测试替换为if (testSupportsSmoothScroll())。请注意,在没有 scrollIntoViewOptions 的情况下,我无法在浏览器上测试其中的任何一个,但它似乎确实适用于 chrome/ff.

最后,您可以尝试使用 polyfill 脚本,它(希望)会检测并消除浏览器差异。我自己从未尝试过,但您可以尝试 seamless scroll polyfill。将脚本导入 header:

<script src="https://cdn.jsdelivr.net/npm/seamless-scroll-polyfill@1.0.0/dist/es5/seamless.js"></script>

然后像这样修改thread2M:

function thread2M() { 
    var elmnt = document.getElementById("scroll2");
    seamless.elementScrollIntoView(elmnt, {behavior: "smooth", block: "center", inline: "center"});
}

虽然使用这种方法您确实需要加载另一个 32KB 的脚本,但这还不错。