jQuery / AngularJS:点击按住在 AngularJS 内部不起作用
jQuery / AngularJS: Tap hold not working inside AngularJS
我很乐意接受建议,因为我在 AngularJS 方面表现不佳。我想隐藏图片框并获取图片的id。
<div data-role="page" id="pageone">
<div data-role="main" class="ui-content">
<div class="my-gallery" itemscope id="grid" >
<div ng-repeat="imageUrl in images" class="col-xs-3">
<p>
<figure itemprop="associatedMedia">
<a href="{{imageUrl}}" name="thumb" id="{{pid[$index]}}" class="thumbnail" itemprop="contentUrl" data-size="800x600">
<img src="" class="img-responsive" id="{{pid[$index]}}" ng-src="{{thumb[$index]}}" style="min-height:50px;height:50px;">
</a>
</figure>
<p>Tap and hold me!</p>
</p>
</div>
</div>
</div>
</div>
这里是隐藏和获取图片id的js代码。
<script>
$(document).on("pagecreate","#pageone",function(){
$("p").on("taphold",function(){
$(this).hide();
});
});
</script>
如果我在下面的表格中使用上面的代码,那么它工作正常。
<div data-role="page" id="pageone">
<div data-role="main" class="ui-content">
<p>If you tap and hold me for one second, I will disappear.</p>
<p>Tap and hold me!</p>
<p>Tap and hold me too!</p>
</div>
</div>
下面是我要实现的目标。用户可以点击任何图像,然后触发事件以从服务器中删除图像。我将为此执行 HTTP 请求,稍后它将隐藏该图像。
目前我什至不能隐藏它。长按事件似乎没有触发。
首先你应该看看这个 post "Thinking in AngularJS" if I have a jQuery background? 这将帮助你了解使用 AngularJS 的重要性。大多数来自 jQuery
的用户并不真正了解 JavaScript 及其异步行为的工作原理。由于简单的 DOM 操作,jQuery
大多数情况下是同步执行的。将 jQuery
与 AngularJS
混合并不是一个好方法,因为 jQuery
操纵了 DOM。更重要的是 -> 无需将 jQuery 与 AngularJS 混合使用。
使用 jQuery
和 AngularJS
可能会破坏 AngularJS
。另一方面 jQuery
很难使用,因为它主要使用 DOM 操作和绑定。在您的情况下,数据绑定失败,因为 DOM 是由 AngularJS
生成的。这是主要问题。您希望与 on('taphold')
绑定的 p
元素在您与 jQuery
绑定时在 DOM 中不可用。这就是您的绑定失败的原因。
请看看这个Fiddle。它重现了你的问题。提示,我将 taphold
事件替换为 click
以使其在 non-mobile 设备上运行,但这并不重要,binding/problem 是相同的。所以你可以在 document is ready
事件后点击移除 p
渲染完成。无法删除使用 AngularJS 呈现的 p
元素,因为 jQuery 数据绑定失败/在元素出现之前很久/或者 $scope
已更改并已被删除由于 E2E 数据绑定,由 AngularJS 重新呈现。
下面的例子展示了如何在AngularJS中绑定事件。此事件称为 longPress,与 taphold
几乎相同。它应该适用于移动和桌面应用程序。
Example Fiddle by using longPress 指令:
查看
<div ng-controller="MyCtrl">
<div ng-repeat="image in images">
<p ng-show="image.show" on-long-press="image.show = false">
{{image.url}}
</p>
</div>
</div>
AngularJS申请
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', ['$scope', '$timeout', function ($scope, $timeout) {
$scope.images = [{
show: true,
url: 'some/url.jpg'
},{
show: true,
url: 'some/url.jpg'
},{
show: true,
url: 'some/url.jpg'
}];
}]);
// taken from https://github.com/puneethrai/angular-long-press/blob/master/dist/angular-long-press.js
myApp.directive('onLongPress', ['$parse', '$timeout', function ($parse, $timeout) {
return {
restrict: 'A',
link: function ($scope, $elm, $attrs) {
var timer;
var timerDuration = (!isNaN($attrs.longPressDuration) && parseInt($attrs.longPressDuration)) || 600;
// By default we prevent long press when user scrolls
var preventLongPressOnScroll = ($attrs.preventOnscrolling ? $attrs.preventOnscrolling === 'true' : true)
// Variable used to prevent long press while scrolling
var touchStartY;
var touchStartX;
var MAX_DELTA = 15;
// Bind touch, mouse and click event
$elm.bind('touchstart', onEnter);
$elm.bind('touchend', onExit);
$elm.bind('mousedown', onEnter);
$elm.bind('mouseup', onExit);
$elm.bind('click', onClick);
// For windows mobile browser
$elm.bind('pointerdown', onEnter);
$elm.bind('pointerup', onExit);
if (preventLongPressOnScroll) {
// Bind touchmove so that we prevent long press when user is scrolling
$elm.bind('touchmove', onMove);
}
function onEnter(evt) {
var functionHandler = $parse($attrs.onLongPress);
// For tracking scrolling
if ((evt.originalEvent || evt).touches) {
touchStartY = (evt.originalEvent || evt).touches[0].screenY;
touchStartX = (evt.originalEvent || evt).touches[0].screenX;
}
//Cancel existing timer
$timeout.cancel(timer);
//To handle click event properly
$scope.longPressSent = false;
// We'll set a timeout for 600 ms for a long press
timer = $timeout(function () {
$scope.longPressSent = true;
// If the touchend event hasn't fired,
// apply the function given in on the element's on-long-press attribute
$scope.$apply(function () {
functionHandler($scope, {
$event: evt
});
});
}, timerDuration);
}
function onExit(evt) {
var functionHandler = $parse($attrs.onTouchEnd);
// Prevent the onLongPress event from firing
$timeout.cancel(timer);
// If there is an on-touch-end function attached to this element, apply it
if ($attrs.onTouchEnd) {
$scope.$apply(function () {
functionHandler($scope, {
$event: evt
});
});
}
}
function onClick(evt) {
//If long press is handled then prevent click
if ($scope.longPressSent && (!$attrs.preventClick || $attrs.preventClick === "true")) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
}
}
function onMove(evt) {
var yPosition = (evt.originalEvent || evt).touches[0].screenY;
var xPosition = (evt.originalEvent || evt).touches[0].screenX;
// If we scrolled, prevent long presses
if (touchStartY !== undefined && touchStartX !== undefined &&
(Math.abs(yPosition - touchStartY) > MAX_DELTA) || Math.abs(xPosition - touchStartX) > MAX_DELTA) {
$timeout.cancel(timer);
}
}
}
};
}]);
我很乐意接受建议,因为我在 AngularJS 方面表现不佳。我想隐藏图片框并获取图片的id。
<div data-role="page" id="pageone">
<div data-role="main" class="ui-content">
<div class="my-gallery" itemscope id="grid" >
<div ng-repeat="imageUrl in images" class="col-xs-3">
<p>
<figure itemprop="associatedMedia">
<a href="{{imageUrl}}" name="thumb" id="{{pid[$index]}}" class="thumbnail" itemprop="contentUrl" data-size="800x600">
<img src="" class="img-responsive" id="{{pid[$index]}}" ng-src="{{thumb[$index]}}" style="min-height:50px;height:50px;">
</a>
</figure>
<p>Tap and hold me!</p>
</p>
</div>
</div>
</div>
</div>
这里是隐藏和获取图片id的js代码。
<script>
$(document).on("pagecreate","#pageone",function(){
$("p").on("taphold",function(){
$(this).hide();
});
});
</script>
如果我在下面的表格中使用上面的代码,那么它工作正常。
<div data-role="page" id="pageone">
<div data-role="main" class="ui-content">
<p>If you tap and hold me for one second, I will disappear.</p>
<p>Tap and hold me!</p>
<p>Tap and hold me too!</p>
</div>
</div>
下面是我要实现的目标。用户可以点击任何图像,然后触发事件以从服务器中删除图像。我将为此执行 HTTP 请求,稍后它将隐藏该图像。
目前我什至不能隐藏它。长按事件似乎没有触发。
首先你应该看看这个 post "Thinking in AngularJS" if I have a jQuery background? 这将帮助你了解使用 AngularJS 的重要性。大多数来自 jQuery
的用户并不真正了解 JavaScript 及其异步行为的工作原理。由于简单的 DOM 操作,jQuery
大多数情况下是同步执行的。将 jQuery
与 AngularJS
混合并不是一个好方法,因为 jQuery
操纵了 DOM。更重要的是 -> 无需将 jQuery 与 AngularJS 混合使用。
使用 jQuery
和 AngularJS
可能会破坏 AngularJS
。另一方面 jQuery
很难使用,因为它主要使用 DOM 操作和绑定。在您的情况下,数据绑定失败,因为 DOM 是由 AngularJS
生成的。这是主要问题。您希望与 on('taphold')
绑定的 p
元素在您与 jQuery
绑定时在 DOM 中不可用。这就是您的绑定失败的原因。
请看看这个Fiddle。它重现了你的问题。提示,我将 taphold
事件替换为 click
以使其在 non-mobile 设备上运行,但这并不重要,binding/problem 是相同的。所以你可以在 document is ready
事件后点击移除 p
渲染完成。无法删除使用 AngularJS 呈现的 p
元素,因为 jQuery 数据绑定失败/在元素出现之前很久/或者 $scope
已更改并已被删除由于 E2E 数据绑定,由 AngularJS 重新呈现。
下面的例子展示了如何在AngularJS中绑定事件。此事件称为 longPress,与 taphold
几乎相同。它应该适用于移动和桌面应用程序。
Example Fiddle by using longPress 指令:
查看
<div ng-controller="MyCtrl">
<div ng-repeat="image in images">
<p ng-show="image.show" on-long-press="image.show = false">
{{image.url}}
</p>
</div>
</div>
AngularJS申请
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', ['$scope', '$timeout', function ($scope, $timeout) {
$scope.images = [{
show: true,
url: 'some/url.jpg'
},{
show: true,
url: 'some/url.jpg'
},{
show: true,
url: 'some/url.jpg'
}];
}]);
// taken from https://github.com/puneethrai/angular-long-press/blob/master/dist/angular-long-press.js
myApp.directive('onLongPress', ['$parse', '$timeout', function ($parse, $timeout) {
return {
restrict: 'A',
link: function ($scope, $elm, $attrs) {
var timer;
var timerDuration = (!isNaN($attrs.longPressDuration) && parseInt($attrs.longPressDuration)) || 600;
// By default we prevent long press when user scrolls
var preventLongPressOnScroll = ($attrs.preventOnscrolling ? $attrs.preventOnscrolling === 'true' : true)
// Variable used to prevent long press while scrolling
var touchStartY;
var touchStartX;
var MAX_DELTA = 15;
// Bind touch, mouse and click event
$elm.bind('touchstart', onEnter);
$elm.bind('touchend', onExit);
$elm.bind('mousedown', onEnter);
$elm.bind('mouseup', onExit);
$elm.bind('click', onClick);
// For windows mobile browser
$elm.bind('pointerdown', onEnter);
$elm.bind('pointerup', onExit);
if (preventLongPressOnScroll) {
// Bind touchmove so that we prevent long press when user is scrolling
$elm.bind('touchmove', onMove);
}
function onEnter(evt) {
var functionHandler = $parse($attrs.onLongPress);
// For tracking scrolling
if ((evt.originalEvent || evt).touches) {
touchStartY = (evt.originalEvent || evt).touches[0].screenY;
touchStartX = (evt.originalEvent || evt).touches[0].screenX;
}
//Cancel existing timer
$timeout.cancel(timer);
//To handle click event properly
$scope.longPressSent = false;
// We'll set a timeout for 600 ms for a long press
timer = $timeout(function () {
$scope.longPressSent = true;
// If the touchend event hasn't fired,
// apply the function given in on the element's on-long-press attribute
$scope.$apply(function () {
functionHandler($scope, {
$event: evt
});
});
}, timerDuration);
}
function onExit(evt) {
var functionHandler = $parse($attrs.onTouchEnd);
// Prevent the onLongPress event from firing
$timeout.cancel(timer);
// If there is an on-touch-end function attached to this element, apply it
if ($attrs.onTouchEnd) {
$scope.$apply(function () {
functionHandler($scope, {
$event: evt
});
});
}
}
function onClick(evt) {
//If long press is handled then prevent click
if ($scope.longPressSent && (!$attrs.preventClick || $attrs.preventClick === "true")) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
}
}
function onMove(evt) {
var yPosition = (evt.originalEvent || evt).touches[0].screenY;
var xPosition = (evt.originalEvent || evt).touches[0].screenX;
// If we scrolled, prevent long presses
if (touchStartY !== undefined && touchStartX !== undefined &&
(Math.abs(yPosition - touchStartY) > MAX_DELTA) || Math.abs(xPosition - touchStartX) > MAX_DELTA) {
$timeout.cancel(timer);
}
}
}
};
}]);