0

我正在寻找一个指令,允许单击外部元素以克隆ui-sref其包含的元素之一,以便单击外部元素的行为与单击.cloned元素相同

<div clone-click=".cloned">
    ...
    <a class="cloned" ui-sref="root.a" ng-if="true">example</a>
    <a class="cloned" ui-sref="root.b" ng-if="false">example</a>
    ...
    <a ui-sref="root.c">elsewhere</a>
    ...
</div>

我尝试了触发点击的属性指令

app.directive('cloneClick', function() {
    return {
        restrict: 'A',
        scope: {
            selector: '@cloneClick'
        },
        link: function(scope, element) {
            element.click(function() {
                element.find(scope.selector).not(':disabled').first().click();
            })
        }
    };
})

但这会导致无限循环或其他东西并且不起作用。我怎样才能让它工作?还是有更好的方法来实现这一目标?

4

2 回答 2

1

您没有考虑事件冒泡。就像现在一样,孩子上的任何点击事件都会冒泡到父母,此时你告诉它再次点击相同的元素......因此如果你想要的目标被点击则无限循环

我的建议是防止事件在<a>.

如果<a>单击本身,则让浏览器处理重定向,如果单击父级的任何其他部分,则使用$location服务使用生成的 href 值进行重定向ui-sref

就像是:

link: function(scope, element) {
  var $link = element.find(scope.selector).not(':disabled').first();
  // prevent bubbling on target link
  $link.click(function(e) {
    e.stopImmediatePropagation()
  });

  element.click(function(e) {
    // make sure target link wasn't element clicked
    if (e.target !== $link[0]) { // assumes no child tags in `<a>`
      $location.url($link.attr('href'));
    }
  });
}

您可能需要根据是否使用 html5mode 进行一些调整

编辑:在写完这篇文章后,我突然想到你可以触发点击<a>而不是使用,$location因为事件传播(冒泡)仍然被阻止

于 2016-09-26T21:54:02.523 回答
0
<ANY clone-click=".is-clone-click:not(:disabled):not(.is-disabled)">
    <a class="is-clone-click" ui-sref="root.example">example</a>
</ANY>

我让它像这样工作。一些禁用指针的元素可以通过制作它们的容器来单击,e.target所以我添加.is-no-clone-click到这些容器上以忽略它们。

app.directive('cloneClick', function() {
    var angular = require('angular');
    var ignore = '[href], [ui-sref], [ng-click], .is-no-clone-click, label, input, textarea, button, select, option, optgroup';

    return {
        restrict: 'A',
        scope: {
            selector: '@cloneClick'
        },
        link: function (scope, element) {
            element.click(function(e) {
                if (e.isTrigger) {
                    return;
                }

                var cloned = element.find(scope.selector).first();
                var target = angular.element(e.target);

                if (cloned.length && !cloned.is(target) && !target.is(ignore)) {
                    cloned.click();
                }
            });
        }
    };
});

也可以通过鼠标悬停和 CSS 类添加光标

element.mouseover(function() {
    element.toggleClass('is-pointer', !!element.has(scope.selector).length);
});

但我最终没有使用这个指令,因为我能够创建一个CSS 链接屏蔽解决方案来实际解决我想要做的事情。

于 2016-09-27T23:58:08.440 回答