2012-05-23 60 views
0

好的,所以我一直在這方面工作太久。請幫我理解爲什麼這樣做。jquery自定義事件附加顯示和隱藏(包括兒童)

我以前發佈的,這是一個類似的問題,但這裏不一樣的:jquery custom events attached to .show and .hide

我收到了一些代碼,工作這個問題的迴應,但沒有任何解釋。

我已轉向所需功能的下一個步驟,並且該發佈中提供的解決方案不能滿足這些擴展的要求。我在嘗試修改代碼時遇到了一些麻煩,不知道爲什麼它的行爲方式如此。

我希望腳本在任何觀看元素更改可見性時觸發一個事件。該元素是否被顯式顯示/隱藏,或該元素是否具有正在顯示/隱藏的祖先。所以如果我修改包含我正在觀看的其他兩個div的div的可見性,那麼我希望這兩個內部div中的每一個都觸發一個事件,表明它們的可見性已更改,即使我'在祖先div上稱爲show/hide。

理想情況下,我希望在回調之前觸發這些事件,以便在對用戶進行任何明顯改變之前執行任何受影響的代碼。

聽起來很簡單。

我注意到的問題之一是這兩個示例的行爲不同。 'question2'的操縱似乎並沒有觸發'madeHidden'。這兩個例子的行爲有所不同。

這是我迄今爲止沒有工作的代碼。 請幫忙。

<script type="text/javascript"> 
    var hiddenBefore; 
    var visibleBefore; 
    function processRadioButtonASD1() { 
     var isChecked = ($("input[name='question1']:checked").val() == "question1.Vermont"); 
     if (isChecked == true) { 
      $("[data-uniquename='question2']").show(250); 
     } else { 
      $("[data-uniquename='question2']").hide(250); 
     } 
    } 
    function watchVisibilityChange(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 processRadioButtonASD2() { 
     var isChecked = ($("input[name='question5']:checked").val() == "question5.Vermont"); 
     if (isChecked == true) { 
      $("[data-uniquename='c']").show(250); 
     } else { 
      $("[data-uniquename='c']").hide(250); 
     } 
    } 
    $(function() { 
     $.each(["show", "hide"], function() { 
      var _oldFn = $.fn[this]; 
      $.fn[this] = function() { 
       var _name = $(this).attr("data-uniquename"); 

       hiddenBefore = $(this).parent().find(":hidden"); 
       visibleBefore = $(this).parent().find(":visible"); 

       var result = _oldFn.apply(this, arguments); 

       //trigger handler on newly visible elements      
       hiddenBefore.filter(":visible").each(function() { 
        $(this).triggerHandler("madeVisible"); 
       }); 

       //trigger handler on newly hidden elements 
       visibleBefore.filter(":hidden").each(function() { 
        $(this).triggerHandler("madeHidden"); 
       }); 
       return result; 
      } 
     }); 
    }); 
    $(document).ready(function() { 

     watchVisibilityChange("question2"); 
     watchVisibilityChange("c.question6"); 
     watchVisibilityChange("c.question7"); 

     processRadioButtonASD1(); 
     processRadioButtonASD2(); 

     //hook up behavior to the appropriate change events 
     $("input[name='question1']").change(function() { 
      processRadioButtonASD1(); 
     }); 
     $("input[name='question5']").change(function() { 
      processRadioButtonASD2(); 
     }); 
    }); 
</script> 

這裏是html。

<div runat="server" id="promptContent"> 
    <div id="radioButtonASD" class="oneExample"> 
     <h2> 
      radio button trigger one</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> 
     <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 id="cascadingASD" class="oneExample"> 
     <h2> 
      radio button trigger multiple</h2> 
     <div data-uniquename="question1" class="question"> 
      <label for="question1"> 
       Question 5) (select Vermont to show question6) 
      </label> 
      <br /> 
      <label data-uniquename="question5.Maine"> 
       <input name="question5" data-uniquename="question5.Maine" type="radio" value="me" />Maine</label><br /> 
      <label data-uniquename="question5.Vermont"> 
       <input name="question5" data-uniquename="question5.Vermont" type="radio" value="question5.Vermont" />Vermont</label><br /> 
      <label data-uniquename="question5.NewHampshire"> 
       <input name="question5" data-uniquename="question5.NewHampshire" type="radio" value="question5.NewHampshire" />New 
       Hampshire</label><br /> 
      <label data-uniquename="question5.Conneticut"> 
       <input name="question5" data-uniquename="question5.Conneticut" type="radio" value="question5.Conneticut" />Conneticut</label><br /> 
      <label data-uniquename="question5.Massachusetts"> 
       <input name="question5" data-uniquename="question5.Massachusetts" type="radio" value="question5.Massachusetts" />Massachusetts 
      </label> 
     </div> 
     <div data-uniquename="c"> 
      <div data-uniquename="c.question6" class="question"> 
       <label> 
        Container Question 6) 
       </label> 
       <br /> 
       <select> 
        <option data-uniquename="c.question6.honda" value="honda">Honda</option> 
        <option data-uniquename="c.question6.volvo" value="volvo">Volvo</option> 
        <option data-uniquename="c.question6.saab" value="saab">Saab</option> 
        <option data-uniquename="c.question6.mercedes" value="mercedes">Mercedes</option> 
        <option data-uniquename="c.question6.audi" value="audi">Audi</option> 
       </select> 
      </div> 
      <div data-uniquename="c.question7" class="question"> 
       <label> 
        Container Question 7) 
       </label> 
       <br /> 
       <select> 
        <option data-uniquename="c.question7.honda" value="honda">Honda</option> 
        <option data-uniquename="c.question7.volvo" value="volvo">Volvo</option> 
        <option data-uniquename="c.question7.saab" value="saab">Saab</option> 
        <option data-uniquename="c.question7.mercedes" value="mercedes">Mercedes</option> 
        <option data-uniquename="c.question7.audi" value="audi">Audi</option> 
       </select> 
      </div> 
     </div> 
    </div> 
