AngularJS: предотвращение срабатывания события mouseenter для дочерних элементов

Я сейчас играю с фреймворком AngularJS и наткнулся на проблему. Я сделал директиву, которая называется «войти». Он запускает функции на mouseenter и mouseleave. Я применил его как атрибут к элементам строки таблицы. Теперь он запускается для каждого дочернего элемента (всех столбцов и т. д.), но должен срабатывать только при наведении указателя мыши на строку таблицы.

Вот как выглядит моя директива:

myapp.directive('enter', function(){
    return {
        restrict: 'A', // link to attribute... default is A
        link: function (scope, element){
            element.bind('mouseenter',function() {
                console.log('MOUSE ENTER: ' + scope.movie.title);
            });
            element.bind('mouseleave',function() {
                console.log('LEAVE');
            });
        }
    }
});

Вот пример: http://jsfiddle.net/dJGfd/1/

Для просмотра сообщений журнала необходимо открыть консоль Javascript.

Каков наилучший способ добиться желаемой функциональности в AngularJS? Я предпочитаю не использовать jQuery, если есть разумное решение AngularJS.


person JustGoscha    schedule 07.03.2013    source источник
comment
Это похоже на ошибку для меня. Небольшое замечание: вы также можете применить директиву Angular под названием ng-mouseenter / ng-mouseleave. Моя идея заключалась бы в том, чтобы сохранить последний наведенный элемент и посмотреть, отличается ли он.   -  person F Lekschas    schedule 08.03.2013


Ответы (1)


Вы можете попробовать это:

myapp.directive('enter', function () {
    return {
        restrict: 'A',
        controller: function ($scope, $timeout) {
            // do we have started timeout
            var timeoutStarted = false;

            // pending value of mouse state
            var pendingMouseState = false;

            $scope.changeMouseState = function (newMouseState) {
                // if pending value equals to new value then do nothing
                if (pendingMouseState == newMouseState) {
                    return;
                }
                // otherwise store new value
                pendingMouseState = newMouseState;
                // and start timeout
                startTimer();
            };

            function startTimer() {     
                // if timeout started then do nothing
                if (timeoutStarted) {
                    return;
                }

                // start timeout 10 ms
                $timeout(function () {
                    // reset value of timeoutStarted flag
                    timeoutStarted = false;
                    // apply new value
                    $scope.mouseOver = pendingMouseState;
                }, 10, true);
            }
        },
        link: function (scope, element) {
            //**********************************************
            //  bind to "mouseenter" and "mouseleave" events
            //**********************************************
            element.bind('mouseover', function (event) {
                scope.changeMouseState(true);
            });

            element.bind('mouseleave', function (event) {
                scope.changeMouseState(false);
            });

            //**********************************************
            //  watch value of "mouseOver" variable
            // or you create bindings in markup
            //**********************************************
            scope.$watch("mouseOver", function (value) {
                console.log(value);
            });
        }
    }
});

То же самое на http://jsfiddle.net/22WgG/

Также вместо

element.bind("mouseenter", ...);

а также

element.bind("mouseleave", ...);

вы можете указать

<tr enter ng-mouseenter="changeMouseState(true)" ng-mouseleave="changeMouseState(false)">...</tr>

См. http://jsfiddle.net/hwnW3/.

person kostik    schedule 10.03.2013