检查 event.target 是否是 Angular 指令(元素)的子元素
Check if an event.target is a child of an Angular directive (element)
我制作了一个自定义 (ul li) 下拉指令。
- 单击此下拉列表时,将打开列表。
- 再次单击列表时,下拉列表将关闭。
- 单击列表中的选项后,该选项将保存在模型中,下拉列表将关闭。
- 在下拉菜单外单击时,下拉菜单将关闭。
大部分是通过以下代码完成的(关闭和打开部分)。
scope.closeDropDown = function () {
scope.isOpened = false;
$document.unbind('click');
};
//The part for opening and closing is pressed
scope.openDropDown = function () {
if (scope.isOpened) {
//The dropdown is already opened, close it
scope.closeDropDown();
} else {
//Open the dropdown, and add an event handler to the document
scope.isOpened = true;
$document.bind('click', function (evt) {
var target = $(evt.target);
// Check if the document clicked element is a child of the directive
// ATTENTION HERE
if (!target.parents('dropdown').length) {
//Target is not a child element, close the dropdown
scope.closeDropDown();
scope.$apply();
}
});
}
};
仔细查看此处的注意部分。
这里我在整个页面上设置了一个事件监听器。使用它给我带来了以下问题:
示例:当有多个下拉菜单时(例如 A 和 B)。
- 打开下拉菜单 A
- 下拉 A 正确打开
- 打开下拉菜单 B
- 下拉 B 正确打开
- dropdown A 获取文档事件并说明按下的元素是下拉指令的子元素(这是正确的)
- 下拉菜单 A 没有关闭(但我希望它关闭!)
如何检查 event.target
是否是 angular.element
的子项?
现在我只检查 event.target
是否是下拉指令的子项(这仅在使用一个下拉指令时有效)!
根据 Zia Ul Rehman Mughal 的要求,我将使用我自己的 drop-down 指令中使用的答案更新问题。
我出错的地方是在drop-down打开的时候添加了点击监听器,关闭的时候又去掉了。 这是错误的!
您必须在创建对象时添加侦听器,并在对象被销毁时再次删除它们(使用 angular $destroy
事件。
要检查单击的目标是否是元素的子元素,您可以使用 $element.find(event.target)
的 length
属性
function closeDropDown() {
$scope.opened = false;
}
function handleClickEvent(event) {
/* When the clicked element is not a child of the element and
the dropdown is openend, close the dropdown. */
if ($element.find(event.target).length === 0 && $scope.opened) {
closeDropDown();
/* Trigger new digest cycle */
$scope.$apply();
}
};
function setListeners() {
/* Bind click event to the document, close the dropDown if clicked
elsewhere on the page. */
var clickHandler = handleClickEvent;
$document.bind('click', clickHandler);
/* Remove the used event handlers when destroying the object */
$scope.$on('$destroy', function () {
$document.unbind('click', clickHandler);
});
}
我制作了一个自定义 (ul li) 下拉指令。
- 单击此下拉列表时,将打开列表。
- 再次单击列表时,下拉列表将关闭。
- 单击列表中的选项后,该选项将保存在模型中,下拉列表将关闭。
- 在下拉菜单外单击时,下拉菜单将关闭。
大部分是通过以下代码完成的(关闭和打开部分)。
scope.closeDropDown = function () {
scope.isOpened = false;
$document.unbind('click');
};
//The part for opening and closing is pressed
scope.openDropDown = function () {
if (scope.isOpened) {
//The dropdown is already opened, close it
scope.closeDropDown();
} else {
//Open the dropdown, and add an event handler to the document
scope.isOpened = true;
$document.bind('click', function (evt) {
var target = $(evt.target);
// Check if the document clicked element is a child of the directive
// ATTENTION HERE
if (!target.parents('dropdown').length) {
//Target is not a child element, close the dropdown
scope.closeDropDown();
scope.$apply();
}
});
}
};
仔细查看此处的注意部分。
这里我在整个页面上设置了一个事件监听器。使用它给我带来了以下问题:
示例:当有多个下拉菜单时(例如 A 和 B)。
- 打开下拉菜单 A
- 下拉 A 正确打开
- 打开下拉菜单 B
- 下拉 B 正确打开
- dropdown A 获取文档事件并说明按下的元素是下拉指令的子元素(这是正确的)
- 下拉菜单 A 没有关闭(但我希望它关闭!)
如何检查 event.target
是否是 angular.element
的子项?
现在我只检查 event.target
是否是下拉指令的子项(这仅在使用一个下拉指令时有效)!
根据 Zia Ul Rehman Mughal 的要求,我将使用我自己的 drop-down 指令中使用的答案更新问题。
我出错的地方是在drop-down打开的时候添加了点击监听器,关闭的时候又去掉了。 这是错误的!
您必须在创建对象时添加侦听器,并在对象被销毁时再次删除它们(使用 angular $destroy
事件。
要检查单击的目标是否是元素的子元素,您可以使用 $element.find(event.target)
length
属性
function closeDropDown() {
$scope.opened = false;
}
function handleClickEvent(event) {
/* When the clicked element is not a child of the element and
the dropdown is openend, close the dropdown. */
if ($element.find(event.target).length === 0 && $scope.opened) {
closeDropDown();
/* Trigger new digest cycle */
$scope.$apply();
}
};
function setListeners() {
/* Bind click event to the document, close the dropDown if clicked
elsewhere on the page. */
var clickHandler = handleClickEvent;
$document.bind('click', clickHandler);
/* Remove the used event handlers when destroying the object */
$scope.$on('$destroy', function () {
$document.unbind('click', clickHandler);
});
}