user883807
user883807

Reputation:

How to add and remove class of one element while hovering over another element via Angular?

I'd like to add a class to an <li> when it's child <a> gets hovered over but I can't seem to get it to work. What is happening is that no matter what <a> element is hovered over, only the first <li> gets affected so I need to be able to target only the parent <li> of the <a> that is currently being hovered over.

Here is what I have so far:

http://jsfiddle.net/faGTg/39/

and here is the code:

Controller (Javascript)

var myApp = angular.module('myApp',[]);
myApp.controller("Ctrl", function($scope){
    $scope.addClass = function(){
        angular.element(document.querySelector('.li-hover')).addClass('hovering');
    }
    $scope.removeClass = function(){
        angular.element(document.querySelector('.li-hover')).removeClass('hovering');
    }
});

HTML

<div ng-app='myApp'>
    <div ng-controller="Ctrl">
        <ul>
            <li class="li-hover" >
                <a href="" ng-mouseover="addClass()" ng-mouseleave="removeClass()">
                    <span>Home</span>
                </a>
            </li>
            <li class="li-hover" >
                <a href="" ng-mouseover="addClass()" ng-mouseleave="removeClass()">
                  <span>About</span>
                </a>
            </li>
            <li class="li-hover" >
                <a href="" ng-mouseover="addClass()" ng-mouseleave="removeClass()">
                  <span>Contact</span>
                </a>
            </li>
        </ul>
    </div>
</div>

CSS

.hovering {
    background-color: pink;
    border-bottom: 5px solid red;
}
li {
    margin: 1em;
    padding: 2em;
    border-bottom: 5px solid #aaa;
    background: #ccc;
}
a { 
    background: white;
    padding: 0.5em;
}

Upvotes: 0

Views: 3792

Answers (2)

Ezequias Dinella
Ezequias Dinella

Reputation: 1306

You can isolate scope using a repeater, and change a property of the repeated item:

myApp.controller("Ctrl", function($scope) {
  $scope.items = [
    {
      href: '',
      title: 'Home',
    },
    {
      href: '',
      title: 'About',
    },
    {
      href: '',
      title: 'Contact',
    }
  ];
});

Then, you can store a over property on item, and use it to change class:

<ul>
  <li ng-repeat="item in items" ng-class="{hovering: item.over}">
    <a ng-href="{{item.href}}" title="{{item.title}}" ng-mouseover="item.over=true" ng-mouseleave="item.over=false">
      <span>{{item.title}}</span>
    </a>
  </li>
</ul>

http://jsfiddle.net/faGTg/41/

Or you can use a simple var for that now, because the ng-repeat directive isolates each item in a new scope:

<ul>
  <li ng-repeat="item in items" ng-class="{hovering: over}">
    <a ng-href="{{item.href}}" title="{{item.title}}" ng-mouseover="over=true" ng-mouseleave="over=false">
      <span>{{item.title}}</span>
    </a>
  </li>
</ul>

I think this is better, because styling on hovering is a view concern. Although the solution above sets a hover property in the current scope, the controller does not need to be concerned about this.

http://jsfiddle.net/33ypvx3g/

Upvotes: 1

Caner Akdeniz
Caner Akdeniz

Reputation: 1862

You don't need any js or jQuery code for that, you can accomplish this with the css :hover selector. Add this to your css:

li:hover {
   background-color: pink;
   border-bottom: 5px solid red;
}

Here is the working sample: http://jsfiddle.net/faGTg/40/

Upvotes: 1

Related Questions