Проблема переполнения при модальном закрытии - PullRequest
0 голосов
/ 24 августа 2018

Мое приложение имеет функцию отображения скрытых действий в списке, где пользователи могут решить удалить элементы в списке.

Он использует 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);
      });
    });
  };
});

Ответы [ 4 ]

0 голосов
/ 26 августа 2018

Как только пользователь нажимает «Отмена» и модальное закрытие, все кнопки внезапно становятся видимыми ...

Чтобы преодолеть этот пункт, я предлагаю удалить класс только после закрытия ласточки:

  • удалить эту строку: $item.hammer().on('tap', hideActions);
  • добавить параметр индекса к вызову удаления: ng-click = "delete ($ index)" в вашем html и $scope.delete = function (idx) { в вашем js
  • удалить класс при закрытии ласты через несколько миллисекунд:

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

Обновленная скрипка

UPDATE

Спасибо за ваш ответ, к сожалению, мне нужен тап, чтобы скрыть кнопку

Я обновил скрипку , удалив jQuery и jQuery for Hammer.

Чтобы скрыть кнопки на закрытии swal, я скрываю текущую кнопку на , нажмите и снова показываю на 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>
0 голосов
/ 26 августа 2018

Добавить document.activeElement.blur(); перед вызовом swal().

https://jsfiddle.net/yd3gpsvL/

Похоже, что причиной является возврат фокуса к кнопке после закрытия всплывающего окна. Здесь обсуждается .


Кроме того, вы можете использовать div вместо button (опционально с role="button"), чтобы избежать функциональности фокуса кнопки.

0 голосов
/ 26 августа 2018

Ваш 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 .

0 голосов
/ 26 августа 2018

Существует конфликт между стилями SweetAlert CSS и вашими стилями CSS, вызывающий эту проблему.

Простым исправлением будет добавление этого CSS в конец вашего CSS-файла:

.offset-action {
  display: none;
}

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

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

Также ответ Развана сделает свою работу, избавившись от фокуса после закрытия модального окна:

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

"добавление document.activeElement.blur (); вверху метода delete ()"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...