3

私は、UI 要件の一部を満たすために jquery の可能性を探っていますが、いくつかの奇妙な動作を経験しています。私は jQuery に非常に慣れていないので、show & hide 関数にフックされた基本的な pub-sub タイプのパターンを実装しようとしています。

カスタム イベント メカニズムは表面上は完全に単純に見えますが、期待どおりに動作していません。構文上の間違いが見当たらないので、これらのカスタム イベントの動作方法を誤解しているに違いありません。

このコードを実行すると、次のようになるはずです。

最初に (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>

ご覧いただきありがとうございます。

4

1 に答える 1

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機能を利用することです。そこから、コードをリファクタリングしてきれいにすることができます。

実際の例を見てみましょう。

于 2012-05-22T21:49:57.223 に答える