</div> 

我真的很喜歡解決方案,但大多我很想知道爲什麼這不按預期工作。

謝謝你的幫助。

回答

0

我很確定我想通了。 我已經明確了我的理解,拔掉了一些頭髮,並且似乎達到了我的目標。

 $.each(["hide"], function() { 
     var effect = $.fn[this]; 
     $.fn[this] = function (duration, move, callback) { 
      var speed = duration; 
      var easing = callback && move || move && !jQuery.isFunction(move) && move; 
      var _mainElement = $(this); 
      var _mainElementOriginallyVisible = $(this).is(":visible"); 
      var _visibleChildrenBefore = $(this).find(":visible"); 
      return effect.call(this, speed, easing, function() { 
       if (_mainElementOriginallyVisible == true) { _mainElement.triggerHandler("madeHidden"); } 
       _visibleChildrenBefore.each(function() { 
        if (!($(this).is(":visible"))) { 
         if ($(this).attr("data-un") !== undefined) { $(this).triggerHandler("madeHidden"); } 
        } 
       }); 
      }); 
     }; 
    }); 
    $.each(["show"], function() { 
     var effect = $.fn[this]; 
     $.fn[this] = function (duration, move, callback) { 
      var speed = duration; 
      var easing = callback && move || move && !jQuery.isFunction(move) && move; 
      var _mainElement = $(this); 
      var _mainElementOriginallyVisible = $(this).is(":visible"); 
      var _hiddenChildrenBefore = $(this).find(":hidden"); 
      return effect.call(this, speed, easing, function() { 
       if (_mainElementOriginallyVisible == false) { _mainElement.triggerHandler("madeVisible"); } 
       _hiddenChildrenBefore.each(function() { 
        if (!($(this).is(":hidden"))) { 
         if ($(this).attr("data-un") !== undefined) { $(this).triggerHandler("madeVisible"); } 
        } 
       }); 
      }); 
     }; 
    }); 

我最初的代碼似乎是與異步動畫有關的最顯着的問題。我的代碼在觸發動畫後立即執行,並沒有等待它完成,因此我剛剛試圖隱藏的元素並未實際隱藏在後續的代碼行中。

我必須利用回調參數來等待動畫在繼續執行之前完成。

這是我到達的代碼。我相信它可以被改進。 請不要猶豫,就如何收緊代碼提供建議。 我只有一個星期左右到jQuery,我想學習。

我認識到除了顯示/隱藏之外,還有其他方法可以改變元素的可見性,我很滿意這些方法必須用於觸發自定義事件的限制。 我也應用了一個故意限制,即只有具有我自定義屬性data-un(以前是data-uniquename)的項目纔會觸發事件。

-Todd