在指令内加载后访问子元素图像
Access child element images after load inside directive
我正在尝试创建一个指令来对子图像执行缩放。这些图像使用 ng-repeat 嵌入,URL 来自父控制器中的 REST API 调用。以下是指令的嵌入:
这是指令的模板:
<div>
<img image-directive-item ng-src="{{image.url}}" ng-style="{'width': {{image.width}}, 'height': {{image.height}}}" ng-if="image.done" />
</div>
要缩放每个图像,我需要有信息:周围其他图像的宽度/高度。目前,我正在尝试在绑定到图像的子指令中将此信息传递给加载的父级。这是我正在测试的代码:
angular.module("myApp")
.directive("imageDirective", function() {
return {
scope: { images: '=images'},
link: function(scope){
for(var i = 0; i < scope.images.length; i++) {
console.log(scope.images[i].width, scope.images[i].height);
}
},
templateUrl: _contextPath + 'static/html/imageDirective.html'
};
})
.directive("imageDirectiveItem", function() {
return {
link: function(scope, element) {
element.bind("load", function(e) {
scope.image.width = this.naturalWidth;
scope.image.height = this.naturalHeight;
});
}
};
});
图像正在页面上加载,加载回调可以读取尺寸,但是控制台中的输出(来自父指令)对于所有图像都是"未定义的未定义",并且是关于无法将宽度/高度设置为空值的错误。
我想以这种格式执行此操作,因为我需要按照它们在 DOM 中出现的顺序处理图像。但是,我正在努力使两者建立联系,而不会诉诸感觉像黑客的东西。有什么想法吗?
下面新开发人员提供的解决方案对我有用。修改了元素传递给父指令的方式,以便它从 load 回调传递对象,该回调包含我需要的信息。今天学到了一些关于 Angular 的新知识!
angular.module("myApp")
.directive("imageDirective", function() {
return {
scope: { images: '=images'},
controller: function($scope){
var toBeLoaded = $scope.images.length;
this.childLoaded = function(childElement) {
console.log(childElement.naturalWidth, childElement.naturalHeight);
if(--toBeLoaded == 0) {
allChildrenLoaded();
}
};
function allChildrenLoaded() {
console.log("All children loaded.");
}
},
templateUrl: _contextPath + 'static/html/imageGrid.html'
};
})
.directive("imageDirectiveItem", function() {
return {
require: "^imageDirective",
link: function(scope, element, attrs, imageDirectiveCtrl) {
element.bind("load", function() {
var e = this;
scope.$apply(function() {
imageDirectiveCtrl.childLoaded(e);
});
});
}
};
});
控制台输出:
414 415
507 338
366 468
432 395
500 354
507 338
414 414
478 358
507 338
All children loaded.
undefined undefined
,是因为在执行for
循环时尚未加载任何图像。
如果需要在父级中"处理"(如您所说)结果,则在范围公开的对象上设置值可能不是最佳方法。例如,您如何知道它已完成加载?如果没有昂贵的深度$watch
,你怎么知道某些事情已经发生了变化?
我认为,更好的方法是公开子指令可以调用的 API。这是通过在父控制器上公开函数并在子控制器上使用require: "^imageDirective"
来完成的。
.directive("imageDirective", function(){
return {
// .. whatever you currently have
controller: function($scope){
var toBeLoaded = 0;
this.registerChild = function(childElem){
toBeLoaded++;
};
this.childLoaded = function(childElem){
toBeLoaded--;
// do whatever processing you need
};
}
}
})
.directive("imageDirectiveItem", function(){
return {
require: "^imageDirective",
link: function(scope, element, attrs, imageDirectiveCtrl){
imageDirectiveCtrl.registerChild(element);
element.bind("load", function(){
scope.$apply(function(){
imageDirectiveCtrl.childLoaded(element);
})
})
}
}
}
如果您使用的是最新的浏览器(IE>= 11),则可以尝试MutationObserver
。
在链接功能中尝试此操作 imageDirective
.
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var target = mutation.addedNodes && mutation.addNodes[0],
targetScope;
if (target) {
target = angular.element(target);
targetScope = target.scope();
console.log(targetScope.width, targetScope.height)
}
});
});
var config = {childList: true};
observer.observe(element[0], config);
- 如何使用css动画/javascript使具有背景图像的元素出现
- 将包含SVG元素的HTML转换为图像文件
- 如何通过选择器元素将图像添加到javascript下拉警报消息中
- 如何缩放像图像一样的元素
- 在d3中向DOM元素添加了图像,但现在它赢得了't过渡
- 普通JS:使80%宽度元素100%IF包含一个图像
- 无法为HTML5中具有画布和图像的可拖动元素设置“拖动图像”
- 将href中的图像替换为其他元素中的图像
- 单击即可更改元素中的图像
- 不显示为表单元素的图像输入按钮的动态创建和appendChild
- Javascript获取元素背景图像,但消除了“;url()”;
- 使用漂亮的照片点击另一个元素显示图像
- 将图像附加到没有 id 或值的 td 元素
- 在指令内加载后访问子元素图像
- 在有限的时间内暂时禁用元素/图像的实时点击
- 在镶边中选择渲染的图片元素图像
- 在执行之前,请检查是否已加载子元素(图像)
- 如何更改单击时HTML元素(图像)的顺序
- 如何在Raphael.js中仅针对纸张的第二元素(图像或矩形)
- 我想用html/stylesheet中的文本来更改元素图像