我想将双子座的列表项目滑动。 (即左右和右 – 左)。它完美地用于右键滑动,但是我无法将列表项目滑动到左侧。
我使用$ ionGesture进行左右滑动,当我使用swiperight事件:event($ ionGesture.on(‘swiperight’,scope.reportEvent,elem))时,它也给了我一个警报,但是我不能让它显示左侧的离子选项按钮。
这是我的指令和控制器代码:
.directive('onSwipeRight',function($ionicGesture) { return { restrict : 'A',link : function(scope,elem,attrs) { var gestureType = attrs.gestureType; switch(gestureType) { case 'swipeRight': $ionicGesture.on('swiperight',scope.reportEvent,elem); break; case 'swipeleft': $ionicGesture.on('swipeleft',elem); break; case 'doubletap': $ionicGesture.on('doubletap',elem); break; case 'tap': $ionicGesture.on('tap',elem); break; } } } }) .controller('ChatsCtrl',function($scope,Chats) { // With the new view caching in Ionic,Controllers are only called // when they are recreated or on app start,instead of every page change. // To listen for when this page is active (for example,to refresh data),// listen for the $ionicView.enter event: // //$scope.$on('$ionicView.enter',function(e) { //}); $scope.chats = Chats.all(); $scope.remove = function(chat) { Chats.remove(chat); } $scope.reportEvent = function (event) { alert("hi"); console.log('Reporting : ' + event.type); event.preventDefault(); }; })
这是我的HTML代码。
<ion-view view-title="Chats"> <ion-content> <ion-list can-swipe="true"> <ion-item gesture-type="swipeRight" on-swipe-right="swipeRight()" class="item-remove-animate item-avatar item-icon-right" ng-repeat="chat in chats" type="item-text-wrap" href="#/tab/chats/{{chat.id}}"> <img ng-src="{{chat.face}}"> <h2>{{chat.name}}</h2> <p>{{chat.lastText}}</p> <i class="icon ion-chevron-right icon-accessory"></i> <ion-option-button class="button-assertive" ng-click="share(item)" side="left"> Share </ion-option-button> <ion-option-button class="button-assertive" ng-click="remove(chat)" side="right"> Delete </ion-option-button> </ion-item> </ion-list> </ion-content> </ion-view>
有人可以为我提供具体的解决方案吗?
我已经编辑了离子类lib来做这样的事情。但我不能做一个JSFiddle或代码笔,我会给你链接到我的修改ion.css和ion.bundle.js!
TL; DR
只需用你的代替它,启动一个离子项目空白。并将此HTML放入其中:
<body ng-app="starter"> <ion-pane> <ion-header-bar class="bar-stable"> <h1 class="title">Ionic Blank Starter</h1> </ion-header-bar> <ion-content> <ion-list show-delete="false" can-swipe="true" swipe-direction="both"> <ion-item href="#"> Item 1 <ion-option-button side="right" class="button-light icon ion-heart"></ion-option-button> <ion-option-button side="right" class="button-light icon ion-email"></ion-option-button> <ion-option-button side="left" class="button-assertive icon ion-trash-a"></ion-option-button> </ion-item> <ion-item href="#"> Item 2 <ion-option-button class="button-light icon ion-heart"></ion-option-button> <ion-option-button class="button-light icon ion-email"></ion-option-button> <ion-option-button class="button-assertive icon ion-trash-a"></ion-option-button> </ion-item> </ion-list> </ion-content> </ion-pane> </body>
您可以使用左,右或两者指定擦拭方向。
在离子选择按钮中,您可以给它一个方面。
希望它有帮助,任何你需要的只是问!我会尝试在稍后的代码中注释我的更改代码!
编辑:
我会尽力解释我做了什么
首先更改ionOptionButton指令以创建按钮的div,一个左和右
//added second div with class item-options-left for the left buttons var ITEM_TPL_OPTION_BUTTONS = '<div class="item-options invisible">' + '</div>' + '<div class="item-options-left invisible">' + '</div>'; IonicModule.directive('ionOptionButton',[function () { function stopPropagation(e) { e.stopPropagation(); } return { restrict: 'E',require: '^ionItem',priority: Number.MAX_VALUE,compile: function ($element,$attr) { $attr.$set('class',($attr['class'] || '') + ' button',true); return function ($scope,$element,$attr,itemCtrl) { if (!itemCtrl.optionsContainer) { itemCtrl.optionsContainer = jqLite(ITEM_TPL_OPTION_BUTTONS); itemCtrl.$element.append(itemCtrl.optionsContainer); } //[NEW] if it as an attribute side = 'left' put the button in the left container if ($attr.side === 'left') { angular.element(itemCtrl.optionsContainer[1]).append($element); itemCtrl.$element.addClass('item-left-editable'); } else{ angular.element(itemCtrl.optionsContainer[0]).append($element); itemCtrl.$element.addClass('item-right-editable'); } //Don't bubble click up to main .item $element.on('click',stopPropagation); }; } }; }]);
.item-options-left { position: absolute; top: 0; left: 0; z-index: 1; height: 100%; } .item-options-left .button { height: 100%; border: none; border-radius: 0; display: -webkit-inline-Box; display: -webkit-inline-flex; display: -moz-inline-flex; display: -ms-inline-flexBox; display: inline-flex; -webkit-Box-align: center; -ms-flex-align: center; -webkit-align-items: center; -moz-align-items: center; align-items: center; } .item-options .button:before { margin: 0 auto; }
现在更改离子列表控制器以接受滑动方向属性
.controller('$ionicList',[ '$scope','$attrs','$ionicListDelegate','$ionicHistory',function ($scope,$attrs,$ionicListDelegate,$ionicHistory) { var self = this; //[NEW] object with can-swipe attr and swipe-direction side attr,default direction is left var swipe = { isSwipeable: true,side: 'left' }; var isReorderShown = false; var isDeleteShown = false; var deregisterInstance = $ionicListDelegate._registerInstance( self,$attrs.delegateHandle,function () { return $ionicHistory.isActiveScope($scope); } ); $scope.$on('$destroy',deregisterInstance); self.showReorder = function (show) { if (arguments.length) { isReorderShown = !!show; } return isReorderShown; }; self.showDelete = function (show) { if (arguments.length) { isDeleteShown = !!show; } return isDeleteShown; }; //[NEW] get swipe direction attribute and store it in a variable to access in other function self.canSwipeItems = function (can) { if (arguments.length) { swipe.isSwipeable = !!can; swipe.side = $attrs.swipeDirection; } return swipe; }; self.cloSEOptionButtons = function () { self.listView && self.listView.clearDragEffects(); }; }]);
要结束,你应该用这个替换slideDrag函数,只是在ion.bundle.js中搜索它
//[NEW] add this var to the others in the function var ITEM_OPTIONS_CLASS_RIGHT = 'item-options-left'; var SlideDrag = function (opts) { this.dragThresholdX = opts.dragThresholdX || 10; this.el = opts.el; this.item = opts.item; this.canSwipe = opts.canSwipe; }; SlideDrag.prototype = new DragOp(); SlideDrag.prototype.start = function (e) { var content,buttonsLeft,buttonsRight,offsetX,buttonsLeftWidth,buttonsRightWidth; if (!this.canSwipe().isSwipeable) { return; } if (e.target.classList.contains(ITEM_CONTENT_CLASS)) { content = e.target; } else if (e.target.classList.contains(ITEM_CLASS)) { content = e.target.querySelector('.' + ITEM_CONTENT_CLASS); } else { content = ionic.DomUtil.getParentWithClass(e.target,ITEM_CONTENT_CLASS); } // If we don't have a content area as one of our children (or ourselves),skip if (!content) { return; } // Make sure we aren't animating as we slide content.classList.remove(ITEM_SLIDING_CLASS); // Grab the starting X point for the item (for example,so we can tell whether it is open or closed to start) offsetX = parseFloat(content.style[ionic.CSS.TRANSFORM].replace('translate3d(','').split(',')[0]) || 0; // Grab the buttons buttonsLeft = content.parentNode.querySelector('.' + ITEM_OPTIONS_CLASS); if (!buttonsLeft) { return; } //[NEW] get the Right buttons buttonsRight = content.parentNode.querySelector('.' + ITEM_OPTIONS_CLASS_RIGHT); if (!buttonsRight) { return; } // [NEW] added the same functionality to both sides,to make buttons visible when dragged if(e.gesture.direction === "left") buttonsLeft.classList.remove('invisible'); else buttonsRight.classList.remove('invisible'); //[NEW] added buttonRight and buttonLeft properties to currentDrag buttonsLeftWidth = buttonsLeft.offsetWidth; buttonsRightWidth = buttonsRight.offsetWidth; this._currentDrag = { buttonsLeft: buttonsLeft,buttonsRight: buttonsRight,buttonsLeftWidth: buttonsLeftWidth,buttonsRightWidth: buttonsRightWidth,content: content,startOffsetX: offsetX }; }; /** * Check if this is the same item that was prevIoUsly dragged. */ SlideDrag.prototype.isSameItem = function (op) { if (op._lastDrag && this._currentDrag) { return this._currentDrag.content == op._lastDrag.content; } return false; }; SlideDrag.prototype.clean = function (isInstant) { var lastDrag = this._lastDrag; if (!lastDrag || !lastDrag.content) return; lastDrag.content.style[ionic.CSS.TRANSITION] = ''; lastDrag.content.style[ionic.CSS.TRANSFORM] = ''; if (isInstant) { lastDrag.content.style[ionic.CSS.TRANSITION] = 'none'; makeInvisible(); ionic.requestAnimationFrame(function () { lastDrag.content.style[ionic.CSS.TRANSITION] = ''; }); } else { ionic.requestAnimationFrame(function () { setTimeout(makeInvisible,250); }); } function makeInvisible() { lastDrag.buttonsLeft && lastDrag.buttonsLeft.classList.add('invisible'); lastDrag.buttonsRight && lastDrag.buttonsRight.classList.add('invisible'); } }; SlideDrag.prototype.drag = ionic.animationFrameThrottle(function (e) { var buttonsLeftWidth; var buttonsRightWidth; // We really aren't dragging if (!this._currentDrag) { return; } // Check if we should start dragging. Check if we've dragged past the threshold,// or we are starting from the open state. if (!this._isDragging && ((Math.abs(e.gesture.deltaX) > this.dragThresholdX) || (Math.abs(this._currentDrag.startOffsetX) > 0))) { this._isDragging = true; } if (this._isDragging) { buttonsLeftWidth = this._currentDrag.buttonsLeftWidth; buttonsRightWidth = this._currentDrag.buttonsRightWidth; // Grab the new X point,capping it at zero //[NEW] added right swipe new position if (this.canSwipe().side === 'left' || (this.canSwipe().side === 'both' && e.gesture.direction === 'left')) var newX = Math.min(0,this._currentDrag.startOffsetX + e.gesture.deltaX); else if (this.canSwipe().side === 'right' || (this.canSwipe().side === 'both' && e.gesture.direction === 'right')) var newX = Math.max(0,this._currentDrag.startOffsetX + e.gesture.deltaX); var buttonsWidth = 0; if (e.gesture.direction === 'right') buttonsWidth = buttonsRightWidth; else buttonsWidth = buttonsLeftWidth; // If the new X position is past the buttons,we need to slow down the drag (rubber band style) if (newX < -buttonsWidth) { // Calculate the new X position,capped at the top of the buttons newX = Math.min(-buttonsWidth,-buttonsWidth + (((e.gesture.deltaX + buttonsWidth) * 0.4))); } this._currentDrag.content.$$ionicOptionsOpen = newX !== 0; this._currentDrag.content.style[ionic.CSS.TRANSFORM] = 'translate3d(' + newX + 'px,0)'; this._currentDrag.content.style[ionic.CSS.TRANSITION] = 'none'; } }); SlideDrag.prototype.end = function (e,doneCallback) { var self = this; // There is no drag,just end immediately if (!self._currentDrag) { doneCallback && doneCallback(); return; } // If we are currently dragging,we want to snap back into place // The final resting point X will be the width of the exposed buttons var restingPoint; if (e.gesture.direction === 'left' && (this.canSwipe().side === 'left' || this.canSwipe().side === 'both')) restingPoint = -self._currentDrag.buttonsLeftWidth; if (e.gesture.direction === 'right' && (this.canSwipe().side === 'right' || this.canSwipe().side === 'both')) restingPoint = self._currentDrag.buttonsRightWidth; // Check if the drag didn't clear the buttons mid-point // and we aren't moving fast enough to swipe open var buttonsWidth = 0; if (e.gesture.direction === 'right') buttonsWidth = self._currentDrag.buttonsRightWidth; else buttonsWidth = self._currentDrag.buttonsLeftWidth; if (e.gesture.deltaX > -(buttonsWidth / 2)) { // If we are going left or right but too slow,or going right,go back to resting if ((e.gesture.direction == "left" || e.gesture.direction == "right") && Math.abs(e.gesture.velocityX) < 0.3) { restingPoint = 0; } } ionic.requestAnimationFrame(function () { if (restingPoint === 0) { self._currentDrag.content.style[ionic.CSS.TRANSFORM] = ''; var buttonsLeft = self._currentDrag.buttonsLeft; var buttonsRight = self._currentDrag.buttonsRight; setTimeout(function () { buttonsLeft && buttonsLeft.classList.add('invisible'); buttonsRight && buttonsRight.classList.add('invisible'); },250); } else { self._currentDrag.content.style[ionic.CSS.TRANSFORM] = 'translate3d(' + restingPoint + 'px,0)'; } self._currentDrag.content.style[ionic.CSS.TRANSITION] = ''; // Kill the current drag if (!self._lastDrag) { self._lastDrag = {}; } ionic.extend(self._lastDrag,self._currentDrag); if (self._currentDrag) { self._currentDrag.buttons = null; self._currentDrag.content = null; } self._currentDrag = null; // We are done,notify caller doneCallback && doneCallback(); }); };
我的解决方案并不完美,但它的工作原理。还有其他方法来做这个,我这样做是为了更好地了解Ionic的工作原理以及他们如何做Ionic指令。
欢迎任何反馈,您可以尝试自己制作或改进此功能。