通过属性值查找 HTMLCollection 的子项

Finding a child of a HTMLCollection by attribute value

在 angular 指令的单元测试中,我想检查已编译的 DOM:

var element = $compile("<div pr-sizeable='...'></div>")($rootScope);
var children = element[0].children;   // HTMLCollection

expect(children.length).toBeGreaterThan(0);  // that's fine

特别是,我想检查是否存在具有属性 pr-swipe-handler='right'.

的特定子元素

我知道我可以迭代子项及其属性集合,但我确信有更紧张的解决方案。

这是我试过的(参考类似post的this answer):

// TypeError: angular.element(...).querySelector is not a function
angular.element(children).querySelector("[pr-swipe-handler='right']")

// TypeError: children.querySelector is not a function
angular.element(children.querySelector("[pr-swipe-handler='right']"))

这里有一个 plunkr 应该可以帮助你:

http://plnkr.co/edit/YRSgbsGCWGujhiOGV97z?p=preview

代码:

app.controller('MainCtrl', function($compile, $document, $scope) {
  $scope.name = 'World';
  var element = $compile('<div><p></p><div pr-swipe-handler="right"></div></div>')($scope);
  console.log(element[0]);
  console.log(element);
  $document.append(element);
  console.log(document.querySelectorAll('[pr-swipe-handler="right"]'))
});

不能在元素上调用querySelector,但可以在document上调用。您需要将元素附加到测试中的文档中,但无论如何您都应该这样做。

给我指明了正确的方向。只有当 HTMLCollection 的元素是实际 DOM 的一部分时,才有可能使用 querySelector-api 检查 HTMLCollection。因此,有必要将编译后的元素附加到其中。

感谢that answer to a similar question,结果发现编译后的元素必须附加到浏览器DOM中的一个concrete元素,这样作为 body$document 不够:

  var element = $compile('<div><p></p><div pr-swipe-handler="right"></div></div>')($scope);
  var body = $document.find('body');
  $document.append(element);   // That's not enough.
  //body.append(element);      // That works fine.
  var rightHandler = document.querySelectorAll('[pr-swipe-handler="right"]');
  $scope.info = rightHandler.length + ' element(s) found.';

参考这个plunk