是否可以测试 scrollIntoView 浏览器兼容性?
Is it possible to test for scrollIntoView browser compatibility?
我正在寻找一种方法来对用户浏览器的 scrollIntoView
功能进行实时测试。这不是“caniuse”检查;相反,我想要优雅的退化。我正在使用 jQuery,如果 scrollIntoView 可以正常工作,我想使用 preventDefault()
。
我开始于:
if (window.scrollIntoView) {
e.preventDefault();
$('p#result').text('scrollIntoView is available');
} else {
$('#result').text('scrollIntoView is not available');
}
但我在检查器中看到 window.scrollIntoView
是 undefined
。但是,因为 scrollIntoView
有效(在我的 Chrome 和 FireFox 版本中),它不应该是未定义的。我还有什么其他选项可以查看用户的浏览器是否支持该功能?
method在元素上,所以你可以检查document.documentElement.scrollIntoView
。
检查 scrollIntoView 是否仅支持布尔值 true / false 或是否还支持平滑滚动行为也很方便。
var isSmoothScrollSupported = 'scrollBehavior' in document.documentElement.style;
if(isSmoothScrollSupported) {
element.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
} else {
element.scrollIntoView(false);
}
我发现至少对于 WaterFox 浏览器(可能还有更多浏览器),document.documentElement.style 中确实存在 scrollBehavior,正如 所暗示的那样,但浏览器会抛出以下错误:
TypeError: 'block' member of ScrollIntoViewOptions 'center' is not a valid
value for enumeration ScrollLogicalPosition.
一个简单的 try-catch 语句为我们解决了这个问题:
try {
element.scrollIntoView({
behavior: "smooth",
block: "center"
});
} catch (error) {
//fallback to prevent browser crashing
element.scrollIntoView(false);
}
你可以这样检查:
if (typeof document.body.scrollIntoView === 'function') {
// Do smth.
yourNode.scrollIntoView();
}
我无法通过单元测试轻松验证这些类型的检查,而不必实施奇怪的覆盖机制,将单元测试端暴露给它不应该真正了解的逻辑。
基于@DrewJex 的,我最终完全根据浏览器的行为方式编写了一些东西,这也更容易测试。
const scrollIntoView = (element, params = true) => {
try {
element.scrollIntoView(params);
return true;
} catch (e) {
return false;
}
};
const scrollTo = (element, params = {}) => {
try {
window.scrollTo({ ...params, top: element.offsetTop });
return true;
} catch (e) {
return false;
}
};
export const scrollToElement = (element) =>
scrollIntoView(element, { behavior: 'smooth' }) ||
scrollIntoView(element) ||
scrollTo(element, { behavior: 'smooth' }) ||
scrollTo(element);
我正在寻找一种方法来对用户浏览器的 scrollIntoView
功能进行实时测试。这不是“caniuse”检查;相反,我想要优雅的退化。我正在使用 jQuery,如果 scrollIntoView 可以正常工作,我想使用 preventDefault()
。
我开始于:
if (window.scrollIntoView) {
e.preventDefault();
$('p#result').text('scrollIntoView is available');
} else {
$('#result').text('scrollIntoView is not available');
}
但我在检查器中看到 window.scrollIntoView
是 undefined
。但是,因为 scrollIntoView
有效(在我的 Chrome 和 FireFox 版本中),它不应该是未定义的。我还有什么其他选项可以查看用户的浏览器是否支持该功能?
method在元素上,所以你可以检查document.documentElement.scrollIntoView
。
检查 scrollIntoView 是否仅支持布尔值 true / false 或是否还支持平滑滚动行为也很方便。
var isSmoothScrollSupported = 'scrollBehavior' in document.documentElement.style;
if(isSmoothScrollSupported) {
element.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
} else {
element.scrollIntoView(false);
}
我发现至少对于 WaterFox 浏览器(可能还有更多浏览器),document.documentElement.style 中确实存在 scrollBehavior,正如
TypeError: 'block' member of ScrollIntoViewOptions 'center' is not a valid
value for enumeration ScrollLogicalPosition.
一个简单的 try-catch 语句为我们解决了这个问题:
try {
element.scrollIntoView({
behavior: "smooth",
block: "center"
});
} catch (error) {
//fallback to prevent browser crashing
element.scrollIntoView(false);
}
你可以这样检查:
if (typeof document.body.scrollIntoView === 'function') {
// Do smth.
yourNode.scrollIntoView();
}
我无法通过单元测试轻松验证这些类型的检查,而不必实施奇怪的覆盖机制,将单元测试端暴露给它不应该真正了解的逻辑。
基于@DrewJex 的
const scrollIntoView = (element, params = true) => {
try {
element.scrollIntoView(params);
return true;
} catch (e) {
return false;
}
};
const scrollTo = (element, params = {}) => {
try {
window.scrollTo({ ...params, top: element.offsetTop });
return true;
} catch (e) {
return false;
}
};
export const scrollToElement = (element) =>
scrollIntoView(element, { behavior: 'smooth' }) ||
scrollIntoView(element) ||
scrollTo(element, { behavior: 'smooth' }) ||
scrollTo(element);