簡體   English   中英

AngularJs-僅在打開Chrome開發者工具時,$ watch才起作用

[英]AngularJs - $watch only works when Chrome Developer Tools is open

我正在嘗試將$ watch附加到指令,該指令監視元素的高度和寬度何時變化,以便它可以使用高度和寬度居中於圖像頂部。

這是我的app.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-topmargin-left值添加到高度的一半和寬度的一半,將元素直接放置在圖像的中心。

在未打開開發人員工具的情況下在Google Chrome中運行該應用程序時,當加載圖像並在元素上調整高度和寬度時,未調用centerElement指令手表,但是當我通過逐步使用Chrome開發人員工具運行該應用程序時,元素就可以恰好位於圖像的中心。 在沒有應用程序的情況下運行應用程序后打開開發人員工具時,沒有錯誤。
另外,我嘗試在Internet Explorer,Edge和Firefox中運行該應用程序。 Internet Explorer和Firefox的行為均與Chrome相同,但是Edge是唯一將圖像居中放置的瀏覽器。

我寧願不使用$ watch,因為它可能會出現性能問題,但是根據我在文檔中和Google上進行的研究,我無法找到另一種方式來做到這一點,但是我非常樂於接受。 我試圖在等待圖像加載然后將元素居中之前找到一些東西,但是我沒有運氣。 我將在應用程序的其他部分重復此指令,因此不必使用$ watch會很棒。

我是angularJS的新手,因此非常感謝您的幫助。 我還是剛開始問有關stackoverflow的問題,所以如果您需要更多信息,請告訴我。

謝謝!

編輯:我為圖像創建了另一個指令,它將在加載時調用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');
            });
        }
    };
});

我自己解決了這個問題。 我需要添加$timeout(); 到我的centerElement指令。 這將強制使用$scope.$apply(); 當完成當前$digest以便將$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,因為該rowposition: relative ,而元素是position: absolute所以我必須使用top: 50%left: 50%margin-top負數和元素和margin-left高度的一半margin-left margin-left: -50px負數和寬度的一半(即,元素高度為200px時, margin-top: -100px ;元素寬度為100px時, margin-left: -50px )以使元素在圖像上居中。 我需要找出元素的寬度和高度,而不是將其硬編碼到CSS中,這在將來出於維護目的可能會很乏味,因為我必須找出所有屏幕尺寸的尺寸進行引導。 因此,為什么我使用$watch 我也在使用引導程序,因此CSS3 flexbox ,因為它搞亂了引導程序網格的響應能力。

因此,如果有人對如何擺脫$ watch有任何想法,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM