события jQuery;предотвратить "братьев и сестер" от запуска событий друг друга - PullRequest
2 голосов
/ 22 июля 2011

Используя jQuery 1.6.1 , учитывая, что у меня есть следующий HTML:

<div class="control">
    <label>My Control</label>
    <input type="text" />
    <input type="text" />
</div>

Когда <input> в <div class="control"> ( только в дальнейшем control) фокусируется, <label> ( с position: relative;) анимирует:

$('.control :input').bind('focus', function(e){
    $(this).prevAll('label').animate({
        'left': '-50px'
    }, 250);
});

А при размытии <label> возвращает:

.bind('blur', function(e){
    $(this).prevAll('label').animate({
        'left': '0px'
    }, 250);
});

Однако, если один из <input> элементов получает фокус, а затем размывается, когда фокус переключается на другой <input> в пределах того же control ( с помощью Tab или щелчком мыши ) события, конечно, все еще происходят, и <label> анимирует взад и вперед.

Как я могу заставить событие размытия запускаться только тогда, когда фокус теряется от всех входов в пределахучитывая control?

Ответы [ 5 ]

1 голос
/ 22 июля 2011

В blur обратном вызове вы можете определить, фокусируется ли какой-либо элемент ввода сейчас, используя $("input:focus").length.Если length>0, то не анимация

Обновление

А как насчет этого кода?

    var control;
    var inTheSameControl=false;
    $('.control :input').bind('focus', function(e){
        if(control)
        {
            if(control.find(this).length>0)
                inTheSameControl=true;
            else
                inTheSameControl=false;
        }
        control=$(this).parent();
        if(!inTheSameControl)
        {
            console.log('focus');
        }
    });
    $('.control :input').bind('blur', function(e){
        if(!inTheSameControl)
        {
            console.log('blur');
        }
    });

Работает с несколькими div.control Когда вы переключаете фокус на input в другом .contor, текст «фокус» входит в консоль, если вы остаетесь в том же .control- нет.Вместо console.log(...) вы можете написать, что хотите.Я не написал ваш код (анимацию), потому что это не предмет.

Надеюсь, это будет полезно.

1 голос
/ 22 июля 2011

В вашем обратном вызове размытия я бы посмотрел на что-то вроде селектора :focus, которое было введено в 1.6:

Использование jQuery для проверки, имеет ли фокус ввода

Если $('.control :focus).length > 0, то return - функция, которая не дает ему работать.

1 голос
/ 22 июля 2011

В прошлом я достиг чего-то похожего, вместо этого связав новый фокус с документом или формой, и заставив метку вернуться, вместо того, чтобы связать размытие с входными данными.

1 голос
/ 22 июля 2011

Редактировать: Обновлен ответ на основе большего количества входных данных, предоставленных ОП.

Если небольшая задержка в одну секунду для скрытия метки - это нормально, вы можете использовать комбинацию setTimeout / clearTimeout.. Примерно так:

<div class="control">
    <label>My Control</label>
    <input type="text" />
    <input type="text" />
    <input type="text" />
</div>
<div class="control">
    <label>My Control</label>
    <input type="text" />
    <input type="text" />
    <input type="text" />
</div>

<div class="control">
    <label>My Control</label>
    <input type="text" />
    <input type="text" />
    <input type="text" />
</div>

<div class="control">
    <label>My Control</label>
    <input type="text" />
    <input type="text" />
    <input type="text" />
</div>

    <script type="text/javascript"> 
        var timeoutIds = [];
            $('.control').each(function(index, el){
                $(':input', el).bind('focus', function(e){     
                        clearTimeout(timeoutIds[index]);
                        $(this).prevAll('label').animate({        
                                'left': '-50px'     
                        }); 
                });

                $(':input', el).bind('blur', function(e){     
                        var that = this;
                        timeoutIds[index] = setTimeout(function(){
                            $(that).prevAll('label').animate({        
                                    'left': '0px' 
                            }); 
                    }, 500);
                });
            });
    </script>

Рабочий пример: http://jsfiddle.net/Tn9sV/2/

0 голосов
/ 22 июля 2011

Два варианта, которые я могу придумать:

  • Вариант 1 (с использованием текущей схемы):

    • blur:. Задержать анимацию с помощьюдоля секунды

    • фокус:. остановить существующую анимацию

  • Вариант 2 (изменить элемент размытия):

    • изменить обозначение размытия, чтобы оно было на вашем div вместо метки
...