Javascript IE中新Google reCAPTCHA在模态或对话框中出现问题

Javascript IE中新Google reCAPTCHA在模态或对话框中出现问题,javascript,twitter-bootstrap,internet-explorer,modal-dialog,recaptcha,Javascript,Twitter Bootstrap,Internet Explorer,Modal Dialog,Recaptcha,reCAPTCHA在Chrome中工作得非常好 但是,只有当reCAPTCHA iframe位于对话框或IE中的模式中时,占位符才会消失 我认为用户写的任何内容都被视为占位符的一部分,并且不会启用“验证”按钮来单击 图片说明了这一点: 当我在modal之外使用recaptcha div时,相同的代码在所有浏览器中都能很好地工作 <html lang="en"> <head> <link href="https://maxcdn.bootstrapcdn.co

reCAPTCHA在Chrome中工作得非常好

但是,只有当reCAPTCHA iframe位于对话框或IE中的模式中时,占位符才会消失

我认为用户写的任何内容都被视为占位符的一部分,并且不会启用“验证”按钮来单击

图片说明了这一点:

当我在modal之外使用recaptcha div时,相同的代码在所有浏览器中都能很好地工作

<html lang="en">
<head>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" 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>

旧的recaptcha,即版本1.0在模式上正常工作

问题是由引导的模式组件产生的

<html lang="en">
<head>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" 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>
当模态即将出现时,调用此函数:

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?的一个元素

我的解决方案是完全禁用此行为,为此只需使用空函数覆盖enforceFocus函数:

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

需要一个更优雅的解决方案

为了跟进“Digibusiness”的响应,更优雅的做法是在页面加载中使用一个实用的引导函数覆盖整个引导函数-document.ready函数将是一个好地方。 通过这种方式,你可以只引用IE,而不是只引用加载在modal上的iframe,因此不需要修改访问性,这一点现在在整个网站上已经成为一个大问题,只是为了一个特定的iframe-over-modal-on-a-specific-browser功能修复

守则如下:

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))
    }
}

显然,此enforceFocus方法仅用于可访问性目的,并且此功能也可以在IE:if/MSIE | Trident/.testwindow.navigator.useragent的条件下被禁用“下一步”和/或“验证”按钮仍然不起作用。它在调试器中命中了断点,但在视觉上没有任何变化。我做了更多的调查,代码仍然在调用引导函数,而不是新的重写函数。