AngularJS: 높이 변화를 관찰하는 더 좋은 방법
이전 가변 높이 내비게이션 문제가 있습니다.aposition: fixes
맨 위의 네비게이션 및 콘텐츠margin-top: $naviHeight
네비게이션은 데이터가 비동기적으로 로드될 때 높이가 변경될 수 있으므로 콘텐츠의 여백도 그에 따라 달라져야 합니다.
나는 이것이 스스로 억제되기를 바란다.따라서 데이터가 로드되는 코드는 없고 관련된 html 요소/지침에만 있습니다.
현재는 다음과 같은 타이머로 AngularJS 1.2.0으로 하고 있습니다.
/*
* Get notified when height changes and change margin-top
*/
.directive( 'emHeightTarget', function(){
return {
link: function( scope, elem, attrs ){
scope.$on( 'heightchange', function( ev, newHeight ){
elem.attr( 'style', 'margin-top: ' + (58+newHeight) + 'px' );
} );
}
}
})
/*
* Checks this element periodically for height changes
*/
.directive( 'emHeightSource', ['$timeout', function( $timeout ) {
return {
link: function( scope, elem, attrs ){
function __check(){
var h = elem.height();
if( h != scope.__height ){
scope.__height = h;
scope.$emit( 'heightchange', h );
}
$timeout( __check, 1000 );
}
__check();
}
}
} ] )
이것은 타이머를 사용하는 것의 명백한 결점(좀 못생겼다고 느껴짐)과 네비게이션 크기를 조정한 후 콘텐츠를 이동할 때까지의 일정 지연이 있습니다.
더 좋은 방법이 있을까요?
이는 워처를 에 등록함으로써 동작합니다.emHeightSource
에브리라고 불리는$digest
. 를 갱신합니다.__height
차례로 감시되고 있는 재산emHeightTarget
:
/*
* Get notified when height changes and change margin-top
*/
.directive( 'emHeightTarget', function() {
return {
link: function( scope, elem, attrs ) {
scope.$watch( '__height', function( newHeight, oldHeight ) {
elem.attr( 'style', 'margin-top: ' + (58 + newHeight) + 'px' );
} );
}
}
} )
/*
* Checks every $digest for height changes
*/
.directive( 'emHeightSource', function() {
return {
link: function( scope, elem, attrs ) {
scope.$watch( function() {
scope.__height = elem.height();
} );
}
}
} )
Div를 사용하지 않고 요소의 높이 변화를 모니터링할 수 있습니다.$watch
스테이트먼트:
// Observe the element's height.
scope.$watch
(
function () {
return linkElement.height();
},
function (newValue, oldValue) {
if (newValue != oldValue) {
// Do something ...
console.log(newValue);
}
}
);
아마 당신은 을 지켜봐야 할 것이다.$window
치수는 다음과 같이 변화합니다.
.directive( 'emHeightSource', [ '$window', function( $window ) {
return {
link: function( scope, elem, attrs ){
var win = angular.element($window);
win.bind("resize",function(e){
console.log(" Window resized! ");
// Your relevant code here...
})
}
}
} ] )
$watch 이벤트와 크기 조정 이벤트를 조합하여 사용했습니다.나는 범위 없이 찾았다.$watch(); 크기 조정 이벤트에서 요소의 높이 변경이 항상 $watch에 의해 인식되는 것은 아닙니다.
link:function (scope, elem) {
var win = angular.element($window);
scope.$watch(function () {
return elem[0].offsetHeight;
},
function (newValue, oldValue) {
if (newValue !== oldValue)
{
// do some thing
}
});
win.bind('resize', function () {
scope.$apply();
});
};
이 어프로치에 의해, (잠재적으로) 네트워크상의reflow
모든 다이제스트 사이클확인만 됩니다.elem.height()
// 다이제스트 사이클이 끝나면 높이가 변경된 경우에만 새 다이제스트가 발생합니다.
var DEBOUNCE_INTERVAL = 50; //play with this to get a balance of performance/responsiveness
var timer
scope.$watch(function() { timer = timer || $timeout(
function() {
timer = null;
var h = elem.height();
if (scope.height !== h) {
scope.$apply(function() { scope.height = h })
}
},
DEBOUNCE_INTERVAL,
false
)
Jamie Pate가 올바르게 언급했듯이 다이제스트 사이클 내에서 직접 DOM에 액세스하는 것은 그다지 좋은 생각이 아니기 때문에 스코프에 바인딩할 수 있는 다른 타이머 기반 변형을 작성했습니다.
.directive("sizeWatcher", ['$timeout', function ($timeout) {
return {
scope: {
sizeWatcherHeight: '=',
sizeWatcherWidth: '=',
},
link: function( scope, elem, attrs ){
function checkSize(){
scope.sizeWatcherHeight = elem.prop('offsetHeight');
scope.sizeWatcherWidth = elem.prop('clientWidth');
$timeout( checkSize, 1000 );
}
checkSize();
}
};
}
이것으로, 임의의 요소에 바인드 할 수 있습니다.
<img size-watcher size-watcher-height="myheight">
<div style="height: {{ myheight }}px">
따라서 div는 항상 이미지와 동일한 높이(지연 1초)를 유지합니다.
이 접근법은 요소의 높이와 폭을 감시하고 요소 속성에 제공된 범위의 변수에 할당합니다.
<div el-size="size"></div>
.directive('elSize', ['$parse', function($parse) {
return function(scope, elem, attrs) {
var fn = $parse(attrs.elSize);
scope.$watch(function() {
return { width: elem.width(), height: elem.height() };
}, function(size) {
fn.assign(scope, size);
}, true);
}
}])
언급URL : https://stackoverflow.com/questions/19048985/angularjs-better-way-to-watch-for-height-change
'programing' 카테고리의 다른 글
Angular JS가 있는 링크에 조건부로 target="_blank" 추가 (0) | 2023.03.18 |
---|---|
Spring Application Configuration을 찾을 수 없음: 잘못된 Spring-boot-starter-test 내용입니까? (0) | 2023.03.18 |
Spring Boot 어플리케이션에서의 통합 테스트용으로 Embedded MongDB를 설정하려면 어떻게 해야 합니까? (0) | 2023.03.18 |
페이지 전체에서 키 누르기 이벤트를 청취하려면 어떻게 해야 하나요? (0) | 2023.03.18 |
UI-Router가 Angular에 있는 기본 서브스테이트로 상태 리다이렉트JS (0) | 2023.03.18 |