IT story

Angularjs-ng-cloak / ng-show 요소가 깜박임

hot-time 2020. 4. 15. 12:36
반응형

Angularjs-ng-cloak / ng-show 요소가 깜박임


angular.js에서 지시문 / 클래스 ng-cloak또는에 문제가 ng-show있습니다.

Chrome은 정상적으로 작동하지만 Firefox에서 ng-cloak또는 의 요소가 깜박입니다 ng-show. IMHO는 ng-cloak/ ng-show변환하여 발생 style="display: none;"합니다. 파이어 폭스 자바 스크립트 컴파일러는 약간 느려서 요소가 잠시 동안 나타난 다음 숨겨져 있습니까?

예:

<ul ng-show="foo != null" ng-cloak>..</ul>

문서에 언급되어 있지 않지만 display: none;CSS에 규칙을 추가하는 것만으로는 충분하지 않을 수 있습니다 . 당신이 몸에 로딩 angular.js 또는 템플릿을 사용, 곧 컴파일되지 않습니다 경우에 ng-cloak지시를 하고 당신의 CSS에 다음을 포함한다 :

/* 
  Allow angular.js to be loaded in body, hiding cloaked elements until 
  templates compile.  The !important is important given that there may be 
  other selectors that are more specific or come later and might alter display.  
 */
[ng\:cloak], [ng-cloak], .ng-cloak {
  display: none !important;
}

의견에서 언급했듯이이 !important것이 중요합니다. 예를 들어 다음과 같은 마크 업이있는 경우

<ul class="nav">
  <li><a href="/foo" ng-cloak>{{bar}}</a></li>
</ul>

을 사용 bootstrap.css하면 다음 선택자가 ng-cloak'ed 요소에 더 구체적입니다.

.nav > li > a {
  display: block;
}

따라서 단순히을 사용하여 규칙을 포함하면 display: none;Bootstrap의 규칙이 우선하고 display가로 설정되어 block템플릿이 컴파일되기 전에 깜박임을 볼 수 있습니다.


으로 문서에 언급 , 당신은에 기초 숨기기에 CSS에 규칙을 추가해야 ng-cloak속성 :

[ng\:cloak], [ng-cloak], .ng-cloak {
    display: none;
}

"Built with Angular"사이트에서 비슷한 트릭을 사용하는데, Github에서 소스를 볼 수 있습니다 : https://github.com/angular/builtwith.angularjs.org

희망이 도움이됩니다!


AngularJS가 headHTML에 포함되어 있는지 확인하십시오 . ngCloak 문서를 참조하십시오 :

최상의 결과를 얻으려면 angular.js 스크립트를 html 파일의 head 섹션에로드해야합니다. 또는 CSS 규칙 (위)을 응용 프로그램의 외부 스타일 시트에 포함시켜야합니다.


나는 ngCloak를 사용하여 운이 없었습니다. 위에서 언급 한 모든 사항에도 불구하고 여전히 깜박 거립니다. 깜박임을 피하는 유일한 확실한 방법은 콘텐츠를 템플릿에 넣고 템플릿을 포함시키는 것입니다. SPA에서 Angular에 의해 컴파일되기 전에 평가되는 유일한 HTML은 기본 index.html 페이지입니다.

몸 안의 모든 것을 가져 와서 별도의 파일에 붙이고 다음과 같이하십시오.

<ng-include src="'views/indexMain.html'"></ng-include>

Angular가 템플릿을 DOM에 추가하기 전에 템플릿을 컴파일하기 때문에 깜박 거리지 않아야합니다.


ngBindngBindTemplate 은 CSS가 필요없는 대안입니다.

<div ng-show="foo != null" ng-cloak>{{name}}</div>  <!-- requires CSS -->
<div ng-show="foo != null" ng-bind="name"></div>
<div ng-show="foo != null" ng-bind-template="name = {{name}}"></div>

