I am using Angularjs for my frontend development. Recently I started implementing Webpack then I realized that angular.element($window).scrollTop() stopped working and started throwing error as “windowElement.width is not a function”. Following are old code and new code with webpack.
Old working code:
app.directive("ajnav", ['$window', '$location', function ($window, $location) {
return {
restrict: "E",
templateUrl: "/templates/common/AJNav.html",
replace: true,
scope: {
seo: '=',
conf: '='
},
link: function (scope, element, attrs) {
//Bind event change the postion of AJ Nav on scroll
var windowElement = angular.element($window);
var onScrollHandler = function () {
//Get current height of iNav.
var iNavHeight = $("#iNavNGI_Header").height();
if (windowElement.scrollTop() > iNavHeight) {
$(element).addClass('navbar-fixed-top');
$(element).removeClass('aj-nav-container-absolute');
}
else {
$(element).removeClass('navbar-fixed-top');
$(element).addClass('aj-nav-container-absolute');
}
};
//Bind event handler on scroll
windowElement.on('scroll', scope.$apply.bind(scope, onScrollHandler));
}
};
}]);
New code with webpack is throwing error:
var $ = require("jquery");
var angular = require("angular");
var Utilities = require("./../../utilities/Utilities");
var AppUtilities = require("./../../utilities/AppUtilities");
module.exports = ['$window', '$location', function ($window, $location) {
return {
restrict: "E",
templateUrl: "/templates/common/AJNav.html",
replace: true,
scope: {
seo: '=',
conf: '='
},
link: function (scope, element, attrs) {
//Bind event change the postion of AJ Nav on scroll
var windowElement = angular.element($window);
var onScrollHandler = function () {
//Get current height of iNav.
var iNavHeight = $("#iNavNGI_Header").height();
if (windowElement.scrollTop() > iNavHeight) {
$(element).addClass('navbar-fixed-top');
$(element).removeClass('aj-nav-container-absolute');
}
else {
$(element).removeClass('navbar-fixed-top');
$(element).addClass('aj-nav-container-absolute');
}
};
//Bind event handler on scroll
windowElement.on('scroll', scope.$apply.bind(scope, onScrollHandler));
}
};
}];
Follownig is stacktrace for the exception I am getting.
TypeError: windowElement.scrollTop is not a function
at module.exports.link.onScrollHandler (site.min.js:42181)
at Scope.$get.Scope.$eval (ite.min.js:25066)
at Scope.$get.Scope.$apply (site.min.js:25165)
at eventHandler (site.min.js:12594)
I am binding this directive in my entry poing App.js as below
app.directive("ajnav", require("./directives/common/AJNav"));
I tried all the option I could but not able to fix it. Please help.
2
Answers
scrollTop
function is added by jquery, you must be loading jquery after angular. In that case you wont get$.fn
functions added to theangular.element
instance. You could as well do$.fn.scrollTop.call($window)
in that case. or$($window).scrollTop()
or load jquery before angular so that your current code works as is.Side Note: You don’t have to do
$(element)
, element is already jq(lite/query) wrapped which hasadd/removeClass
function available already.Angular is loading before JQuery.
It’s also worth mentioning why you get that error instead of “scrollTop is undefined”.
It’s because scrollTop is also a property of Element.
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop