Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度指令,使行可单击链接,导航条件有问题_Javascript_Html_Angular_Typescript_Svg - Fatal编程技术网

Javascript 角度指令,使行可单击链接,导航条件有问题

Javascript 角度指令,使行可单击链接,导航条件有问题,javascript,html,angular,typescript,svg,Javascript,Html,Angular,Typescript,Svg,我有一个angular指令,使HTML元素像链接一样工作。它做得很好。我的问题是让它在某些情况下退出该行为,即当用户单击装饰元素的子元素时。我的行为是正确的,但我真的不喜欢我做事的方式。我希望找到一个更干净、更可靠的解决方案 我有下面的Angular指令使一行充当链接 这很简单。获取url字符串,具有一些事件侦听器,将其大部分大脑委托给服务。为了简洁起见,我将只展示GoToService的关键部分 @Directive({ selector: '[appGoto]' }) export cl

我有一个angular指令,使HTML元素像链接一样工作。它做得很好。我的问题是让它在某些情况下退出该行为,即当用户单击装饰元素的子元素时。我的行为是正确的,但我真的不喜欢我做事的方式。我希望找到一个更干净、更可靠的解决方案

我有下面的Angular指令使一行充当链接

这很简单。获取url字符串,具有一些事件侦听器,将其大部分大脑委托给服务。为了简洁起见,我将只展示
GoToService
的关键部分

@Directive({
  selector: '[appGoto]'
})
export class GotoDirective {

  @Input() appGoto: string;

  constructor(private _goToSvc: GoToService) {
  }

  @HostListener('mouseup', ['$event'])
  @HostListener('keydown', ['$event'])
  OnEvent($event) {
    this._goToSvc.goTo(this.appGoto, $event);
  }

  @HostListener('mousedown', ['$event'])
  OnMouseDown($event) {
    this._goToSvc.markMouseDownLocation($event);
  }

}
这是我目前的解决方案。它很难看,但我会解释为什么我有它。它接受一个事件及其目标,检查事件的目标是否是一个按钮(首先是简单方法)。如果失败,它会检查事件的点击坐标是否与DOM中的某个按钮相交。我同意,布莱

 private _isButtonOrIntersectsWithButton(target, $event): boolean {
    if (target.nodeName.toLowerCase() === 'button') {
      return true;
    }

    const xCoordinate = $event.x;
    const yCoordinate = $event.y;

    const buttons = this._document.getElementsByTagName('button');

    // array functions (ie .some(v => ...) don't work on htmlelement collections, using manual loop
    // tslint:disable-next-line:prefer-for-of
    for (let iButton = 0; iButton < buttons.length; iButton++) {
      const button = buttons[iButton] as HTMLElement;
      const boundary = button.getBoundingClientRect();
      const xRange = [boundary.left < boundary.right ? boundary.left : boundary.right
        , boundary.right > boundary.left ? boundary.right : boundary.left];
      const yRange = [boundary.bottom < boundary.top ? boundary.bottom : boundary.top
        , boundary.top > boundary.bottom ? boundary.top : boundary.bottom];

      if (xCoordinate >= xRange[0] && xCoordinate <= xRange[1] &&
        yCoordinate >= yRange[0] && yCoordinate <= yRange[1]) {
        return true;
      }
    }

    return false;
  }
然而,该解决方案的问题是SVG。我们使用
按钮
,按钮中有一些图标,如
s。它们依次具有
元素,这些元素包含
元素。出于某种原因,
SVGSVGElement
s似乎不知道它们的父级。这很奇怪,因为他们的子元素
SVGPathElements
do。如果事件的目标是一个
,或者它的子
,那么图形遍历将过早终止,并得出结论,该元素不是按钮或按钮的子元素

我还尝试显式地将我希望忽略的元素传递给指令,并对照它们及其所有子元素检查我的目标。这个问题是
=
操作符,虽然对大多数HTML元素都很好,但在比较
元素时却没有效果。也就是说,
目标与等效的
相比将返回false。与
元素相同

目前,笨拙的冲突代码可以工作,但我不喜欢它。我在寻找更好的选择

func isElementButtonOrChildThereof
   if element is button
      return true
   if element is not button
      go get its parent

   if parent is null
      return false

   recurse on parent, default to false if stack gets too deep