ng-cloak을 트리거하는 다른 방법을 사용하는 경우 허용되는 답변 외에도 ...

CSS / LESS에 몇 가지 추가 특성을 추가 할 수도 있습니다.

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
.ng-cloak, .x-ng-cloak,
.ng-hide {
    display: none !important;
}

비슷한 문제가 있었고 전환이 포함 된 클래스가 있으면 요소가 깜박임을 알았습니다. 성공하지 않고 ng-cloak을 추가하려고했지만 전환을 제거하면 버튼 깜박임이 중지되었습니다.

이온 프레임 워크를 사용하고 있으며 버튼 아웃 라인에 이러한 전환이 있습니다.

.button-outline {
  -webkit-transition: opacity .1s;
  transition: opacity .1s;
}

클래스를 덮어 쓰기하여 전환을 제거하면 버튼 깜박임이 중지됩니다.

최신 정보

다시 이온 성에서는 ng-show / ng-hide를 사용할 때 깜박임이 있습니다. 다음 CSS를 추가하면 해결됩니다.

.ng-hide-add,
.ng-hide-remove {
  display: none !important;
}

출처 : http://forum.ionicframework.com/t/beta-14-ng-hide-show/14270/9


<div ng-show="expression">ng-show 지시문이 실행되기 전에 "표현식"이 초기에 거짓 이었지만 처음에 1 초 동안 a가 표시 되는 문제가있었습니다 .

내가 사용한 솔루션은 에서처럼 "ng-hide"클래스를 수동으로 추가하여 <div ng-show="expression" ng-hide>처음 숨겨지기 시작했는지 확인하는 것이 었습니다. ng-show 지시문은 필요에 따라 ng-hide 클래스를 추가 / 제거합니다.


시도 파이어 버그를 끕니다 . 나는 진지하다. 이것은 내 경우에 도움이됩니다.

허용 대답을 적용하고 있는지 확인 방화범이 끌려 파이어 폭스에서이 켜져 오프 : F12 키를 눌러 다음이 페이지에 대한 방화범을 해제 - 작은 버튼을 오른쪽 상단 모서리에.


깜박임 문제를 일으킬 수있는 두 가지 별도의 문제가 실제로 있으며이 중 하나 또는 둘 다에 직면 할 수 있습니다.

문제 1 : ng-cloak이 너무 늦게 적용되었습니다

이 문제는 AngularJS가 헤드에로드되도록하는 것이이 페이지의 많은 답변에서 설명 된대로 해결되었습니다. ngCloak 문서를 참조하십시오 :

최상의 결과를 얻으려면 angular.js 스크립트를 html 파일의 head 섹션에로드해야합니다. 또는 CSS 규칙 (위)을 응용 프로그램의 외부 스타일 시트에 포함시켜야합니다.

문제 2 : ng-cloak가 너무 빨리 제거됨

이 문제는 페이지에 CSS가 많고 서로 연계 된 규칙이 있고 최상위 레이어가 적용되기 전에 CSS의 더 깊은 레이어가 깜박일 때 발생할 수 있습니다.

style="display:none"요소 를 추가 하는 것과 관련된 답변의 jQuery 솔루션 은 스타일이 충분히 늦게 제거되는 한 (실제로이 두 가지 문제를 모두 해결하는 한)이 문제를 해결합니다. 그러나 HTML에 스타일을 직접 추가하지 않으려면을 사용하여 동일한 결과를 얻을 수 있습니다 ng-show.

질문의 예부터 시작하십시오.

<ul ng-show="foo != null" ng-cloak>..</ul>

요소에 추가 ng-show 규칙을 추가하십시오.

<ul ng-show="isPageFullyLoaded && (foo != null)" ng-cloak>..</ul>

( ng-cloak문제 1을 피해야합니다.)

그런 다음 app.run 세트에서 isPageFullyLoaded:

