使用元素的高度改变页面滚动菜单的CSS

Changing CSS of menu on page scroll using height of element

本文关键字:滚动 菜单 CSS 改变 元素 高度      更新时间:2023-09-26

你好在我的页面上,我有三个部分,其中包含菜单和滑块区域,有一个红色的背景,白色的文本和内容区域有一个白色的背景,黑色的文本和脚注区域有一个灰色的背景。我的菜单是静态的,这意味着无论你滚动到页面的哪个部分,它都会显示。

然而,当我滚动到页面的白色部分时,我的问题出现了,因为菜单文本是白色的,在页面的白色部分文本不显示。

所以我决定尝试改变页面滚动上的css,我环顾四周,发现这个指令返回滚动位置和使用滚动位置,我可以改变css ng-class

   /**
     * Scroll Position Directive
     */
    .directive('scrollPosition', function($window) {
        return {
            scope: {
                scroll: '=scrollPosition'
            },
            link: function(scope, element, attrs) {
                var windowEl = angular.element($window);
                var handler = function() {
                    scope.scroll = windowEl.scrollTop();
                }
                windowEl.on('scroll', scope.$apply.bind(scope, handler));
                handler();
            }
        };
    })

上面的代码工作,但我面临着另一个问题,在我的主页上,标题的高度不同于其他页面,因为我的网站是响应的,标题大小可能会根据屏幕大小而变化。因此,我不能使用固定的高度来更改类,如下面的代码所示:

ng-class="{ 'topbar': scroll > 200 }"

我真正想要的是:

 ng-class="{ 'topbar': scroll > heightOfHeader }"

其中 hightofheader 是我的头部区域的高度,可以根据屏幕大小而改变。

我已经在网上寻找了许多关于如何在页面加载或屏幕尺寸变化时获得我的头部高度的解决方案,但我还没有找到解决方案,任何我尝试返回0作为我的头部高度。

.directive('elementHeight', function() {
            return {
                scope: {
                    elementHeight: '='
                },
                link: function(scope, element) {
                    /*var windowEl = angular.element($window);
                    var handler = function() {
                        scope.elementHeight = element[0].offsetHeight;
                    }
                    windowEl.on('load', scope.$apply.bind(scope, handler));
                    handler();*/
                    /*$timeout(function(){
                        scope.elementHeight = $('#header').height();
                    });*/
                    $(window).load(function() {
                        scope.elementHeight = element[0].offsetHeight;
                    });
                }
            };

注释的代码是我尝试过的不工作的旧解决方案。

好的,所以我终于找到了一个解决方案,把我在stackoverflow上找到的几个答案放在一起。对于滚动位置,我保留了已有的代码:

/**
     * Scroll Position Directive
     */
    .directive('scrollPosition', function($window) {
        return {
            scope: {
                scroll: '=scrollPosition'
            },
            link: function(scope, element, attrs) {
                var windowEl = angular.element($window);
                var handler = function() {
                    scope.scroll = windowEl.scrollTop();
                }
                windowEl.on('scroll', scope.$apply.bind(scope, handler));
                handler();
            }
        };
    })

对于高度,我在这里发现了这段代码,我修改了一点(虽然我不完全理解这里发生了什么):

/*
 * Get notified when height changes and change margin-top
 */
.directive( 'elHeightTarget', function($rootScope) {
    return {
        link: function( scope, elem, attrs ) {
            scope.$watch( '__height', function( newHeight, oldHeight ) {
                $rootScope.$broadcast('elHeight', newHeight);
            } );
        }
    }
})
/*
 * Checks every $digest for height changes
 */
.directive( 'elHeightSource', function() {
    return {
        link: function( scope, elem, attrs ) {
            scope.$watch( function() {
                scope.__height = elem.height();
            } );
        }
    }
})

在elhighttarget指令中,我添加了一个$rootScope。$broadcast作用域中。$watch广播任何高度的变化。

然后在Main Controller中:

.controller('MainCtrl', ['$http', '$scope', '$state', '$rootScope', function($http, $scope, $state, $rootScope) {
    $scope.height = 0;
    $scope.scroll = 0;
    $scope.$on('elHeight', function(events, args){
        $scope.height = args;
    });
}])

最后,在我的HTML中,我看到使用ng-class根据标题的滚动位置和高度来更改菜单的类:

<div class="menu-wrapper">
    <div class="menu" scroll-position="scroll" ng-class="{ 'menu-default': scroll < height, 'menu-red': scroll > height  }">
        <div class="container">
            ...
        </div>
    </div>
</div>

这是我的头部的html,我添加了指令,检查高度的任何变化:

<div id="header" class="header" el-height-target el-height-source>
    ...
</div>

这就是全部:)我不知道是否有一个更容易和更好的方法来做到这一点,但这绝对解决了我的问题。:)