最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Form in iframe unable to regain focus with Angular and IE11 - Stack Overflow

programmeradmin6浏览0评论

I have an Angular app with a route that contains an iframe. The iframe loads a form. 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. Works in Chrome and Firefox.

The specific steps to recreate are as follows:

  1. Load page in IE11
  2. Click Iframe link
  3. Data can be entered into form input
  4. While the cursor is still in the form input, click the Iframe link
  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.

Below is sample code that recreates the issue. You can see it running here: /.

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.

What causes IE11 to prevent the form in the iframe from regaining focus on the second load?

HTML Page

<!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/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
        <script src="//cdnjs.cloudflare/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

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

I have an Angular app with a route that contains an iframe. The iframe loads a form. 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. Works in Chrome and Firefox.

The specific steps to recreate are as follows:

  1. Load page in IE11
  2. Click Iframe link
  3. Data can be entered into form input
  4. While the cursor is still in the form input, click the Iframe link
  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.

Below is sample code that recreates the issue. You can see it running here: 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.

What causes IE11 to prevent the form in the iframe from regaining focus on the second load?

HTML Page

<!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./ajax/libs/angular.js/1.4.3/angular.min.js"></script>
        <script src="//cdnjs.cloudflare./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

<form method="post" action="">
    <input type="text" id="example1" name="example1" placeholder="sample text">
</form>
Share Improve this question edited Aug 17, 2015 at 18:44 Aaron McIver 24.7k5 gold badges61 silver badges90 bronze badges asked Aug 14, 2015 at 16:38 Matt RileyMatt Riley 2931 gold badge2 silver badges16 bronze badges 2
  • With developer tools panel open it works, without if you use tab key to move focus it works. Mouse click doen't work, very strange behavior, but with right click -> select all option you can gain the focus. Try to add a simple script on iframe code that manually set the focus on first input text – fantarama Commented Aug 19, 2015 at 9:45
  • There's an outside chance this is a bug within IE itself. A similar issue has been reported on Microsoft Connect: IE 10/11 IFrame removal causes loss of the ability to focus input elements https://connect.microsoft./IE/feedback/details/1613994/ie-10-11-iframe-removal-causes-loss-of-the-ability-to-focus-input-elements – Matt Riley Commented Aug 19, 2015 at 15:02
Add a ment  | 

1 Answer 1

Reset to default 8 +200

I have no idea what causes this issue, probably IE quirk. Anyway, I found that it works just fine if you focus the iframe manually in JS but it must be in a $timeout.

I added an ng-init to the iframe that basically focuses the iframe manually.

.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.

发布评论

评论列表(0)

  1. 暂无评论