app.run(['$rootScope', function ($rootScope) {
    $rootScope.$safeApply = function (fn) {
        $rootScope.isPageFullyLoaded = true;
    }
}]);

정확히 무엇을하고 있는지에 따라 app.run이 설정하기 가장 좋은 장소 일 수도 있고 아닐 수도 있습니다 isPageFullyLoaded. 중요한 것은 isPageFullyLoaded깜박 거리고 싶지 않은 것이 사용자에게 공개 될 준비가 된 후에 true로 설정되도록하는 것입니다.

문제 1 은 OP가 겪고있는 문제인 것처럼 들리지만 다른 사람들은 문제 2 대신 또는 문제 2쳐서 솔루션이 작동하지 않거나 부분적으로 만 작동하는 것으로 나타났습니다 .

중요 참고 : ng-cloak을 너무 늦게 적용하고 곧 제거 할 수있는 솔루션을 모두 적용하십시오. 이러한 문제 중 하나만 해결해도 증상이 완화되지 않을 수 있습니다.


우리는 회사에서이 문제에 부딪 쳤고 깜박 거리는 ng-show 요소의 CSS 스타일에 "display : none"을 추가하여 문제를 해결했습니다. 우리는 ng-cloak을 전혀 사용할 필요가 없었습니다. 이 스레드의 다른 스레드와 달리 Safari에서는 Firefox 또는 Chrome이 아닌이 문제가 발생 했습니다 .iOS7의 Safari 지연 페인트 다시 버그 로 인한 것일 수 있습니다 .


그만한 가치가 있기 때문에 비슷한 문제가 발생했습니다. 캐시가 활성화 된 상태에서 앱 / 사이트에서 소스 파일을 재사용하여 도움이되는지 확인하는 것이 좋습니다.

플리커가있는 런인으로 DevTools를 열고 캐시를 비활성화 한 상태에서 테스트했습니다. 캐싱을 활성화 한 상태에서 패널을 닫은 상태로두면 문제가 해결되었습니다.


헤드 태그의 아래 문장을 유지하면이 문제가 해결되었습니다.

<style type="text/css">
    [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
    display: none !important;
}
</style>

공식 문서


이러한 방법을 사용할 수 없었으므로 결국 다음을 수행했습니다. 처음 숨길 요소의 경우 :

<div <!--...--> style="display: none;" ng-style="style">

그런 다음 컨트롤러에서 상단 또는 근처에 이것을 추가하십시오.

$scope.style = { display: 'block' };

이런 방식으로 요소는 처음에 숨겨져 있으며 컨트롤러 코드가 실제로 실행될 때만 표시됩니다.

로직을 추가하여 필요에 따라 배치를 조정할 수 있습니다. 필자의 경우 현재 로그인하지 않은 경우 로그인 경로로 전환하고 인터페이스가 미리 깜박이지 않기를 원하므로 $scope.style로그인 확인 후에 설정 했습니다.


ng-if대신 사용하는 것이 좋습니다 ng-show. ng-ifDOM에서 요소를 완전히 제거하고 다시 만들고 ng-show가 깜박이지 않도록합니다.


이온 프레임 워크를 사용하고 있습니다 .CSS 스타일을 추가하면 특정 상황에서 작동하지 않을 수 있습니다 .ng-show / ng-hide 대신 ng-if를 사용해보십시오

참조 : https://books.google.com.my/books?id=-_5_CwAAQBAJ&pg=PA138&lpg=PA138&dq=ng-show+hide+flickering+in+ios&source=bl&ots=m2Turk8DFh&sig=8hNiWx26euGR2k_WeyaVzdicJed== = onepage & q = ng-show % 20hide % 20flickering % 20in % 20ios & f = false


버전 [1.4.9]이 data-ng-cloak 지시어를 지원할 수 있도록 아래로 업데이트되었으므로 각도 문서를 참조하는 것이 좋습니다.

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
  display: none !important;
}

