JQuery, сочетающий фокус и события наведения - PullRequest
2 голосов
/ 25 декабря 2009

У меня возникли проблемы с объединением событий HOVER и FOCUS с jquery. Это то, что у меня было изначально:

$("input,textarea").focus(function () {

    $(this).parent().siblings('div.exp').removeClass('hide');
    $(this).parent().siblings('div.exp').addClass('show');

});


$("input,textarea").blur(function (){

    $(this).parent().siblings('div.exp').removeClass('show');
    $(this).parent().siblings('div.exp').addClass('hide');
    if ($(this).val().length <= 0) {
        $(this).siblings('span.warning').removeClass('hide');
        $(this).siblings('span.warning').addClass('show');}

    else {

        $(this).siblings('span.warning').removeClass('show');
        $(this).siblings('span.warning').addClass('hide');
    }


});

По сути, у меня есть форма контакта пользователя со строками, подобными приведенным ниже:

<div class="row">
  <p><label>Your Name</label><input type="text" name="name" id="name" value=""/><span class="warning">Your name is missing</span></p>
  <div class="exp">Who am I to address?</div> 
</div>

Смысл моего кода Jquery состоит в том, чтобы выдать скрытый div (exp), когда пользователь фокусирует какой-либо один элемент ввода или элемент textarea, а также проверить, не является ли значение указанного ввода пустым при расфокусировке (размытии) элемента. (Я еще не приступил к проверке, так что проверка длины строки сейчас является лишь временным заполнителем). Если элемент имеет строку, меньшую или равную 0, то span.warning должен быть «показан» пользователю.

Это все работает хорошо. Вот где я застрял:

Я хочу добавить курсор, но без конфликта с фокусом. Мой желаемый конечный эффект таков:

Вы наведите курсор на любой ввод или текстовую область, и вы получите div.exp, чтобы показать (exp для объяснения). Вы фокусируете любой ввод или область, и div.exp остается там, даже если вы собираетесь навести курсор на любые другие входы или текстовые области. Если вы наведите курсор на уже сфокусированный ввод, ничего не произойдет.

Итак, в двух словах, элементы фокусировки и наведения должны работать, так сказать, «независимо». Не уверен, что я ясно дал понять, ну да ладно, я попытался =)

Приветствие G

Ответы [ 2 ]

4 голосов
/ 26 декабря 2009

Ваш код можно значительно сократить, используя .hide() и .show() и связывая события. Я разместил демо здесь .

$(document).ready(function(e){
 // hide all explanations and warnings
 $('.exp, .warning').hide();
 // add focus, blur and hover events to all inputs & textareas
 $('input,textarea')
  // if focused, show the explanation
  .focus(function(){
   // show explanation on focus (and add a class so the hover function knows not to hide it
   $(this).addClass('focused').closest('.row')
    .find('.exp').show()
    .find('.warning').hide();
  })
  .blur(function(){
   // hide explanation on blur
   $(this).removeClass('focused').closest('.row').find('.exp').hide();
   if ($(this).val().length < 1) {
    // input is empty, show the warning
    $(this).closest('.row').find('.warning').show();
   } else {
    // input is not empty, hide the warning... you might want to add the validation here
    $(this).closest('.row').find('.warning').hide();
   }
  })
  .hover(function(){
   // show explanation when hovered
   $(this).closest('.row').find('.exp').show();
  },function(){
   // hide explanation if the input is not focused
   if ($(this).is(':not(.focused)')) $(this).closest('.row').find('.exp').hide();
  })
});
3 голосов
/ 25 декабря 2009

Вы можете установить флаг для входа или текстовой области, пока он сфокусирован, чтобы избежать конфликта с вашим событием наведения. Если флаг установлен в значение true, когда происходит событие over или out, его код не выполняется. Следующий код демонстрирует идею (я не проверял ее).

$("input,textarea").focus( function()
{
    $(this).parent().siblings( 'div.exp' ).removeClass( 'hide' ).addClass( 'show' );
    $(this).data( "hasFocus", true );
} );

$("input,textarea").blur(function()
{
    $(this).parent().siblings( 'div.exp' ).removeClass( 'show' ).addClass( 'hide' );

    if( $(this).val().length <= 0 )
        $(this).siblings( 'span.warning' ).removeClass( 'hide' ).addClass( 'show' );
    else
        $(this).siblings( 'span.warning' ).removeClass( 'show' ).addClass( 'hide' );

    $(this).data( "hasFocus", false );
});

$("input,textarea").hover( function()
{
    // Over event
    if( typeof $(this).data( "hasFocus" ) != undefined && !$(this).data( "hasFocus" ) )
        $(this).parent().siblings( 'div.exp' ).removeClass( 'hide' ).addClass( 'show' );
},
function()
{
    // Out event
    if( typeof $(this).data( "hasFocus" ) != undefined && !$(this).data( "hasFocus" ) )
        $(this).parent().siblings( 'div.exp' ).removeClass( 'show' ).addClass( 'hide' );
} );
...