javascript - 单击进入 ace 编辑器时防止模态窗口向上滚动

标签 javascript angularjs angular-ui ace-editor

我有一个 modal包含 ace editor 的窗口.当模态窗口打开时,我向下滚动并在 ace 编辑器 中单击以添加一些文本。然后突然窗口自动向上滚动。我再次向下滚动,在编辑器内部单击,它再次向上滚动。最后,在第三次时,我能够将文本插入到编辑器中。当模态足够高并且编辑器不可见时会发生这种情况,除非您向下滚动它。

这是为什么呢?如何防止这种自动滚动行为?

这是 plunker:http://plnkr.co/edit/NHHkUtrw8SIDIzViNiqw?p=preview

Controller :

angular.module('ui.bootstrap.demo', ['ui.bootstrap', 'ui.ace']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {

  $scope.items = ['item1', 'item2', 'item3'];

  $scope.open = function (size) {

    var modalInstance = $modal.open({
      templateUrl: 'myModalContent.html',
      controller: 'ModalInstanceCtrl',
      size: size,
      resolve: {
        items: function () {
          return $scope.items;
        }
      }
    });

    modalInstance.result.then(function (selectedItem) {
      $scope.selected = selectedItem;
    }, function () {
      $log.info('Modal dismissed at: ' + new Date());
    });
  };
});

// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.

angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {

  $scope.items = items;
  $scope.selected = {
    item: $scope.items[0]
  };

  $scope.editor = {
    text: 'Hello, how are you getting on?'
  };

  $scope.aceOptions = function (mode) {
    return {
      mode: mode,
      onLoad: function (_ace) {
        // HACK to have the ace instance in the scope...
        $scope.modeChanged = function () {
          _ace.getSession().setMode("ace/mode/" + mode);
        };
      }
    };
  };

  $scope.ok = function () {
    $modalInstance.close($scope.selected.item);
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

HTML:

<!doctype html>
<html ng-app="ui.bootstrap.demo">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script>
    <script src="//rawgit.com/ajaxorg/ace-builds/v1.2.6/src-min-noconflict/ace.js"></script>
    <script src="//rawgithub.com/ajaxorg/ace-builds/master/src-min-noconflict/mode-css.js"></script>
    <script src="//rawgithub.com/angular-ui/ui-ace/bower/ui-ace.min.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>

<div ng-controller="ModalDemoCtrl">
    <script type="text/ng-template" id="myModalContent.html">
        <div class="modal-header">
            <h3 class="modal-title">I'm a modal!</h3>
        </div>
        <div class="modal-body">
            <ul>
                <li ng-repeat="item in items">
                    <a ng-click="selected.item = item">{{ item }}</a>
                </li>
            </ul>
            Selected: <b>{{ selected.item }}</b>
            <p>
            Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
            </p>
            <p>Editor:</p>
            <div ui-ace="{
              useWrapMode : true,
              showGutter: true,
              theme:'twilight',
              mode: 'markdown',
              rendererOptions: {
                maxLines: 5,
                minLines: 3
              }
            }" ng-model="editor.text"></div>

        </div>
        <div class="modal-footer">
            <button class="btn btn-primary" ng-click="ok()">OK</button>
            <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
        </div>
    </script>

    <button class="btn btn-default" ng-click="open()">Open me!</button>
    <button class="btn btn-default" ng-click="open('lg')">Large modal</button>
    <button class="btn btn-default" ng-click="open('sm')">Small modal</button>
    <div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
  </body>
</html>

最佳答案

当文本区域获得焦点时,浏览器会将其滚动到 View 中。这会导致各种溢出问题:隐藏元素滚动,单击时编辑器跳转。

Ace 试图通过设置固定位置来防止这种情况发生,以确保文本区域在屏幕上,但在位置规范中存在错误:固定,https://bugs.chromium.org/p/chromium/issues/detail?id=20574这使得 postion:fixed 的工作方式类似于 position:absolute 相对于转换后的元素。

如果您没有办法从 ace 的父元素中删除转换,最好的解决方法是添加 css 以使 .ace_text-input 始终绝对定位。

TLDR 将以下 css 添加到您的页面

.ace_text-input {
    position: absolute!important;
}

关于javascript - 单击进入 ace 编辑器时防止模态窗口向上滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43738707/

相关文章:

javascript - 在 google chrome 插件 (javascript) 中通过 xpath 获取元素值

javascript - 这里是 Android WebView 上的诺基亚 map

javascript - 不同 View 上具有不同值的组件

javascript - Angular-UI( Bootstrap )弹出窗口不起作用?

javascript - 条纹自定义金额字段

javascript - 使用 TypeScript 和 Browserify 如何更简单地导入和使用类

javascript - 单击时更改背景颜色

javascript - 如何将日期范围选择器(AngularJS 自定义指令)链接到 AngularUI-Select2 行为?

angularjs - 如何加载 Angular UI Bootstrap 和依赖项

angularjs - Angular UI 模态中的嵌入不起作用