подскажите почему closest не работает в ie11

170
30 июня 2022, 05:30

подскажите в чем может быть ошибка, в ie11 только в одном месте не отработывает полифил для closest? SCRIPT5007: Не удалось получить свойство "matches" ссылки, значение которой не определено или является NULL

код полифила 
    if (!Element.prototype.closest) {
        if (!Element.prototype.matches) {
            Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
        }
        Element.prototype.closest = function (s) {
            var el = this;
            var ancestor = this;
            if (!document.documentElement.contains(el)) return null;
            do {
                if (ancestor.matches(s)) return ancestor;
                ancestor = ancestor.parentElement;
            } while (ancestor !== null);
            return null;
        };
    }

if (!Element.prototype.closest) {
  if (!Element.prototype.matches) {
    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
  }
  Element.prototype.closest = function(s) {
    var el = this;
    var ancestor = this;
    if (!document.documentElement.contains(el)) return null;
    do {
      if (ancestor.matches(s)) return ancestor;
      ancestor = ancestor.parentElement;
    } while (ancestor !== null);
    return null;
  };
}
(function() {
  var testResultsSvg = document.querySelectorAll('.js-test-result-svg')
  if (testResultsSvg.length < 1) {
    return
  }
  testResultsSvg = Array.prototype.slice.call(testResultsSvg);
  testResultsSvg.forEach(function(testResultSvg) {
    var testResultColumns = testResultSvg.querySelectorAll('.test-result-column')
    var mainElement = testResultSvg.closest('.test-result')
    console.log(mainElement)
    var testCurrent = parseInt(mainElement.querySelector('.js-test-result-current').innerHTML)
    var testMinimum = parseInt(mainElement.querySelector('.js-test-result-minimum').innerHTML)
    var testPossible = parseInt(mainElement.querySelector('.js-test-result-possible').innerHTML)
    console.log(testCurrent, testMinimum, testPossible)
    if (testCurrent < testMinimum) {
      console.log('less')
      testResultSvg.classList.add('test-result-svg-red')
    } else if (testCurrent >= testMinimum) {
      console.log('more', testCurrent, testMinimum)
      testResultSvg.classList.add('test-result-svg-green')
    }
    if (mainElement.classList.contains('test-result-important')) {
      testResultSvg.classList.add('test-result-svg-stroke')
    }
    var testLevel = (testCurrent * 100) / testPossible
    testLevel = Math.floor((14 * testLevel) / 100)
  })
})();
<div class="main-content-right-box-wrapper">
  <div class="test-header">
    <h1 class="test-title h1 color-font-blue">
      Производительность и отказоустойчивость
    </h1>
  </div>
