바인드 클래스를 창 스크롤 이벤트로 전환
사용자가 브라우저 창을 특정 지점 아래로 스크롤하면 #page div의 클래스를 전환합니다.
내가 지금까지 해 온 일은 잘 되어가고 있다.
<div ng-app="myApp" scroll id="page">
<header></header>
<section></section>
</div>
app = angular.module('myApp', []);
app.directive("scroll", function ($window) {
return function(scope, element, attrs) {
angular.element($window).bind("scroll", function() {
if (this.pageYOffset >= 100) {
element.addClass('min');
console.log('Scrolled below header.');
} else {
element.removeClass('min');
console.log('Header is in view.');
}
});
};
});
(헤더 100px 아래로 창을 스크롤하면 클래스가 전환됩니다.)
하지만, 제가 틀렸다면 정정해 주세요. Angular와 이 일을 하는 것은 올바른 방법이 아니라고 생각합니다.
대신 ng-class를 사용하여 스코프에 부울값을 저장하는 것이 최선의 방법이라고 생각했습니다.다음과 같은 경우:
<div ng-app="myApp" scroll id="page" ng-class="{min: boolChangeClass}">
<header></header>
<section></section>
</div>
app = angular.module('myApp', []);
app.directive("scroll", function ($window) {
return function(scope, element, attrs) {
angular.element($window).bind("scroll", function() {
if (this.pageYOffset >= 100) {
scope.boolChangeClass = true;
console.log('Scrolled below header.');
} else {
scope.boolChangeClass = false;
console.log('Header is in view.');
}
});
};
});
이것은 동적이지는 않지만 스코프 값을 변경하면 됩니다.스크롤 콜백에서 boolChangeClass가 생성되면 ng클래스는 갱신되지 않습니다.
그래서 궁금한 것은 사용자가 특정 포인트 아래로 스크롤할 때 AngularJS를 사용하여 #page 클래스를 전환하는 가장 좋은 방법은 무엇입니까?
내 질문에 답해 준 Flek에게 감사한다.
<div ng-app="myApp" scroll id="page" ng-class="{min:boolChangeClass}">
<header></header>
<section></section>
</div>
app = angular.module('myApp', []);
app.directive("scroll", function ($window) {
return function(scope, element, attrs) {
angular.element($window).bind("scroll", function() {
if (this.pageYOffset >= 100) {
scope.boolChangeClass = true;
} else {
scope.boolChangeClass = false;
}
scope.$apply();
});
};
});
왜 다들 대규모 작전을 제안하죠?이것이 왜 "각선" 솔루션이 아닌지 모르겠다.
.directive('changeClassOnScroll', function ($window) {
return {
restrict: 'A',
scope: {
offset: "@",
scrollClass: "@"
},
link: function(scope, element) {
angular.element($window).bind("scroll", function() {
if (this.pageYOffset >= parseInt(scope.offset)) {
element.addClass(scope.scrollClass);
} else {
element.removeClass(scope.scrollClass);
}
});
}
};
})
다음과 같이 사용할 수 있습니다.
<navbar change-class-on-scroll offset="500" scroll-class="you-have-scrolled-down"></navbar>
또는
<div change-class-on-scroll offset="500" scroll-class="you-have-scrolled-down"></div>
이것은 제 해결책입니다.그렇게 까다롭지 않고 간단한 ng클래스 디렉티브를 통해 몇 가지 마크업에 사용할 수 있습니다.이와 같이 각 케이스의 클래스 및 스크롤 포스를 선택할 수 있습니다.
App.js:
angular.module('myApp',[])
.controller('mainCtrl',function($window, $scope){
$scope.scrollPos = 0;
$window.onscroll = function(){
$scope.scrollPos = document.body.scrollTop || document.documentElement.scrollTop || 0;
$scope.$apply(); //or simply $scope.$digest();
};
});
index.html:
<html ng-app="myApp">
<head></head>
<body>
<section ng-controller="mainCtrl">
<p class="red" ng-class="{fix:scrollPos >= 100}">fix me when scroll is equals to 100</p>
<p class="blue" ng-class="{fix:scrollPos >= 150}">fix me when scroll is equals to 150</p>
</section>
</body>
</html>
여기서 JSFiddle 작업
편집:
~하듯이
$apply()
실제로 전화하고 있다$rootScope.$digest()
직접 사용할 수 있습니다.$scope.$digest()
대신$scope.$apply()
콘텍스트에 따라 퍼포먼스가 향상됩니다.
요약하자면:$apply()
항상 작동하지만 강제로$digest
퍼포먼스 문제를 일으킬 수 있는 모든 스코프에 대해 설명합니다.
이것이 도움이 될 수도 있습니다:)
컨트롤러
$scope.scrollevent = function($e){
// Your code
}
HTML
<div scroll scroll-event="scrollevent">//scrollable content</div>
또는
<body scroll scroll-event="scrollevent">//scrollable content</body>
지시.
.directive("scroll", function ($window) {
return {
scope: {
scrollEvent: '&'
},
link : function(scope, element, attrs) {
$("#"+attrs.id).scroll(function($e) { scope.scrollEvent != null ? scope.scrollEvent()($e) : null })
}
}
})
퍼포먼스는요?
- 계산을 줄이기 위해 항상 이벤트를 디바운스합니다.
- 사용하다
scope.applyAsync
전체 다이제스트 주기 수를 줄이려면
function debounce(func, wait) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
func.apply(context, args);
};
if (!timeout) func.apply(context, args);
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
angular.module('app.layout')
.directive('classScroll', function ($window) {
return {
restrict: 'A',
link: function (scope, element) {
function toggle() {
angular.element(element)
.toggleClass('class-scroll--scrolled',
window.pageYOffset > 0);
scope.$applyAsync();
}
angular.element($window)
.on('scroll', debounce(toggle, 50));
toggle();
}
};
});
3. Watch/Digest를 트리거할 필요가 전혀 없는 경우compile
.directive('classScroll', function ($window, utils) {
return {
restrict: 'A',
compile: function (element, attributes) {
function toggle() {
angular.element(element)
.toggleClass(attributes.classScroll,
window.pageYOffset > 0);
}
angular.element($window)
.on('scroll', utils.debounce(toggle, 50));
toggle();
}
};
});
그리고 이렇게 사용할 수 있습니다.<header class-scroll="header--scrolled">
지시문은 그들이 말하는 "각진 세계 안"이 아닙니다.그래서 물건을 바꿀 때 다시 들어가려면 Apply를 사용해야 합니다.
언급URL : https://stackoverflow.com/questions/14878761/bind-class-toggle-to-window-scroll-event
'programing' 카테고리의 다른 글
woocommerce 브레드 크럼 누락 숍 링크 (0) | 2023.03.20 |
---|---|
MongoDB에서 데이터베이스 간에 컬렉션을 복사하는 방법 (0) | 2023.03.20 |
커스텀 애트리뷰트를 추가하는 방법 (0) | 2023.03.20 |
JSON 오브젝트에 후행 콤마를 사용할 수 있습니까? (0) | 2023.03.20 |
모든 eslint 규칙에 오류가 아닌 경고를 표시할 수 있습니까? (0) | 2023.03.20 |