Item options drag fix

This commit is contained in:
Max Lynch
2013-11-06 21:24:15 -06:00
parent 0fc1731b1d
commit 703a745179
3 changed files with 49 additions and 35 deletions

41
dist/js/ionic.js vendored
View File

@ -3115,6 +3115,14 @@ window.ionic = {
(function(ionic) { (function(ionic) {
'use strict'; 'use strict';
var ITEM_CLASS = 'item';
var ITEM_CONTENT_CLASS = 'item-content';
var ITEM_SLIDING_CLASS = 'item-sliding';
var ITEM_OPTIONS_CLASS = 'item-options';
var ITEM_PLACEHOLDER_CLASS = 'item-placeholder';
var ITEM_REORDERING_CLASS = 'item-reordering';
var ITEM_DRAG_CLASS = 'item-drag';
var DragOp = function() {}; var DragOp = function() {};
DragOp.prototype = { DragOp.prototype = {
start: function(e) { start: function(e) {
@ -3251,10 +3259,10 @@ window.ionic = {
SlideDrag.prototype.start = function(e) { SlideDrag.prototype.start = function(e) {
var content, buttons, offsetX, buttonsWidth; var content, buttons, offsetX, buttonsWidth;
if(e.target.classList.contains('list-item-content')) { if(e.target.classList.contains(ITEM_CONTENT_CLASS)) {
content = e.target; content = e.target;
} else if(e.target.classList.contains('list-item')) { } else if(e.target.classList.contains(ITEM_CLASS)) {
content = e.target.querySelector('.list-item-content'); content = e.target.querySelector('.' + ITEM_CONTENT_CLASS);
} }
// If we don't have a content area as one of our children (or ourselves), skip // If we don't have a content area as one of our children (or ourselves), skip
@ -3263,13 +3271,13 @@ window.ionic = {
} }
// Make sure we aren't animating as we slide // Make sure we aren't animating as we slide
content.classList.remove('list-item-sliding'); 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) // 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.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0; offsetX = parseFloat(content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0;
// Grab the buttons // Grab the buttons
buttons = content.parentNode.querySelector('.list-item-buttons'); buttons = content.parentNode.querySelector('.' + ITEM_OPTIONS_CLASS);
if(!buttons) { if(!buttons) {
return; return;
} }
@ -3348,7 +3356,7 @@ window.ionic = {
var onRestingAnimationEnd = function(e) { var onRestingAnimationEnd = function(e) {
if(e.propertyName == '-webkit-transform') { if(e.propertyName == '-webkit-transform') {
content.classList.remove('list-item-sliding'); content.classList.remove(ITEM_SLIDING_CLASS);
} }
e.target.removeEventListener('webkitTransitionEnd', onRestingAnimationEnd); e.target.removeEventListener('webkitTransitionEnd', onRestingAnimationEnd);
}; };
@ -3356,7 +3364,7 @@ window.ionic = {
window.requestAnimationFrame(function() { window.requestAnimationFrame(function() {
var currentX = parseFloat(_this._currentDrag.content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0; var currentX = parseFloat(_this._currentDrag.content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0;
if(currentX !== restingPoint) { if(currentX !== restingPoint) {
_this._currentDrag.content.classList.add('list-item-sliding'); _this._currentDrag.content.classList.add(ITEM_SLIDING_CLASS);
_this._currentDrag.content.addEventListener('webkitTransitionEnd', onRestingAnimationEnd); _this._currentDrag.content.addEventListener('webkitTransitionEnd', onRestingAnimationEnd);
} }
_this._currentDrag.content.style.webkitTransform = 'translate3d(' + restingPoint + 'px, 0, 0)'; _this._currentDrag.content.style.webkitTransform = 'translate3d(' + restingPoint + 'px, 0, 0)';
@ -3386,11 +3394,11 @@ window.ionic = {
var placeholder = this.el.cloneNode(true); var placeholder = this.el.cloneNode(true);
placeholder.classList.add('list-item-placeholder'); placeholder.classList.add(ITEM_PLACEHOLDER_CLASS);
this.el.parentNode.insertBefore(placeholder, this.el); this.el.parentNode.insertBefore(placeholder, this.el);
this.el.classList.add('list-item-reordering'); this.el.classList.add(ITEM_REORDERING_CLASS);
this._currentDrag = { this._currentDrag = {
@ -3457,7 +3465,7 @@ window.ionic = {
var placeholder = this._currentDrag.placeholder; var placeholder = this._currentDrag.placeholder;
// Reposition the element // Reposition the element
this.el.classList.remove('list-item-reordering'); this.el.classList.remove(ITEM_REORDERING_CLASS);
this.el.style.top = 0; this.el.style.top = 0;
var finalPosition = ionic.DomUtil.getChildIndex(placeholder); var finalPosition = ionic.DomUtil.getChildIndex(placeholder);
@ -3499,14 +3507,12 @@ window.ionic = {
this._initDrag(); this._initDrag();
// Listen for drag and release events // Listen for drag and release events
/*
window.ionic.onGesture('drag', function(e) { window.ionic.onGesture('drag', function(e) {
_this._handleDrag(e); _this._handleDrag(e);
}, this.el); }, this.el);
window.ionic.onGesture('release', function(e) { window.ionic.onGesture('release', function(e) {
_this._handleEndDrag(e); _this._handleEndDrag(e);
}, this.el); }, this.el);
*/
}, },
/** /**
* Called to tell the list to stop refreshing. This is useful * Called to tell the list to stop refreshing. This is useful
@ -3585,7 +3591,7 @@ window.ionic = {
// Return the list item from the given target // Return the list item from the given target
_getItem: function(target) { _getItem: function(target) {
while(target) { while(target) {
if(target.classList.contains('list-item')) { if(target.classList.contains(ITEM_CLASS)) {
return target; return target;
} }
target = target.parentNode; target = target.parentNode;
@ -3597,14 +3603,13 @@ window.ionic = {
_startDrag: function(e) { _startDrag: function(e) {
ionic.views.ListView.__super__._startDrag.call(this, e); ionic.views.ListView.__super__._startDrag.call(this, e);
return;
var _this = this; var _this = this;
this._isDragging = false; this._isDragging = false;
// Check if this is a reorder drag // Check if this is a reorder drag
if(ionic.DomUtil.getParentOrSelfWithClass(e.target, 'list-item-drag') && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) { if(ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_DRAG_CLASS) && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) {
var item = this._getItem(e.target); var item = this._getItem(e.target);
if(item) { if(item) {
@ -3614,6 +3619,7 @@ window.ionic = {
} }
// Check if this is a "pull down" drag for pull to refresh // Check if this is a "pull down" drag for pull to refresh
/*
else if(e.gesture.direction == 'down') { else if(e.gesture.direction == 'down') {
this._dragOp = new PullToRefreshDrag({ this._dragOp = new PullToRefreshDrag({
el: this.el, el: this.el,
@ -3629,11 +3635,13 @@ window.ionic = {
}); });
this._dragOp.start(e); this._dragOp.start(e);
} }
*/
// Or check if this is a swipe to the side drag // Or check if this is a swipe to the side drag
else if(e.gesture.direction == 'left' || e.gesture.direction == 'right') { else if(e.gesture.direction == 'left' || e.gesture.direction == 'right') {
this._dragOp = new SlideDrag({ el: this.el }); this._dragOp = new SlideDrag({ el: this.el });
this._dragOp.start(e); this._dragOp.start(e);
e.preventDefault();
} }
}, },
@ -3642,7 +3650,6 @@ window.ionic = {
ionic.views.ListView.__super__._handleEndDrag.call(this, e); ionic.views.ListView.__super__._handleEndDrag.call(this, e);
var _this = this; var _this = this;
return;
if(!this._dragOp) { if(!this._dragOp) {
this._initDrag(); this._initDrag();
return; return;
@ -3660,8 +3667,8 @@ window.ionic = {
ionic.views.ListView.__super__._handleDrag.call(this, e); ionic.views.ListView.__super__._handleDrag.call(this, e);
var _this = this, content, buttons; var _this = this, content, buttons;
return;
if(!this._dragOp) { if(!this._dragOp) {
e.preventDefault();
this._startDrag(e); this._startDrag(e);
if(!this._dragOp) { return; } if(!this._dragOp) { return; }
} }

View File

@ -22,7 +22,7 @@
<h1 class="title">Modal</h1> <h1 class="title">Modal</h1>
<button class="button button-clear button-primary" ng-click="closeModal()">Cancel</button> <button class="button button-clear button-primary" ng-click="closeModal()">Cancel</button>
</header> </header>
<content has-header="true"> <content>
Realllllyyy long content Realllllyyy long content
<div style="height: 2000px; background-color: red;"></div> <div style="height: 2000px; background-color: red;"></div>
</content> </content>

View File

@ -1,6 +1,14 @@
(function(ionic) { (function(ionic) {
'use strict'; 'use strict';
var ITEM_CLASS = 'item';
var ITEM_CONTENT_CLASS = 'item-content';
var ITEM_SLIDING_CLASS = 'item-sliding';
var ITEM_OPTIONS_CLASS = 'item-options';
var ITEM_PLACEHOLDER_CLASS = 'item-placeholder';
var ITEM_REORDERING_CLASS = 'item-reordering';
var ITEM_DRAG_CLASS = 'item-drag';
var DragOp = function() {}; var DragOp = function() {};
DragOp.prototype = { DragOp.prototype = {
start: function(e) { start: function(e) {
@ -137,10 +145,10 @@
SlideDrag.prototype.start = function(e) { SlideDrag.prototype.start = function(e) {
var content, buttons, offsetX, buttonsWidth; var content, buttons, offsetX, buttonsWidth;
if(e.target.classList.contains('list-item-content')) { if(e.target.classList.contains(ITEM_CONTENT_CLASS)) {
content = e.target; content = e.target;
} else if(e.target.classList.contains('list-item')) { } else if(e.target.classList.contains(ITEM_CLASS)) {
content = e.target.querySelector('.list-item-content'); content = e.target.querySelector('.' + ITEM_CONTENT_CLASS);
} }
// If we don't have a content area as one of our children (or ourselves), skip // If we don't have a content area as one of our children (or ourselves), skip
@ -149,13 +157,13 @@
} }
// Make sure we aren't animating as we slide // Make sure we aren't animating as we slide
content.classList.remove('list-item-sliding'); 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) // 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.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0; offsetX = parseFloat(content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0;
// Grab the buttons // Grab the buttons
buttons = content.parentNode.querySelector('.list-item-buttons'); buttons = content.parentNode.querySelector('.' + ITEM_OPTIONS_CLASS);
if(!buttons) { if(!buttons) {
return; return;
} }
@ -234,7 +242,7 @@
var onRestingAnimationEnd = function(e) { var onRestingAnimationEnd = function(e) {
if(e.propertyName == '-webkit-transform') { if(e.propertyName == '-webkit-transform') {
content.classList.remove('list-item-sliding'); content.classList.remove(ITEM_SLIDING_CLASS);
} }
e.target.removeEventListener('webkitTransitionEnd', onRestingAnimationEnd); e.target.removeEventListener('webkitTransitionEnd', onRestingAnimationEnd);
}; };
@ -242,7 +250,7 @@
window.requestAnimationFrame(function() { window.requestAnimationFrame(function() {
var currentX = parseFloat(_this._currentDrag.content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0; var currentX = parseFloat(_this._currentDrag.content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0;
if(currentX !== restingPoint) { if(currentX !== restingPoint) {
_this._currentDrag.content.classList.add('list-item-sliding'); _this._currentDrag.content.classList.add(ITEM_SLIDING_CLASS);
_this._currentDrag.content.addEventListener('webkitTransitionEnd', onRestingAnimationEnd); _this._currentDrag.content.addEventListener('webkitTransitionEnd', onRestingAnimationEnd);
} }
_this._currentDrag.content.style.webkitTransform = 'translate3d(' + restingPoint + 'px, 0, 0)'; _this._currentDrag.content.style.webkitTransform = 'translate3d(' + restingPoint + 'px, 0, 0)';
@ -272,11 +280,11 @@
var placeholder = this.el.cloneNode(true); var placeholder = this.el.cloneNode(true);
placeholder.classList.add('list-item-placeholder'); placeholder.classList.add(ITEM_PLACEHOLDER_CLASS);
this.el.parentNode.insertBefore(placeholder, this.el); this.el.parentNode.insertBefore(placeholder, this.el);
this.el.classList.add('list-item-reordering'); this.el.classList.add(ITEM_REORDERING_CLASS);
this._currentDrag = { this._currentDrag = {
@ -343,7 +351,7 @@
var placeholder = this._currentDrag.placeholder; var placeholder = this._currentDrag.placeholder;
// Reposition the element // Reposition the element
this.el.classList.remove('list-item-reordering'); this.el.classList.remove(ITEM_REORDERING_CLASS);
this.el.style.top = 0; this.el.style.top = 0;
var finalPosition = ionic.DomUtil.getChildIndex(placeholder); var finalPosition = ionic.DomUtil.getChildIndex(placeholder);
@ -385,14 +393,12 @@
this._initDrag(); this._initDrag();
// Listen for drag and release events // Listen for drag and release events
/*
window.ionic.onGesture('drag', function(e) { window.ionic.onGesture('drag', function(e) {
_this._handleDrag(e); _this._handleDrag(e);
}, this.el); }, this.el);
window.ionic.onGesture('release', function(e) { window.ionic.onGesture('release', function(e) {
_this._handleEndDrag(e); _this._handleEndDrag(e);
}, this.el); }, this.el);
*/
}, },
/** /**
* Called to tell the list to stop refreshing. This is useful * Called to tell the list to stop refreshing. This is useful
@ -471,7 +477,7 @@
// Return the list item from the given target // Return the list item from the given target
_getItem: function(target) { _getItem: function(target) {
while(target) { while(target) {
if(target.classList.contains('list-item')) { if(target.classList.contains(ITEM_CLASS)) {
return target; return target;
} }
target = target.parentNode; target = target.parentNode;
@ -483,14 +489,13 @@
_startDrag: function(e) { _startDrag: function(e) {
ionic.views.ListView.__super__._startDrag.call(this, e); ionic.views.ListView.__super__._startDrag.call(this, e);
return;
var _this = this; var _this = this;
this._isDragging = false; this._isDragging = false;
// Check if this is a reorder drag // Check if this is a reorder drag
if(ionic.DomUtil.getParentOrSelfWithClass(e.target, 'list-item-drag') && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) { if(ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_DRAG_CLASS) && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) {
var item = this._getItem(e.target); var item = this._getItem(e.target);
if(item) { if(item) {
@ -500,6 +505,7 @@
} }
// Check if this is a "pull down" drag for pull to refresh // Check if this is a "pull down" drag for pull to refresh
/*
else if(e.gesture.direction == 'down') { else if(e.gesture.direction == 'down') {
this._dragOp = new PullToRefreshDrag({ this._dragOp = new PullToRefreshDrag({
el: this.el, el: this.el,
@ -515,11 +521,13 @@
}); });
this._dragOp.start(e); this._dragOp.start(e);
} }
*/
// Or check if this is a swipe to the side drag // Or check if this is a swipe to the side drag
else if(e.gesture.direction == 'left' || e.gesture.direction == 'right') { else if(e.gesture.direction == 'left' || e.gesture.direction == 'right') {
this._dragOp = new SlideDrag({ el: this.el }); this._dragOp = new SlideDrag({ el: this.el });
this._dragOp.start(e); this._dragOp.start(e);
e.preventDefault();
} }
}, },
@ -528,7 +536,6 @@
ionic.views.ListView.__super__._handleEndDrag.call(this, e); ionic.views.ListView.__super__._handleEndDrag.call(this, e);
var _this = this; var _this = this;
return;
if(!this._dragOp) { if(!this._dragOp) {
this._initDrag(); this._initDrag();
return; return;
@ -546,8 +553,8 @@
ionic.views.ListView.__super__._handleDrag.call(this, e); ionic.views.ListView.__super__._handleDrag.call(this, e);
var _this = this, content, buttons; var _this = this, content, buttons;
return;
if(!this._dragOp) { if(!this._dragOp) {
e.preventDefault();
this._startDrag(e); this._startDrag(e);
if(!this._dragOp) { return; } if(!this._dragOp) { return; }
} }