Можно ли проверить совместимость браузера с scrollIntoView?
Я ищу способ сделать тест в режиме реального времени для scrollIntoView
функциональность браузера моего пользователя. Это не "проверка caniuse"; скорее я хочу иметь грациозную деградацию. Я использую JQuery, и хотел бы использовать preventDefault()
если scrollIntoView работает
Я начал с:
if (window.scrollIntoView) {
e.preventDefault();
$('p#result').text('scrollIntoView is available');
} else {
$('#result').text('scrollIntoView is not available');
}
но я вижу что window.scrollIntoView
является undefined
в инспекторе. Тем не менее, потому что scrollIntoView
работает (в моей версии Chrome и FireFox), оно не должно быть неопределенным. Какие еще варианты я могу увидеть, если браузер пользователя поддерживает эту функцию?
5 ответов
Этот метод на элементах, так что вы можете проверить 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 (и, вероятно, еще нескольких), scrollBehavior действительно существует в document.documentElement.style, как предполагает Стефан ван де Вурен, однако браузер выдаст следующую ошибку:
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);