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

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

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

  1. загрузить страницу в IE11
  2. нажмите iframe link
  3. данные можно ввести в форму ввод
  4. пока курсор все еще находится в форме ввода, щелкните ссылку Iframe
  5. маршрут будет перезагружен, очистив форму
  6. при нажатии на ввод формы для ввода нового текста форма не может восстановить фокус

Я заметил, что если вы нажмете домашнюю ссылку после ввода текста, затем нажмите ссылку 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>

Угловое 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';
        }
    }
})();

форма в 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")
            })
    }
}

конечно, было бы чище обернуть это в директиву.