Проблемы с новым reCAPTCHA Google в IE, когда внутри модального или диалогового

reCAPTCHA отлично работает в Chrome.

Однако (только когда reCAPTCHA iframe находится внутри диалогового окна или модального) в IE, местозаполнитель не исчезнет.

Независимо от того, что пользователь пишет, считается частью заполнителя (я думаю), и кнопка "проверить" не будет разрешена для нажатия.

На рисунке показано следующее:

Тот же код отлично работает во всех браузерах, когда я беру recaptcha div вне модального

<html lang="en">
<head>
    <link href="#" onclick="location.href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css'; return false;" rel="stylesheet">
    <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
    <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
    <script type="text/javascript">
    var onloadCallback = function() {
        grecaptcha.render('html_element', {
          'sitekey' : '6Lc7PAATAAAAAE7JwcA7tNEDIrczjCCUvi3GiK4L'
      });
    };
    </script>
</head>
<body>
    <div class="container">
        <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
          Launch modal
      </button>
      <!-- Modal -->
      <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
          <div class="modal-dialog">
            <div class="modal-content">
                <form action="?" method="POST">
                  <div id="html_element"></div>
                  <br>
                  <input type="submit" value="Submit">
              </form>
          </div>
      </div>
  </div>
</div>
</body>
</html>

Ответ 1

Задача генерируется модальной компонентой Bootstrap.

Когда модальный появится, эта функция вызывается:

Modal.prototype.enforceFocus = function () {
    $(document)
    .off('focusin.bs.modal') // guard against infinite focus loop
    .on('focusin.bs.modal', $.proxy(function (e) {
        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
            this.$element.trigger('focus')
        }
    }, this))
}

Функция добавляет событие "focusin" в документ, чтобы быть уверенным, что фокус все еще находится внутри модального; если фокус переходит к другому элементу вне модального, то последний сразу получает его обратно.
Поэтому, когда вы нажимаете внутри формы recaptcha, конфликт фокуса вызывает ошибку Internet Explorer.

Во всяком случае, одним из возможных решений является переопределить этот метод и отключить поведение фокуса, когда компонент recaptcha получает фокус, но это довольно сложно сделать, потому что нет контроля над recaptcha html (как вы можете знать, если e.target является элементом recaptcha?).

Мое решение состоит в том, чтобы полностью отключить это поведение, для этого просто переопределите функцию принудительного использования с пустой функцией:

$.fn.modal.Constructor.prototype.enforceFocus = function () { };

Более элегантное решение будет оценено.:)

Ответ 2

Старый recaptcha, то есть версия 1.0 работает нормально на модальном

Ответ 3

Чтобы следить за ответом "Digibusiness", немного более элегантным было бы переопределение всей функции начальной загрузки с практической (при загрузке на странице - функция document.ready была бы хорошим местом). Таким образом, вы можете ссылаться только на IE при переполнении + только на iframes, загружаемом в модальную систему, следовательно, не прикручивая доступность (которая в наши дни стала большой проблемой) по всему сайту только для определенного iframe-over-modal-on- a-specific-browser functionallity fix.

  • Ниже приведен код:

    if (window.navigator.userAgent.indexOf("MSIE ") > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {  // If Internet Explorer
        $.fn.modal.Constructor.prototype.enforceFocus = function () {
            $(document)
            .off('focusin.bs.modal') // guard against infinite focus loop
            .on('focusin.bs.modal', $.proxy(function (e) {
                if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
                    if (e.target.nodeName !== "IFRAME") {
                        this.$element.trigger('focus')
                    }
                }
            }, this))
        }
    }