繁体   English   中英

模态关闭时溢出问题

[英]Overflow issue when modal close

我的应用程序有一个滑动以在列表中显示隐藏操作,用户可以决定删除列表中的项目。

它使用HammerJS来处理滑动事件,使用SweetAlert2来确认动作。

问题是当SweetAlert弹出窗口被解雇时。 一旦用户点击取消并且模态关闭,所有按钮都会突然显示。 整个文件向左移动。

我创建了一个可以重现它的JSFiddle

重现步骤:

  • 在其中一个项目上从右向左滑动以显示操作;
  • 点击“x”删除项目;
  • 单击取消。

我还会粘贴以下代码的内容以供参考:

HTML:

<div ng-app="app" ng-controller="mainCtrl" class="wrapper">
  <div class="items" swipe>
    <div ng-repeat="item in items" class="item">
       <div>
         <div class="item-wrapper">
           <div class="logo">
             <img src="http://2.bp.blogspot.com/-Y2XrnrXJmXs/Uf5Y_bfr4jI/AAAAAAAAALk/ydouC9lEmDE/s1600/Logogap+Logobb.jpg" />
           </div>
           <div class="info">
             <div class="title">
               {{item.title}}
             </div>
             <div class="description">
               {{item.description}}
             </div>
           </div>
         </div>
         <div class="offset-action">
           <button ng-click="delete()">
             X
           </button>
         </div>
       </div>
    </div>
  </div>
</div>

CSS:

body {
  overflow: hidden;
}

.wrapper {
  border: 1px solid grey;
  min-width: 350px;
  max-width: 800px;
}

.items {
  overflow: hidden;
  position: relative;
}

.item {
  padding: 10px 15px;
  position: relative;
  transition: transform 250ms ease-in-out;
}

.item.show-actions {
  transform: translateX(-70px);
}

.item-wrapper {
  align-items: center;
  display: flex;
}

.logo {
  width: 80px;
}

.logo img {
  margin: auto;
  width: 80px;
  height: auto;
}

.offset-action {
  align-items: center;
  background: #B11A1F;
  display: flex;
  position: absolute;
  top: 0;
  bottom: 0;
  text-align: center;
  right: -70px;
  width: 70px;
}

button {
  background: transparent;
  border: none;
  color: white;
  width: 100%;
  height: 100%;
}

使用Javascript:

angular.module('app', [])

