2012-05-22 29 views
3

我正在探索的jQuery的潛力,以滿足我們的一些用戶界面的要求,並遇到一些好奇的行爲。我對jQuery非常陌生,我正在嘗試實現一種基本的pub-sub類型的模式,該模式被迷住了隱藏函數。jQuery的自定義事件附加到.show和.hide

儘管自定義事件機制在表面上看起來非常簡單,但其行爲並不像我期望的那樣。我看不到我的語法錯誤,所以我必須誤解這些定製事件的工作方式。

當我執行此代碼時,我認爲應發生

最初(在doc.Ready之後)應該隱藏question2元素。

當我點擊'Vermont'單選按鈕時,問題2應該變爲可見,隨後顯示一個警告框,指示'question2已經變得可見'。

當我點擊另一個單選按鈕時,問題2應該隱藏,然後一個警告框指示問題2已被隱藏。

實際發生的事情是,當使問題2可見時我得到許多警報框,而當我隱藏它時沒有任何警報框? 請幫我理解爲什麼這樣做。

下面是腳本:

<script type="text/javascript"> 

    function processRadioButtonASD() { 
     var isChecked = ($("input[name=question1]:checked").val() == "question1.Vermont"); 
     if (isChecked == true) { 
      $("[data-uniquename=question2]").show(250); 
     } else { 
      $("[data-uniquename=question2]").hide(250); 
     } 
    } 

    function detectVisibilityChange(uniqueName) { 
     $("[data-uniquename=" + uniqueName + "]").bind("madeVisible", function() { 
      alert($(this).attr("data-uniquename") + " was made visible"); 
     }); 
     $("[data-uniquename=" + uniqueName + "]").bind("madeHidden", function() { 
      alert($(this).attr("data-uniquename") + " was made hidden"); 
     }); 
    } 

    $(function() { 
     $.each(["show", "hide"], function() { 
      var _oldFn = $.fn[this]; 
      $.fn[this] = function() { 
       var wasVisible = $(this).is(':visible'); 
       var result = _oldFn.apply(this, arguments); 
       var isVisible = $(this).is(':visible'); 

       if ((isVisible == true) && (wasVisible == false)) { 
        $(this).triggerHandler("madeVisible"); 
       } else if ((isVisible == false) && (wasVisible == true)) { 
        $(this).triggerHandler("madeHidden"); 
       } 
       return result; 
      } 
     }); 
    }); 

    $(document).ready(function() { 
     processRadioButtonASD(); 
     detectVisibilityChange("question2"); 
     $("input[name='question1']").change(function() { processRadioButtonASD(); }); 
    }); 
</script> 

下面是HTML:

<div id="content"> 
    <div id="radioButtonASD" class="example"> 
     <h2>radio button visibility trigger</h2> 
     <div data-uniquename="question1" class="question"> 
      <label for="question1"> 
       Question 1) (select Vermont to show Question2) 
      </label> 
      <br /> 
      <label data-uniquename="question1.Maine"> 
       <input name="question1" data-uniquename="question1.Maine" type="radio" value="me" />Maine</label><br /> 
      <label data-uniquename="question1.Vermont"> 
       <input name="question1" data-uniquename="question1.Vermont" type="radio" value="question1.Vermont" />Vermont</label><br /> 
      <label data-uniquename="question1.NewHampshire"> 
       <input name="question1" data-uniquename="question1.NewHampshire" type="radio" value="question1.NewHampshire" />New 
       Hampshire</label><br /> 
      <label data-uniquename="question1.Conneticut"> 
       <input name="question1" data-uniquename="question1.Conneticut" type="radio" value="question1.Conneticut" />Conneticut</label><br /> 
      <label data-uniquename="question1.Massachusetts"> 
       <input name="question1" data-uniquename="question1.Massachusetts" type="radio" value="question1.Massachusetts" />Massachusetts 
      </label> 
     </div> 
    <br /> 
     <div data-uniquename="question2" class="question"> 
      <label> 
       Question 2) 
      </label> 
      <br /> 
      <select> 
       <option data-uniquename="question2.honda" value="honda">Honda</option> 
       <option data-uniquename="question2.volvo" value="volvo">Volvo</option> 
       <option data-uniquename="question2.saab" value="saab">Saab</option> 
       <option data-uniquename="question2.mercedes" value="mercedes">Mercedes</option> 
       <option data-uniquename="question2.audi" value="audi">Audi</option> 
      </select> 
     </div> 
    </div> 
</div> 

感謝您尋找。

回答

1

我想出了一種替代方法。

$.each(["show", "hide"], function() { 
    var effect = $.fn[this]; 
    $.fn[this] = function(duration, move, callback) { 
     // Match the arguments 
     var speed = duration; 
     var easing = callback && move || move && !jQuery.isFunction(move) && move; 
     var fn = callback || !callback && move || jQuery.isFunction(duration) && duration; 
     // Wrap the callback function 
     var wrapped = fn; 
     var wasVisible = $(this).is(':visible'); 
     fn = function(){ 
      var isVisible = $(this).is(':visible'); 
      $.proxy(wrapped, this); 
      if ((isVisible == true) && (wasVisible == false)) { 
       $(this).triggerHandler("madeVisible"); 
      } else if ((isVisible == false) && (wasVisible == true)) { 
       $(this).triggerHandler("madeHidden"); 
      } 
     }; 
     // Run the effect with the wrapped callback    
     return effect.call(this, speed, easing, fn); 
    }; 
}); 

這個想法是利用callback函數。從那裏你可以重構和清理代碼。

看看a working example

+0

爲了創造我所追求的行爲,我真的需要了解發生了什麼。你能幫我理解爲什麼我最初發布的代碼的行爲方式如此嗎? 非常感謝您的幫助。 – Todd

+0

@Todd,爲了理解發生了什麼,你必須挖掘jQuery代碼本身,當然追蹤'$ .hide()'。如果有幫助,請不要忘記標記答案;) – Alexander

+0

感謝Alexander,答案肯定有幫助。它並沒有真正回答這個問題,因爲我仍然不明白是什麼導致了我所經歷的行爲。非常感謝發佈它。 – Todd