eventos personalizados de jquery adjuntos a .show y .hide

Estoy explorando el potencial de jquery para satisfacer algunos de nuestros requisitos de interfaz de usuario y estoy experimentando un comportamiento curioso. Soy muy nuevo en jQuery, y estoy tratando de implementar un tipo de patrón pub-sub básico que está conectado a las funciones de mostrar y ocultar.

A pesar de que el mecanismo de eventos personalizados parece perfectamente simple en la superficie, no se comporta como esperaba. No puedo ver mi error sintáctico, por lo que debo estar malinterpretando la forma en que estos eventos personalizados están destinados a funcionar.

Cuando ejecuto este código, esto es lo que pienso debemos suceder.

Inicialmente (después de doc.Ready) el elemento question2 debe estar oculto.

Cuando hago clic en el botón de opción 'Vermont', la pregunta 2 debe hacerse visible seguida de un cuadro de alerta que indica que 'la pregunta 2 se ha hecho visible'.

Cuando hago clic en otro botón de radio, la pregunta 2 debe ocultarse seguida de un cuadro de alerta que indica que la pregunta 2 se ha ocultado.

Lo que sucede en realidad es que recibo numerosos cuadros de alerta cuando hago visible la pregunta 2, y ninguno cuando la oculto. Por favor, ayúdame a entender por qué está haciendo esto.

Aquí está el guión:

    <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>

Aquí está el 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>

Gracias por mirar.

preguntado el 22 de mayo de 12 a las 21:05

1 Respuestas

Se me ocurrió una forma alternativa.

$.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);
    };
});

La idea es hacer uso de la callback función. Desde allí puede refactorizar y limpiar el código.

Echa un vistazo a un ejemplo de trabajo.

contestado el 22 de mayo de 12 a las 22:05

Me quito el sombrero por crear el comportamiento que buscaba. Sin embargo, realmente necesito entender lo que está pasando. ¿Me pueden ayudar a entender por qué el código que publiqué originalmente se comportaba de esa manera? Muchas gracias por su ayuda. - Todd

@Todd, Bueno, para entender lo que estaba pasando, tendrías que profundizar en el código jQuery rastreando $.hide() por supuesto. Y no olvides marcar la respuesta si te fue útil ;) - Alexander

Gracias Alexander, la respuesta fue definitivamente útil. Sin embargo, realmente no respondió la pregunta porque todavía no entiendo qué estaba causando el comportamiento que estaba experimentando. Muchas gracias por publicarlo. - Todd

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.