위의 ng-cloak 솔루션을 사용해 보았지만 Firefox에서 간헐적으로 문제가 있습니다. 나를 위해 일한 유일한 해결 방법은 Angular가 완전히로드 될 때까지 양식로드를 지연시키는 것입니다.

단순히 앱에 ng-init를 추가하고 양식 측에서 ng-if를 사용하여 설정 한 변수가 이미로드되었는지 확인합니다.

<div ng-app="myApp" ng-init="loaded='yes'"> 
   <form ng-if="loaded.length > 0">
      <!--all my elements here-->
   </form>
</div>

다른 답변 외에도 템플릿 코드의 플래시가 계속 발생하면 페이지 하단에 스크립트가있을 가능성이 높으므로 ng-cloak 지시문이 똑바로 작동하지 않습니다. 스크립트를 헤드로 이동하거나 CSS 규칙을 만들 수 있습니다.

문서에 따르면 "최상의 결과를 얻으려면 angular.js 스크립트를 html 문서의 헤드 섹션에로드해야합니다. 또는 위의 CSS 규칙을 응용 프로그램의 외부 스타일 시트에 포함시켜야합니다."

이제 외부 스타일 시트 일 필요는 없지만 헤드의 요소 일뿐입니다.

<style type="text/css">
  .ng-cloak {
    display: none !important;
  }
</style>

출처 : https://docs.angularjs.org/api/ng/directive/ngCloak


여기에 게시 된 모든 솔루션을 시도했지만 여전히 Firefox에서 깜박입니다.

그것이 누군가에게 도움이된다면 style="display: none;", 메인 컨텐츠 div 에 추가 한 다음 $('#main-div-id').show();서버에서 데이터를 가져온 후 모든 것이로드되면 jQuery (이미 페이지에서 이미 사용 중임)를 사용하여 해결했습니다 .


실제로 Rick Strahl의 Web Log의 제안이 내 문제를 완벽하게 해결한다는 것을 알았습니다 (특히 Firebug를 실행하는 동안 ng-cloak이 원시 {{code}}를 깜박임과 관련하여 이상한 문제가 있음).

핵 옵션 : 컨텐츠 수동 숨기기

명시 적 CSS를 사용하는 것이 최선의 선택이므로 다음 사항이 필요하지 않습니다. 그러나 여기에서는 다른 프레임 워크 또는 자체 마크 업 기반 템플릿에서로드시 컨텐츠를 수동으로 숨기거나 표시하는 방법에 대한 통찰력을 제공하므로 여기에서 언급하겠습니다.

CSS 스타일을 페이지에 명시 적으로 포함시킬 수 있다고 생각하기 전에 ng-cloak이 왜 작동하지 않는지 알아 내려고했습니다. 아무데도 시간을 낭비하지 않고 마침내 컨테이너를 수동으로 숨기고 표시하기로 결정했습니다. 아이디어는 간단합니다. 처음에는 컨테이너를 숨기고 Angular가 초기 처리 및 페이지에서 템플릿 마크 업 제거를 완료 한 후에 표시합니다.

Angular가 제어권을 얻은 후에 내용을 수동으로 숨기고 표시 할 수 있습니다. 이를 위해 나는 다음을 사용했다.

<div id="mainContainer" class="mainContainer boxshadow"
    ng-app="app" style="display:none">

페이지에서 처음에 요소를 명시 적으로 숨기는 표시 없음 스타일을 주목하십시오.

그런 다음 Angular가 초기화를 실행하고 페이지에서 템플릿 마크 업을 효과적으로 처리하면 내용을 표시 할 수 있습니다. Angular의 경우이 'ready'이벤트는 app.run () 함수입니다.

app.run( function ($rootScope, $location, cellService) {        
    $("#mainContainer").show();
});

이렇게하면 display : none 스타일과 내용이 효과적으로 제거됩니다. app.run ()이 시작될 때 DOM은 채워진 데이터 또는 최소한 빈 데이터로 표시 될 준비가되었습니다. Angular는 제어권을 얻었습니다.