.controller('mainCtrl', function($scope) {
    $scope.items = [
    {title: 'Lorem Ipsum', description: 'Consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.'},
    {title: 'Lorem Ipsum', description: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'},
    {title: 'Lorem Ipsum', description: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.'},
    {title: 'Lorem Ipsum', description: 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'}
  ];

  $scope.delete = function() {
    swal({
        title: 'Lorem Ipsum',
      text: 'Dolor sit amet?',
      type: 'error',
      showCancelButton: true
    }).then(function(action) {
        if (action.value) {
        console.log('success');
      } else {
        swal.noop;
      }
    })
  }
})  

.directive('swipe', function() {
    return function(scope) {
    scope.$watch('items', function() {
      var $items = $('.item');
      var show_action = 'show-actions';

      function hideActions() {
        $items.removeClass(show_action);
      }

      $items.each(function() {
        var $item = $(this);

        $item.hammer().on('swipeleft', function() {
          var $this = $(this);
          $items.removeClass(show_action);
          if (!$this.hasClass(show_action)) {
            $this.addClass(show_action);
          }
        });

        $item.hammer().on('tap', hideActions);
      });
    });
  };
});

SweetAlert CSS样式与CSS样式之间存在冲突导致此问题。

一个简单的解决方法是将这个CSS添加到CSS文件的末尾:

.offset-action {
  display: none;
}

.show-actions .offset-action {
  display: flex;
}

https://jsfiddle.net/saeedahmadi/1L7zc25b/

Razvan的回答也将通过在关闭模态后摆脱焦点来完成工作:

https://stackoverflow.com/a/52028143/5939933

“在delete()方法的顶部添加document.activeElement.blur();”

添加document.activeElement.blur(); 在调用swal()之前。

https://jsfiddle.net/yd3gpsvL/

它看起来是由弹出关闭后焦点返回按钮引起的。 这里有一个关于它讨论


或者,您可以使用div而不是button (可选择使用role="button" )来避免按钮的焦点功能。

你的JavaScript需要稍微刷新和document.activeElement.blur(); 在delete()方法的顶部:

angular.module('app', [])

.controller('mainCtrl', function($scope) {
    $scope.items = [
    {title: 'Lorem Ipsum', description: 'Consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.'},
    {title: 'Lorem Ipsum', description: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'},
    {title: 'Lorem Ipsum', description: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.'},
    {title: 'Lorem Ipsum', description: 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'}
  ];

  $scope.delete = function() {
  document.activeElement.blur();
    swal({
        title: 'Lorem Ipsum',
      text: 'Dolor sit amet?',
      type: 'error',
      showCancelButton: true
    }).then(function(action) {
        if (action.value) {
        console.log('success');
      } else {
        swal.noop;
      }
    })
  }
})  

.directive('swipe', function() {
    return function(scope) {
    scope.$watch('items', function() {
      var $items = $('.item');
      var show_action = 'show-actions';

      function showActions() {
          var $this = $(this);
          $items.removeClass(show_action);
          if (!$this.hasClass(show_action)) {
            $this.addClass(show_action);
          }
        }

      function hideActions() {
        $items.removeClass(show_action);
      }

      $items.each(function() {
        var $item = $(this);

        $item.hammer().on('swipeleft', showActions);

        $item.hammer().on('tap', hideActions);
      });
    });
  };
});

这是你的jsFiddle的更新。

一旦用户点击取消并且模态关闭,所有按钮突然可见......

为了克服这一点,我建议仅在swal关闭时删除该类:

  • 删除这一行: $item.hammer().on('tap', hideActions);
  • 在删除调用中添加索引参数:你的html中的ng-click =“delete($ index)”和你的js中的$scope.delete = function (idx) {
  • 几毫秒后删除swal上的类:

     setTimeout(function(){ $('.item').eq(idx).removeClass('show-actions'); }, 200); 

更新的小提琴

UPDATE

谢谢你的回答,不幸的是我需要点按才能隐藏按钮

我更新了小提琴删除jQuery和jQuery for Hammer。

为了隐藏SwaI位关闭按钮我躲上自来水当前按钮和swipeleft再次显示。

 angular.module('app', []).controller('mainCtrl', function ($scope) { $scope.items = [{title: 'Lorem Ipsum', description: 'Consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.'}, {title: 'Lorem Ipsum', description: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'}, {title: 'Lorem Ipsum', description: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.'}, {title: 'Lorem Ipsum', description: 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'}]; $scope.delete = function () { swal({ title: 'Lorem Ipsum', text: 'Dolor sit amet?', type: 'error', showCancelButton: true }).then(function (action) { if (action.value) { console.log('success'); } else { swal.noop; } }) } }).directive('swipe', function () { return function (scope) { scope.$watch('items', function () { document.querySelectorAll('.item').forEach(function (ele, idx) { var mc = new Hammer(ele); mc.on("swipeleft", function (e) { e.target.closest('.item').classList.add('show-actions'); e.target.closest('.item').querySelector('.offset-action').style.display = ''; }).on("tap", function (e) { e.target.closest('.item').classList.remove('show-actions'); e.target.closest('.item').querySelector('.offset-action').style.display = 'none'; }); }); }); }; }); 
 body { overflow: hidden; } .wrapper { border: 1px solid grey; min-width: 350px; max-width: 800px; } .items { overflow: hidden; position: relative; } .item { padding: 10px 15px; position: relative; transition: transform 250ms ease-in-out; } .item.show-actions { transform: translateX(-70px); } .item-wrapper { align-items: center; display: flex; } .logo { width: 80px; } .logo img { margin: auto; width: 80px; height: auto; } .offset-action { align-items: center; background: #B11A1F; display: flex; position: absolute; top: 0; bottom: 0; text-align: center; right: -70px; width: 70px; } button { background: transparent; border: none; color: white; width: 100%; height: 100%; } 
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/7.26.11/sweetalert2.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/7.26.11/sweetalert2.all.js"></script> <div ng-app="app" ng-controller="mainCtrl" class="wrapper"> <div class="items" swipe> <div ng-repeat="item in items" class="item"> <div> <div class="item-wrapper"> <div class="logo"> <img src="http://2.bp.blogspot.com/-Y2XrnrXJmXs/Uf5Y_bfr4jI/AAAAAAAAALk/ydouC9lEmDE/s1600/Logogap+Logobb.jpg"/> </div> <div class="info"> <div class="title"> {{item.title}} </div> <div class="description"> {{item.description}} </div> </div> </div> <div class="offset-action"> <button ng-click="delete()"> X </button> </div> </div> </div> </div> </div> 

暂无
暂无

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

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