mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
ng-click fixes
This commit is contained in:
55
dist/js/ionic-angular.js
vendored
55
dist/js/ionic-angular.js
vendored
@@ -44,7 +44,8 @@ angular.module('ionic.ui', [
|
||||
'ionic.ui.list',
|
||||
'ionic.ui.checkbox',
|
||||
'ionic.ui.toggle',
|
||||
'ionic.ui.radio'
|
||||
'ionic.ui.radio',
|
||||
'ionic.ui.touch'
|
||||
]);
|
||||
|
||||
|
||||
@@ -2564,6 +2565,58 @@ angular.module('ionic.ui.toggle', [])
|
||||
|
||||
})(window.ionic);
|
||||
;
|
||||
|
||||
// Similar to Angular's ngTouch, however it uses Ionic's tap detection
|
||||
// and click simulation. ngClick
|
||||
|
||||
(function(angular, ionic) {'use strict';
|
||||
|
||||
|
||||
angular.module('ionic.ui.touch', [])
|
||||
|
||||
.config(['$provide', function($provide) {
|
||||
$provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
|
||||
// drop the default ngClick directive
|
||||
$delegate.shift();
|
||||
return $delegate;
|
||||
}]);
|
||||
}])
|
||||
|
||||
.directive('ngClick', ['$parse', function($parse) {
|
||||
|
||||
function onTap(e) {
|
||||
// wire this up to Ionic's tap/click simulation
|
||||
ionic.clickElement(e.target, e);
|
||||
}
|
||||
|
||||
// Actual linking function.
|
||||
return function(scope, element, attr) {
|
||||
|
||||
var clickHandler = $parse(attr.ngClick);
|
||||
|
||||
element.on('click', function(event) {
|
||||
scope.$apply(function() {
|
||||
clickHandler(scope, {$event: (event)});
|
||||
});
|
||||
});
|
||||
|
||||
ionic.on('tap', onTap, element[0]);
|
||||
|
||||
// Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
|
||||
// something else nearby.
|
||||
element.onclick = function(event) { };
|
||||
|
||||
scope.$on('$destroy', function () {
|
||||
ionic.off('tap', onTap, element[0]);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
|
||||
})(window.angular, window.ionic);
|
||||
;
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
|
||||
4
dist/js/ionic-angular.min.js
vendored
4
dist/js/ionic-angular.min.js
vendored
File diff suppressed because one or more lines are too long
52
dist/js/ionic.js
vendored
52
dist/js/ionic.js
vendored
@@ -1909,22 +1909,31 @@ window.ionic = {
|
||||
})();
|
||||
|
||||
// polyfill use to simulate native "tap"
|
||||
function inputTapPolyfill(ele, e) {
|
||||
ionic.clickElement = function(ele, e) {
|
||||
// simulate a normal click by running the element's click method then focus on it
|
||||
ele.click();
|
||||
ele.focus();
|
||||
if(ele.disabled) return;
|
||||
|
||||
var c = getCoordinates(e.gesture);
|
||||
var clickEvent = new MouseEvent('click', {
|
||||
clientX: c.x,
|
||||
clientY: c.y,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
ele.dispatchEvent(clickEvent);
|
||||
|
||||
if(ele.tagName === 'INPUT' || ele.tagName === 'TEXTAREA' || ele.tagName === 'SELECT') {
|
||||
ele.focus();
|
||||
} else {
|
||||
ele.blur();
|
||||
}
|
||||
|
||||
// remember the coordinates of this tap so if it happens again we can ignore it
|
||||
recordTapCoordinates(e);
|
||||
recordCoordinates(e);
|
||||
|
||||
// set the last tap time so if a click event quickly happens it knows to ignore it
|
||||
ele.lastTap = Date.now();
|
||||
|
||||
// Stop! HOWEVER!! with touch devices there are still ghostclicks, hence the above logic
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function tapPolyfill(orgEvent) {
|
||||
// if the source event wasn't from a touch event then don't use this polyfill
|
||||
@@ -1951,12 +1960,12 @@ window.ionic = {
|
||||
ele.tagName === "TEXTAREA" ||
|
||||
ele.tagName === "SELECT" ) {
|
||||
|
||||
return inputTapPolyfill(ele, e);
|
||||
return ionic.clickElement(ele, e);
|
||||
|
||||
} else if( ele.tagName === "LABEL" ) {
|
||||
// check if the tapped label has an input associated to it
|
||||
if(ele.control) {
|
||||
return inputTapPolyfill(ele.control, e);
|
||||
return ionic.clickElement(ele.control, e);
|
||||
}
|
||||
}
|
||||
ele = ele.parentElement;
|
||||
@@ -2001,7 +2010,7 @@ window.ionic = {
|
||||
|
||||
// remember the coordinates of this click so if a tap or click in the
|
||||
// same area quickly happened again we can ignore it
|
||||
recordTapCoordinates(e);
|
||||
recordCoordinates(e);
|
||||
}
|
||||
|
||||
function isRecentTap(event) {
|
||||
@@ -2023,7 +2032,7 @@ window.ionic = {
|
||||
}
|
||||
}
|
||||
|
||||
function recordTapCoordinates(event) {
|
||||
function recordCoordinates(event) {
|
||||
var c = getCoordinates(event);
|
||||
if(c.x && c.y) {
|
||||
var tapId = 'ts' + Date.now();
|
||||
@@ -2042,13 +2051,16 @@ window.ionic = {
|
||||
function getCoordinates(event) {
|
||||
// This method can get coordinates for both a mouse click
|
||||
// or a touch depending on the given event
|
||||
var touches = event.touches && event.touches.length ? event.touches : [event];
|
||||
var e = (event.changedTouches && event.changedTouches[0]) ||
|
||||
(event.originalEvent && event.originalEvent.changedTouches &&
|
||||
event.originalEvent.changedTouches[0]) ||
|
||||
touches[0].originalEvent || touches[0];
|
||||
if(event) {
|
||||
var touches = event.touches && event.touches.length ? event.touches : [event];
|
||||
var e = (event.changedTouches && event.changedTouches[0]) ||
|
||||
(event.originalEvent && event.originalEvent.changedTouches &&
|
||||
event.originalEvent.changedTouches[0]) ||
|
||||
touches[0].originalEvent || touches[0];
|
||||
|
||||
return { x: e.clientX, y: e.clientY }; // return the click or touch coordinates
|
||||
if(e) return { x: e.clientX, y: e.clientY };
|
||||
}
|
||||
return { x:0, y:0 };
|
||||
}
|
||||
|
||||
var tapCoordinates = {}; // used to remember coordinates to ignore if they happen again quickly
|
||||
|
||||
4
dist/js/ionic.min.js
vendored
4
dist/js/ionic.min.js
vendored
File diff suppressed because one or more lines are too long
51
js/ext/angular/src/directive/ionicTouch.js
vendored
Normal file
51
js/ext/angular/src/directive/ionicTouch.js
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
// Similar to Angular's ngTouch, however it uses Ionic's tap detection
|
||||
// and click simulation. ngClick
|
||||
|
||||
(function(angular, ionic) {'use strict';
|
||||
|
||||
|
||||
angular.module('ionic.ui.touch', [])
|
||||
|
||||
.config(['$provide', function($provide) {
|
||||
$provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
|
||||
// drop the default ngClick directive
|
||||
$delegate.shift();
|
||||
return $delegate;
|
||||
}]);
|
||||
}])
|
||||
|
||||
.directive('ngClick', ['$parse', function($parse) {
|
||||
|
||||
function onTap(e) {
|
||||
// wire this up to Ionic's tap/click simulation
|
||||
ionic.clickElement(e.target, e);
|
||||
}
|
||||
|
||||
// Actual linking function.
|
||||
return function(scope, element, attr) {
|
||||
|
||||
var clickHandler = $parse(attr.ngClick);
|
||||
|
||||
element.on('click', function(event) {
|
||||
scope.$apply(function() {
|
||||
clickHandler(scope, {$event: (event)});
|
||||
});
|
||||
});
|
||||
|
||||
ionic.on('tap', onTap, element[0]);
|
||||
|
||||
// Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
|
||||
// something else nearby.
|
||||
element.onclick = function(event) { };
|
||||
|
||||
scope.$on('$destroy', function () {
|
||||
ionic.off('tap', onTap, element[0]);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
|
||||
})(window.angular, window.ionic);
|
||||
3
js/ext/angular/src/ionicAngular.js
vendored
3
js/ext/angular/src/ionicAngular.js
vendored
@@ -31,7 +31,8 @@ angular.module('ionic.ui', [
|
||||
'ionic.ui.list',
|
||||
'ionic.ui.checkbox',
|
||||
'ionic.ui.toggle',
|
||||
'ionic.ui.radio'
|
||||
'ionic.ui.radio',
|
||||
'ionic.ui.touch'
|
||||
]);
|
||||
|
||||
|
||||
|
||||
@@ -9,27 +9,46 @@
|
||||
<link rel="stylesheet" href="../../../../dist/css/ionic.css">
|
||||
|
||||
<script src="../../../../dist/js/ionic.js"></script>
|
||||
<script src="../../../../dist/js/angular/angular.js"></script>
|
||||
<script src="../../../../dist/js/angular/angular.min.js"></script>
|
||||
<script src="../../../../dist/js/angular/angular-animate.min.js"></script>
|
||||
<script src="../../../../dist/js/angular/angular-sanitize.min.js"></script>
|
||||
<script src="../../../../dist/js/angular-ui/angular-ui-router.min.js"></script>
|
||||
<script src="../../../../dist/js/ionic-angular.js"></script>
|
||||
<style>
|
||||
td { padding: 2px 4px }
|
||||
input { margin: 10px !important; }
|
||||
.item-content {
|
||||
padding: 2px !important;
|
||||
}
|
||||
.list {
|
||||
margin: 5px !important;
|
||||
}
|
||||
.button {
|
||||
line-height: 18px !important;
|
||||
min-height: 30px !important;
|
||||
}
|
||||
.dot {
|
||||
position: absolute;
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
background-color: red;
|
||||
z-index: 1000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body ng-controller="MyCtrl">
|
||||
<form id="form">
|
||||
<button class="button" ng-click="buttonClick()">button ng-click</button>
|
||||
<div class="div button" ng-click="buttonClick()">div ng-click</div>
|
||||
<button class="button" ng-click="buttonClick()">button</button>
|
||||
<div class="div button" ng-click="buttonClick()">div</div>
|
||||
{{ buttonValue }} -
|
||||
{{ radioModel.data }}
|
||||
|
||||
<div class="list">
|
||||
|
||||
<item ng-repeat="item in menuItems" item="item" ng-click="item.actionItem()">{{item.label}}</item>
|
||||
<item ng-repeat="item in menuItems" item="item" ng-click="item.actionItem()">ng-click="item.actionItem()"</item>
|
||||
|
||||
<item ng-click="itemClick()">ng-click="itemClick()"</item>
|
||||
|
||||
<item ng-click="{{ stringClick }}">ng-click="{{ stringClick }]"</item>
|
||||
|
||||
<radio ng-change="radioChange()"
|
||||
ng-click="radioClick(radioModel.data)"
|
||||
@@ -46,9 +65,7 @@
|
||||
<label class="label1">
|
||||
<input type="radio" name="radio" id="radio1" class="radio1">
|
||||
</label>
|
||||
<label class="label2">
|
||||
<input type="radio" name="radio" id="radio2" class="radio2">
|
||||
</label>
|
||||
<input type="radio" name="radio" id="radio2" class="radio2">
|
||||
|
||||
<button id="clear">Clear</button>
|
||||
<button id="stop">Stop</button>
|
||||
@@ -61,15 +78,20 @@
|
||||
|
||||
.controller('MyCtrl', function($scope) {
|
||||
|
||||
$scope.stringClick = 'stringMethod()';
|
||||
$scope.stringMethod = function() {
|
||||
console.log('{{ stringClick }]', 'click')
|
||||
};
|
||||
|
||||
$scope.itemClick = function() {
|
||||
console.log('itemClick')
|
||||
console.log('itemClick()', 'click')
|
||||
};
|
||||
|
||||
$scope.menuItems = [
|
||||
{
|
||||
label: 'Label',
|
||||
label: 'Item 1',
|
||||
actionItem: function() {
|
||||
console.log('actionItem')
|
||||
console.log('item.actionItem()', 'click')
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -110,8 +132,20 @@
|
||||
document.addEventListener('touchstart', function(e){
|
||||
console.log('touchstart');
|
||||
});
|
||||
document.addEventListener('touchend', function(){
|
||||
document.addEventListener('touchend', function(e){
|
||||
console.log('touchend');
|
||||
if(!e.changedTouches || !e.changedTouches.length) return;
|
||||
|
||||
var dot = document.createElement('div');
|
||||
dot.style.left = (e.changedTouches[0].clientX - 1) + 'px';
|
||||
dot.style.top = (e.changedTouches[0].clientY - 1) + 'px';
|
||||
dot.className = 'dot';
|
||||
dot.id = 'dot' + Date.now();
|
||||
document.body.appendChild(dot);
|
||||
setTimeout(function(){
|
||||
var oldDot = document.getElementById(dot.id);
|
||||
oldDot.parentElement.removeChild(oldDot)
|
||||
}, 3000);
|
||||
});
|
||||
document.addEventListener('mousedown', function(){
|
||||
console.log('mousedown');
|
||||
@@ -165,6 +199,10 @@
|
||||
|
||||
msgs.unshift( msg );
|
||||
|
||||
if(msgs.length > 30) {
|
||||
msgs.splice(30);
|
||||
}
|
||||
|
||||
// do this so we try not to interfere with the device performance
|
||||
clearTimeout(timeId);
|
||||
timeId = setTimeout(function(){
|
||||
|
||||
@@ -29,22 +29,31 @@
|
||||
})();
|
||||
|
||||
// polyfill use to simulate native "tap"
|
||||
function inputTapPolyfill(ele, e) {
|
||||
ionic.clickElement = function(ele, e) {
|
||||
// simulate a normal click by running the element's click method then focus on it
|
||||
ele.click();
|
||||
ele.focus();
|
||||
if(ele.disabled) return;
|
||||
|
||||
var c = getCoordinates(e.gesture);
|
||||
var clickEvent = new MouseEvent('click', {
|
||||
clientX: c.x,
|
||||
clientY: c.y,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
ele.dispatchEvent(clickEvent);
|
||||
|
||||
if(ele.tagName === 'INPUT' || ele.tagName === 'TEXTAREA' || ele.tagName === 'SELECT') {
|
||||
ele.focus();
|
||||
} else {
|
||||
ele.blur();
|
||||
}
|
||||
|
||||
// remember the coordinates of this tap so if it happens again we can ignore it
|
||||
recordTapCoordinates(e);
|
||||
recordCoordinates(e);
|
||||
|
||||
// set the last tap time so if a click event quickly happens it knows to ignore it
|
||||
ele.lastTap = Date.now();
|
||||
|
||||
// Stop! HOWEVER!! with touch devices there are still ghostclicks, hence the above logic
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function tapPolyfill(orgEvent) {
|
||||
// if the source event wasn't from a touch event then don't use this polyfill
|
||||
@@ -71,12 +80,12 @@
|
||||
ele.tagName === "TEXTAREA" ||
|
||||
ele.tagName === "SELECT" ) {
|
||||
|
||||
return inputTapPolyfill(ele, e);
|
||||
return ionic.clickElement(ele, e);
|
||||
|
||||
} else if( ele.tagName === "LABEL" ) {
|
||||
// check if the tapped label has an input associated to it
|
||||
if(ele.control) {
|
||||
return inputTapPolyfill(ele.control, e);
|
||||
return ionic.clickElement(ele.control, e);
|
||||
}
|
||||
}
|
||||
ele = ele.parentElement;
|
||||
@@ -121,7 +130,7 @@
|
||||
|
||||
// remember the coordinates of this click so if a tap or click in the
|
||||
// same area quickly happened again we can ignore it
|
||||
recordTapCoordinates(e);
|
||||
recordCoordinates(e);
|
||||
}
|
||||
|
||||
function isRecentTap(event) {
|
||||
@@ -143,7 +152,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
function recordTapCoordinates(event) {
|
||||
function recordCoordinates(event) {
|
||||
var c = getCoordinates(event);
|
||||
if(c.x && c.y) {
|
||||
var tapId = 'ts' + Date.now();
|
||||
@@ -162,13 +171,16 @@
|
||||
function getCoordinates(event) {
|
||||
// This method can get coordinates for both a mouse click
|
||||
// or a touch depending on the given event
|
||||
var touches = event.touches && event.touches.length ? event.touches : [event];
|
||||
var e = (event.changedTouches && event.changedTouches[0]) ||
|
||||
(event.originalEvent && event.originalEvent.changedTouches &&
|
||||
event.originalEvent.changedTouches[0]) ||
|
||||
touches[0].originalEvent || touches[0];
|
||||
if(event) {
|
||||
var touches = event.touches && event.touches.length ? event.touches : [event];
|
||||
var e = (event.changedTouches && event.changedTouches[0]) ||
|
||||
(event.originalEvent && event.originalEvent.changedTouches &&
|
||||
event.originalEvent.changedTouches[0]) ||
|
||||
touches[0].originalEvent || touches[0];
|
||||
|
||||
return { x: e.clientX, y: e.clientY }; // return the click or touch coordinates
|
||||
if(e) return { x: e.clientX, y: e.clientY };
|
||||
}
|
||||
return { x:0, y:0 };
|
||||
}
|
||||
|
||||
var tapCoordinates = {}; // used to remember coordinates to ignore if they happen again quickly
|
||||
|
||||
Reference in New Issue
Block a user