简体   繁体   English

iframe中的表单无法通过Angular和IE11重新获得焦点

[英]Form in iframe unable to regain focus with Angular and IE11

I have an Angular app with a route that contains an iframe. 我有一个Angular应用程序,其中包含一个包含iframe的路径。 The iframe loads a form. iframe加载表单。 On the first load of the route, you are able to enter data into the form. 在第一次加载路径时,您可以在表单中输入数据。 On the second load of the route the form input is unable to regain focus on click in IE11. 在路径的第二次加载时,表单输入无法重新关注IE11中的单击。 Works in Chrome and Firefox. 适用于Chrome和Firefox。

The specific steps to recreate are as follows: 重新创建的具体步骤如下:

  1. Load page in IE11 在IE11中加载页面
  2. Click Iframe link 点击iframe链接
  3. Data can be entered into form input 可以将数据输入表单输入
  4. While the cursor is still in the form input, click the Iframe link 当光标仍在表单输入中时,单击Iframe链接
  5. The route will reload, clearing the form 该路线将重新加载,清除表格
  6. When clicking the form input to enter new text, the form is unable to regain focus 单击表单输入以输入新文本时,表单无法重新获得焦点

I noticed that if you click the Home link after entering text, then click the iframe link the form is able to regain focus allowing new text to be entered. 我注意到,如果您在输入文本后单击“主页”链接,则单击iframe链接,表单可以重新获得焦点,从而允许输入新文本。

Below is sample code that recreates the issue. 下面是重新创建问题的示例代码。 You can see it running here: http://matthewriley.github.io/iframe-form/ . 你可以在这里看到它: http//matthewriley.github.io/iframe-form/

Note that the controller forces a reload of the route based on a flag. 请注意,控制器根据标志强制重新加载路径。 This is to support a business requirement that if a user is in the iframe and choses to click the iframe link, the route will fully reload. 这是为了支持业务要求,即如果用户在iframe中并且选择单击iframe链接,则路由将完全重新加载。

What causes IE11 to prevent the form in the iframe from regaining focus on the second load? 是什么原因导致IE11阻止iframe中的表单重新关注第二次加载?

HTML Page HTML页面

<!DOCTYPE html>
<html lang="en-US">
    <head>
        <meta charset="utf-8" />
        <title>Iframe Reload Test</title>
    </head>
    <body>
        <div ng-app="IframeTest">
            <p><span><a href="#/">Home</a></span>&nbsp;<span><a href="#/iframe">Iframe</a></span></p>
            <div ui-view></div>
        </div>
        <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
        <script src="app.js"></script>
    </body>
</html>

Angular App 角度应用程序

// app.routes.js
(function() {
    'use strict';
    angular
        .module('IframeTest', [
            'ui.router',
            'IframeTest.iFrameModule'
        ])
        .config(routeConfig);
    routeConfig.$inject = ['$stateProvider', '$urlRouterProvider'];
    function routeConfig($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise("/");
        $stateProvider
            .state('home', {
                url:'/',
                template: '<h4>Home</h4><p>This is the home page.</p>'
            })
            .state('iFrame', {
                url:'/iframe',
                template: '',
                controller: 'IFrameCtrlAs',
                controllerAs: 'vm'
            })
            .state('iFrame/:flag', {
                url:'/iframe/:flag',
                template: '<h4>Iframe</h4><p><iframe src="{{vm.url}}" id="iframeID" frameborder="1" width="100%" scrolling="no"></iframe></p>',
                controller: 'IFrameCtrlAs',
                controllerAs: 'vm'
            });
    }
})();

// iFrame.controller.js
(function() {
    'use strict';
    angular
        .module('IframeTest.iFrameModule', [])
        .controller('IFrameCtrlAs', IFrameCtrlAs);
    IFrameCtrlAs.$inject = ['$stateParams', '$location'];
    function IFrameCtrlAs($stateParams, $location) {
        var vm = this;
        if(!angular.isDefined($stateParams.flag)){
            var reloadPath = $location.path() + '/true';
            $location.path(reloadPath);
        }
        else{
            vm.url = 'form.html';
        }
    }
})();

Form in Iframe 在iframe中的表单

<form method="post" action="">
    <input type="text" id="example1" name="example1" placeholder="sample text">
</form>

I have no idea what causes this issue, probably IE quirk. 我不知道是什么导致了这个问题,可能是IE怪癖。 Anyway, I found that it works just fine if you focus the iframe manually in JS but it must be in a $timeout . 无论如何,我发现如果你手动将iframe集中在JS中,但它必须在$timeout才能正常工作。

I added an ng-init to the iframe that basically focuses the iframe manually. 我向iframe添加了一个ng-init,它基本上是手动聚焦iframe。

.state('iFrame/:flag', {
        url:'/iframe/:flag',
        template: '<h4>Iframe</h4><p><iframe src="{{vm.url}}" ng-init="vm.init()" id="iframeID" frameborder="1" width="100%" scrolling="no"></iframe></p>',
        controller: 'IFrameCtrlAs',
        controllerAs: 'vm'
    });

And here's the controller 这是控制器

function IFrameCtrlAs($stateParams, $location, $timeout) {
    var vm = this;

    if(!angular.isDefined($stateParams.flag)){
        var reloadPath = $location.path() + '/true';
        $location.path(reloadPath);
    }
    else{
        vm.url = 'form.html';

    }
    vm.init = function(){
            $timeout(function(){        
                document.getElementById("iframeID").contentWindow.focus();
                console.log("loaded")
            })
    }
}

Of course, it might be cleaner to wrap this in a directive. 当然,将它包装在指令中可能更清晰。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM