2012-01-02 2 views
0

Я пытаюсь создать раскрывающееся меню, которое можно открыть и закрыть с помощью кнопки Toggle и, ее можно закрыть, щелкнув в любом месте самого документа.jQuery Функция Toggle конфликтует с Mouseup

Когда человек нажимает кнопку Toggle, меню открывается должным образом. Если посетитель затем щелкнет в другом месте документа, меню закрывается , но требуется 2 клика, чтобы активировать функцию Toggle этой кнопки еще раз. Я бы хотел уменьшить это до . 1 раз нажмите, конечно.

Отъезд http://jsfiddle.net/MEweN/3/ по этому вопросу. Может ли кто-нибудь помочь мне, пожалуйста?

ответ

3

Toggle сохраняет состояние на объекте, на который вы его называете. Каждый раз, когда вы вызываете Toggle, он чередуется между функцией 1 и функцией 2. Он ничего не знает о вашем приложении. Он просто чередует между двумя функциями, которые вы передаете ему каждый раз, когда вы его вызываете.

Когда вы перезагружаете состояние всплывающего окна без использования Toggle, он выходит из синхронизации, поскольку теперь он не знает, что вы хотите вернуться в первое состояние. Таким образом, когда вы нажимаете снова, он выполняет вторую функцию, когда вы хотите, чтобы она выполняла первую функцию.

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

При работе с вашим фактическим кодом я также обнаружил, что обработка события mouseup в документе не очень совместима с обработкой события click в объекте. Проблема в том, что mouseup приходит до щелчка, поэтому вы получите оба события в последовательности, и вы не получите желаемого эффекта. Когда я изменил на щелчок в документе, он много работал проще так:

$("#general_show").click(function() { 
    var $this = $(this); 
    if ($this.hasClass('selected')) { 
     $this.removeClass('selected').parent().next().hide(); 
    } else { 
     $this.addClass('selected').parent().next().show(); 
    } 
    return(false); 
}); 

$(document).click(function (e) { 
    if ($('#general_info').is(':visible') && 
      $(e.target).parents('#general_info').length === 0) { 
     $('#general_show').removeClass('selected').parent().next().hide(); 
     return(false); 
    } 
}); 

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

+0

Спасибо! Отличное решение и отзывы. –

0
$("#general_show").click(function() { 
     if($(this).is('.selected')){ 
      $(this).removeClass().parent().next().hide() 
     }else{ 
      $(this).addClass('selected').parent().next().show() 
     } 
    }); 

    $(document).mouseup(function (e) { 
    if (
     $('#general_show').is('.selected') 
     && $(e.target).parents('#general_info').length === 0 
     && $(e.target).attr('id')!== "general_show" 
    ) { 
     $('#general_show').click() 
    } 
    }); 
0
$("#general_show").click(function() { 
    if ($('#general_info').is(':visible')){ 
     // Hiding informations 

     $(this).removeClass('selected').parent().next().hide(); // try to always pass argument to removeClass, which class you want to remove 
    } else { 
     // Showin informations  
     $(this).addClass('selected').parent().next().show(); 

    }}); 

$(document).mouseup(function (e) { 
    // We don't want to use this function when clicked on button 
    if (e.target.id == 'general_show') return; 

    if ($('#general_info').is(':visible')){ 

      $('#general_show').removeClass().parent().next().hide(); 
     } 
}); 

JSFiddle ссылка: http://jsfiddle.net/MEweN/5/