Форма в iframe не может восстановить фокус с помощью Angular и IE11

У меня есть приложение Angular с маршрутом, содержащим iframe. Iframe загружает форму. При первой загрузке маршрута вы можете вводить данные в форму. При втором загрузке маршрута вход в форму не может восстановить фокус при щелчке в IE11. Работает в Chrome и Firefox.

Конкретные шаги для воссоздания заключаются в следующем:

  • Загрузите страницу в IE11
  • Нажмите ссылку iframe
  • Данные могут быть введены в ввод формы
  • Пока курсор все еще находится в форме ввода, нажмите ссылку Iframe
  • Маршрут перезагрузится, очистка формы
  • При нажатии ввода формы для ввода нового текста форма не может восстановить фокус

Я заметил, что если вы нажмете ссылку "Главная" после ввода текста, затем нажмите ссылку iframe, форма которой сможет восстановить фокус, позволяя вводить новый текст.

Ниже приведен пример кода, который воссоздает проблему. Вы можете увидеть, как он работает здесь: http://matthewriley.github.io/iframe-form/.

Обратите внимание, что контроллер заставляет перезагружать маршрут на основе флага. Это должно поддерживать бизнес-требование: если пользователь находится в iframe и хочет щелкнуть ссылку iframe, маршрут будет полностью перезагружен.

Что заставляет IE11 препятствовать тому, чтобы форма в iframe возвращала фокус на второй загрузке?

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.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';
        }
    }
})();

Форма в Iframe

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

Ответ 1

Я понятия не имею, что вызывает эту проблему, возможно, IE quirk. Во всяком случае, я обнаружил, что он работает отлично, если вы фокусируете iframe вручную в JS, но он должен быть в $timeout.

Я добавил ng-init в iframe, который в основном фокусирует 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'
    });

И вот контроллер

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

Конечно, это может быть более чистым, чтобы обернуть это в директиве.