위의 모든 답변을 시도했지만 아무것도 효과가 없었습니다. 이온 앱을 사용하여 하이브리드 앱을 개발했으며 깜박임이 아닌 오류 메시지를 만들려고했습니다. 내 요소에 ng-hide 클래스를 추가하여 문제를 해결했습니다. 내 div에는 이미 오류가있을 때 요소를 표시하는 ng-show가 있습니다. ng-hide를 추가하면 각도가로드되기 전에 div가 표시되지 않도록 설정됩니다. ng-cloak이 없거나 헤드에 각도를 추가 할 필요가 없습니다.


위의 논의에서 AS

[ng-cloak] {
                display: none;
            }

문제를 해결하는 완벽한 방법입니다.


지시문에서 ng-show를 사용하여 팝업을 표시하고 숨 깁니다.

<div class="..." ng-show="showPopup">

위의 어느 것도 나를 위해 일하지 않았으며 ng-show 대신 ng-if를 사용하는 것은 과잉 일 것입니다. 이는 클릭 할 때마다 전체 팝업 컨텐츠를 제거하고 DOM에 추가하는 것을 의미합니다. 대신 ng-if를 동일한 요소에 추가하여 문서로드시 표시되지 않도록했습니다.

<div class="..." ng-show="showPopup" ng-if="popupReady">

그런 다음이 지시문을 담당하는 컨트롤러에 초기화를 시간 초과로 추가했습니다.

$timeout(function () {
    $scope.popupReady = true;
});

이렇게하면 깜박임 문제를 제거하고 매번 클릭 할 때마다 비용이 많이 드는 DOM 삽입 작업을 피할 수있었습니다. 이것은 하나의 목적 대신 동일한 목적으로 두 개의 스코프 변수를 사용하는 비용이 들었지만 지금까지는 이것이 최선의 선택입니다.


시도 ng-cloak했지만 여전히 짧게 깜박입니다. 아래 코드는 완전히 제거했습니다.

<body style="display:none;" ng-style="{'display':'block'}">

위에 나열된 해결책 중 어느 것도 나를 위해 일하지 않았습니다. 그런 다음 실제 기능을 살펴보기로 결정하고“$ scope.watch”가 시작될 때 이름 필드에 가치가 없다는 것을 깨달았습니다. 그래서 코드에서 oldValue와 newValue를 설정 한 다음

$scope.$watch('model.value', function(newValue, oldValue) {
if (newValue !== oldValue) {
validateValue(newValue);
}
});

이 경우 scope.watch가 실행될 때 기본적으로 AngularJS는 이름 변수 (model.value)의 변경 사항을 모니터링합니다.


나는 포장 할 것이다 <ul>A를을<div ng-cloak>


개인적으로이 ng-class속성 을 사용하기로 결정했습니다 ng-show. 나는 항상 기본적으로 표시되지 않는 팝업 창에 대해이 경로에서 더 많은 성공을 거두었습니다.

예전에는 <div class="options-modal" ng-show="showOptions"></div>

지금 : <div class="options-modal" ng-class="{'show': isPrintModalShown}">

options-modal 클래스의 CSS display: none가 기본적으로 사용됩니다. show 클래스는 display:blockCSS를 포함합니다 .


줄 바꿈 방지

<meta http-equiv="Content-Security-Policy"              content="
default-src 'FOO';   
script-src 'FOO';    
style-src  'FOO'; 
font-src 'FOO';">

Firefox 45.0.1에서 작동

<meta http-equiv="Content-Security-Policy"              content="    default-src 'FOO';    script-src 'FOO';     style-src  'FOO';    font-src 'FOO';">

참고 URL : https://stackoverflow.com/questions/11249768/angularjs-ng-cloak-ng-show-elements-blink

반응형