</div>
<div class="main-content-right-box-wrapper-bordered">
  <div class="test-result-line"></div>
  <div class="test-result">
    <h4 class="test-result-title color-font-blue">Поздравляем, вы сдали тест!</h4>
    <div class="test-result-content">
      <div class="test-result-box">
        <div class="test-result-stats">
          <div class="test-result-stats-numbers">
            <p class="test-result-current color-font-blue js-test-result-current">170</p>
            <!--чтобы наложился нужный цвет это значение сравнивается с минимально возможном от чего выберается цвет, после чего сравнивается в максимально возможным и вычесляется сколько будет пустых свеч -->
            <p class="test-result-possible color-font-blue">/&nbsp;</p>
            <p class="test-result-possible color-font-blue js-test-result-possible"> 180</p>
          </div>
          <p class="test-result-stats-text p1 color-font-blue">Набрано баллов</p>
          <div class="test-result-minimum">
            <p class="p2 color-font-blue">Минимум: <span class="bold js-test-result-minimum">160</span></p>
          </div>
        </div>
      </div>
      <div class="test-result-main-image">
        <svg viewBox="0 0 416 200" fill="#000000" xmlns="http://www.w3.org/2000/svg" class="js-test-result-svg">
          <rect class="test-result-column" y="192" width="20.2927" height="8" />
        </svg>
      </div>
      <div class="test-result-info">
        <div class="test-result-info-item svg-action-blue">
          <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
            <path d="M32 4C16.5608 4 4 16.5608 4 32C4 47.4392 16.5608 60 32 60C47.4392 60 60 47.4392 60 32C60 16.5608 47.4392 4 32 4ZM32 54.4C19.6492 54.4 9.6 44.3508 9.6 32C9.6 19.6492 19.6492 9.6 32 9.6C44.3508 9.6 54.4 19.6492 54.4 32C54.4 44.3508 44.3508 54.4 32 54.4Z" />
            <path d="M29.1969 45.9927L34.7969 45.9927L34.7969 27.8002L29.1969 27.8002L29.1969 45.9927Z" />
            <path d="M29.1969 23.5928L34.7969 23.5928L34.7969 18.0068L29.1969 18.0068L29.1969 23.5928Z" />
          </svg>
          <div class="test-result-info-desc">
            <h3 class="h3 color-font-blue bold">21</h3>
            <p class="test-result-info-desc-p p2 color-font-blue">Вопросов</p>
          </div>
        </div>
        <div class="test-result-info-item svg-action-blue">
          <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
            <path d="M34.8006 18.0005H29.2007V33.1593L38.4209 42.3795L42.38 38.4204L34.8006 30.841V18.0005Z" />
          </svg>
          <div class="test-result-info-desc">
            <h3 class="h3 color-font-blue bold">2ч 37мин</h3>
            <p class="test-result-info-desc-p p2 color-font-blue">Затрачено</p>
          </div>
        </div>
        <div class="test-result-info-item svg-red">
          <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
            <path d="M29.6304 22.4414H34.3708V36.6623H29.6304V22.4414Z" />
            <path d="M29.6304 39.0327H34.3708V43.773H29.6304V39.0327Z" />
          </svg>
          <div class="test-result-info-desc">
            <h3 class="h3 color-warning-red bold">2</h3>
            <p class="test-result-info-desc-p p2 color-font-blue">Ошибки</p>
          </div>
        </div>
      </div>
      <div class="test-result-buttons-box">
        <a href="" class="button button-text button-main">Пройти ещё раз</a>
        <a href="" class="button button-border button-text">Ко всем тестам</a>
      </div>
      <div class="test-result-icon">
        <svg viewBox="0 0 155 160" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M71.2963 87.727C71.9083 126.037 98.6826 134.391 111.993 133.779C129.588 133.167 137.697 121.233 143.051 110.676C148.406 100.12 140.604 70.2855 143.969 51.7729C147.335 33.2604 141.216 -3.45866 107.862 0.366247C67.9304 5.26212 70.5313 39.8392 71.2963 87.727Z" fill="#48CEF8"/>
        </svg>
      </div>
    </div>
  </div>
</div>

Answer 1

Проблема и с кодом полифила

  1. } while (ancestor !== null); - ansector может быть undefined, поэтому проверка должна быть нестрогой
  2. не во всех случаях может присутствовать свойство parentElement, вместо него можно использовать parentNode

И с самим кодом: нет проверки возвращаемого значения, поэтому, если .closest вернет null - по любой причине, дальнейший код падает при попытке обращения к этому null.

Answer 2

Попробуйте этот полифил. Рекурсивный работает быстрее цикла.

(function(ELEMENT) {
    ELEMENT.matches = ELEMENT.matches || ELEMENT.mozMatchesSelector || ELEMENT.msMatchesSelector || ELEMENT.oMatchesSelector || ELEMENT.webkitMatchesSelector;
    ELEMENT.closest = ELEMENT.closest || function closest(selector) {
        if (!this) return null;
        if (this.matches(selector)) return this;
        if (!this.parentElement) {return null}
        else return this.parentElement.closest(selector)
      };
}(Element.prototype));
READ ALSO
Как очистить инпут типа file

Как очистить инпут типа file

есть форма в которой пользможет добавлять изображения и при необходимости удалять его

239
Как поместить arguments в call

Как поместить arguments в call

Я хочу запускать функцию не теряя контекст, но при этом имея возможность не привязываться к количеству аргументов

228
Basic авторизация с помощью javascript

Basic авторизация с помощью javascript

Имеем: страницу djdservice

178
Можете объяснить данную функцию?

Можете объяснить данную функцию?

Ясно, что при нажатии на ultabs__caption происходит событие и что дальше?

148