Я использую $watch
agular $watch
чтобы вызывать предупреждение, когда элемент становится видимым.
var scrollElement = "#hiddenObj";
$scope.$watch(function() { return $(scrollElement).is(':visible') }, function() {
alert('hi);
});
Проблема в том, что предупреждение отображается при загрузке страницы, но при загрузке страницы, элемент скрыт по умолчанию и отображается только по щелчку некоторой ссылки.
Чтобы подтвердить мое предположение, я поставил точку останова непосредственно перед этим кодом, и в моей консоли я выполнил этот код:
$(scrollElement).is(':visible')
и он возвращает false
. Это подтвердило, что элемент невидим при загрузке страницы. Я не знаю, почему предупреждение все еще отображается при загрузке страницы. И когда я нажимаю ссылку, и scrollElement
становится видимым, ничего не происходит.
Здесь что-то не хватает?
Обратный вызов прослушивателя часов будет выполняться всякий раз, когда изменяется watchExpression
, а не когда оно true/false
. Таким образом, когда ваша страница будет загружена, ваше значение watchExpression
будет false
и слушатель будет выполнен. Чтобы этого избежать, вы можете проверить новое значение вашего watchExpression
:
$scope.$watch(function() { return $(scrollElement).is(':visible') }, function(newVal) {
if(newVal === true) {
alert('Element showed');
}
});
Вторая проблема заключается в том, что watchExpression
вызывается при каждом вызове $digest()
. Таким образом, ваш обработчик кликов (чтобы показать/скрыть элемент) должен вызвать цикл $ digest, чтобы оценить выражение, ng-click
будет хорошей идеей.
В вашем случае watchExpression
:
function() { return $(scrollElement).is(':visible') }
это должно быть закодировано в директивах, которые изменяют переменную области видимости как $ scope.elemVisible
.directive("visible",function(){
return{
restrict:"AE",
scope:{yourVarName:'='},
link:function(scope,elem,attrs){
$(window).scroll(function(ev){//if you want to do something on scroll
var vis=$(elem).is(':visible');
scope.yourVarName=vis;
scope.$apply();
});
$(someElement).bind('click',function(ev){// or if you want do something on click
var vis=$(elem).is(':visible');
scope.yourVarName=vis;
scope.$apply();
});
}
}
})
HTML
<visible yourVarName="isVisible"/>
контроллер
$scope.$watch('isVisible',function(newVal,oldVal){...});
(oldVal, newVal)
своей функции и сначала сравнить ихfalse
для выражения$(scrollElement).is(':visible')
, но когда элемент отображается, консоль для этого показываетtrue
. В идеале, только на этом этапе должно быть показано предупреждение, потому что на этом этапеwatchExpression
изменяется.