AngularJs - $watch仅在Chrome Developer Tools打开时有效
AngularJs - $watch only works when Chrome Developer Tools is open
我正在尝试将$watch附加到一个指令上,该指令监视元素的高度和宽度何时更改,以便它可以使用高度和宽度在图像顶部居中。
这是我的应用程序.js代码:
app.directive('centerElement', function ($timeout) {
return function (scope, element, attrs) {
scope.$watch(function () {
return {
'h': element[0].offsetHeight,
'w': element[0].offsetWidth
};
},
function (newValue, oldValue) {
var elementHeight = newValue.h;
var elementWidth = newValue.w;
/*To account for rounding errors and not loop*/
if(elementHeight % 2 === 0)
{
element.css('margin-top', '-' + ((elementHeight) / 2) + 'px');
}
else
{
element.css('margin-top', '-' + ((elementHeight + 1) / 2) + 'px');
}
if(elementWidth % 2 === 0)
{
element.css('margin-left', '-' + ((elementWidth) / 2) + 'px');
}
else
{
element.css('margin-left', '-' + ((elementWidth + 1) / 2) + 'px');
}
}, true);
element.bind('centerElement', function () {
scope.$apply();
});
};
});
这是我的 html 代码:
<div class="row relativePosition">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 noPadding">
<img id="getStartedGiveGiftImage" ng-src="{{homeCtrl.getHomeImageBySectionName('getStartedGiveGift').url}}"/>
</div>
<div id="getStartedGiveGiftCol" class="absolutePosition" center-element>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12">
<div class="getStartedGiveGiftText headingTitle">
Swapping, Sharing,
<div class="getStartedGiveGiftText text-right">
and Caring
</div>
</div>
</div>
<div id="getStartedGiveGiftButtons" class="col-lg-4 col-md-4 col-sm-4 col-xs-12 text-right">
<div>
<a id="getStartedGiveGiftButton1" class="btn btn-default text-right redBackgroundGradient" href="{{homeCtrl.getPage('Get Started').route}}">Get Started</a>
</div>
<div>
<a id="getStartedGiveGiftButton2" class="btn btn-default getStartedGiveGiftButton greenBackgroundGradient text-right text-white" href="{{homeCtrl.getPage('Give a Gift').route}}">Give a Gift</a>
</div>
</div>
</div>
</div>
我已经将 .getStartedGiveGiftCol 的 css 设置为
#getStartedGiveGiftCol {
top: 50%;
left: 50%; }
将margin-top
值和margin-left
值添加到高度的一半和宽度的一半,将元素直接放置在图像的中心。
当我在未打开开发人员工具的情况下在谷歌浏览器中运行该应用程序时,当加载图像并在元素上调整高度和宽度时,不会调用 centerElement 指令手表,但是当我通过逐步运行应用程序时 Chrome 开发人员工具,元素在图像上居中就好了。 当我在没有它的情况下运行应用程序后打开开发人员工具时,没有错误。
另外,我尝试在Internet Explorer,Edge和Firefox中运行该应用程序。 Internet Explorer和Firefox的行为方式都与Chrome相同,但是,Edge是唯一以应有的方式将图像居中的浏览器。
我宁愿不使用$watch,因为它可能存在性能问题,但从我在文档和谷歌上所做的研究来看,我无法找到另一种方法来做到这一点,但我对想法非常开放。 我试图在等待图像加载然后居中元素时找到一些东西,但我没有运气。 我将在应用程序的其他部分重复此指令,因此不必使用$watch会很棒。
我对 angularJS 很陌生,所以非常感谢任何帮助。 我也是关于stackoverflow的新手,所以如果您需要更多信息,请告诉我。
谢谢!
编辑:我为 image 创建了另一个指令,它在加载时会调用 scope.$digest()。 这似乎有所帮助,但是当我多次刷新页面时,有时它仍然不起作用。 有什么想法吗?
这是我添加的指令:
app.directive('imageOnload', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
scope.$digest();
});
element.bind('error', function(){
alert('image could not be loaded');
});
}
};
});
我自己想通了。 我需要在我的centerElement
指令中添加$timeout();
。 这将强制在完成当前$digest
时进行$scope.$apply();
,以便将$watch
中所做的更改实际应用于页面。
我的指令如下:
app.directive('centerElement', function ($timeout) {
return function (scope, element, attrs) {
scope.$watch(function () {
$timeout();
return {
'h': element[0].offsetHeight,
'w': element[0].offsetWidth
};
},
function (newValue, oldValue) {
var elementHeight = newValue.h;
var elementWidth = newValue.w;
/*To account for rounding errors and not loop*/
if(elementHeight % 2 === 0)
{
element.css('margin-top', '-' + ((elementHeight) / 2) + 'px');
}
else
{
element.css('margin-top', '-' + ((elementHeight + 1) / 2) + 'px');
}
if(elementWidth % 2 === 0)
{
element.css('margin-left', '-' + ((elementWidth) / 2) + 'px');
}
else
{
element.css('margin-left', '-' + ((elementWidth + 1) / 2) + 'px');
}
}, true);
element.bind('centerElement', function () {
scope.$apply();
});
};
});
如果有人对如何避免使用$watch
有任何想法,请告诉我。 我不能只使用 CSS,因为row
是position: relative
的,元素是position: absolute
所以我必须使用top: 50%
、left: 50%
、margin-top
负数和元素高度的一半,margin-left
负数和宽度的一半(即 当元素高度为 200px 时margin-top: -100px
,当元素宽度为 100px 时margin-left: -50px
),以便将元素在图像上居中。 我需要找出元素的宽度和高度,而不是将其硬编码为 CSS,这在将来出于维护目的可能会很乏味,因为我必须找出所有屏幕尺寸的大小才能引导。 因此,为什么我使用$watch
.我也在使用引导程序,所以 CSS3 flexbox
是不可能的,因为它搞砸了引导网格响应能力。
因此,如果有人有任何想法如何摆脱$watch,请告诉我。
- 如何有效地将游戏数据存储在URL查询字符串中
- 如何使用Node.js最有效地解析网页
- jquery代码在Mozilla中有效,但在其他浏览器上无效
- 有效形式-始终只显示1个错误[角度]
- Javascript袖珍参考,第121页:这是怎么回事;猴子补丁”;方法应该有效
- 单击仅在第二次单击后有效
- 什么'是在asp.net MVC中将本地化的resources.resx文件转换为javascript文件的有效
- 为什么自我执行匿名有效
- D3.js生成有效的SVG,但不显示任何内容
- 如何在AngularJS中有效地检查日期是否有效
- 为什么不是'我的函数在解析云代码中工作吗?当我在Angular和Express中测试时,它是有效的
- 滚动在Chrome中有效,但在Firefox或IE中无效
- 有效地获取两个区间之间的随机整数
- Rails将JavaScript对象存储到Model的有效方式
- Javascript XMLHttpRequest——只有第一个POST请求有效
- 使用条件语句,使 jquery fadeIn/fadeOut 仅在视口 >= 480px 时才有效
- 有效负载字节与实际字节不同
- 如何在three.js中有效地使用TraingleStripDrawMode
- 外部链接的Javascript文件赢得't执行,但函数有效
- AngularJs - $watch仅在Chrome Developer Tools打开时有效