【问题标题】:jquery custom events attached to .show and .hide附加到 .show 和 .hide 的 jquery 自定义事件
【发布时间】:2012-05-22 20:05:44
【问题描述】:

我正在探索 jquery 满足我们一些 UI 要求的潜力,并且正在经历一些奇怪的行为。我对 jQuery 很陌生,我正在尝试实现一种基本的 pub-sub 类型的模式,它与 show & hide 函数挂钩。

尽管自定义事件机制表面上看起来非常简单,但它的行为并不符合我的预期。我看不出我的语法错误,所以我一定是误解了这些自定义事件的工作方式。

当我执行这段代码时,这就是我认为应该发生的事情。

最初(在 doc.Ready 之后)应该隐藏 question2 元素。

当我点击“佛蒙特州”单选按钮时,问题 2 应该会显示出来,然后会出现一个警告框,指示“问题 2 已显示”。

当我点击另一个单选按钮时,问题 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>

感谢收看。

【问题讨论】:

    标签: jquery-ui jquery


    【解决方案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

    【讨论】:

    • 向你致敬,因为你创造了我想要的行为。我真的需要了解发生了什么。你能帮我理解为什么我最初发布的代码的行为方式是这样的吗?非常感谢您的帮助。
    • @Todd,要了解发生了什么,您当然必须深入了解跟踪$.hide() 的jQuery 代码本身。如果有帮助,别忘了标记答案;)
    • 谢谢亚历山大,答案肯定很有帮助。但它并没有真正回答这个问题,因为我仍然不明白是什么导致了我所经历的行为。非常感谢您发布它。
    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多