Можно ли проверить совместимость браузера с 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);
Другие вопросы по тегам