收听同一元素上的多个事件以触发

时间:2015-11-19 21:15:09

标签: jquery javascript-events listener jquery-deferred

我需要你的帮助,因为我的智慧结束了。我试图在表单元素上等待多个事件。为了告诉你我的意思,这是一个例子:

var el = this,
    conditions = $( this ).data( 'conditions' ),
    promises = [];

$( conditions ).each( function () {
    var def = new $.Deferred(),
        condition = this;

    $( el ).hide();

    $( this.listener ).on( 'change', function () {
        if ( $( '#' + condition.target ).is( ':checked' ) ) {
            def.resolve( 'show' );
        } else {
            def.resolve( 'hide' );
        }

        promises.push( def );
    } );
} );

$.when.apply( undefined, promises ).done( function ( res ) {
    console.log( res );
} );

这背后的想法是,我可以监听select元素并检查用户选择的值。如果条件验证为true,则显示另一个元素。

现在的问题是:如果我在同一个元素上有另一个条件,则两个侦听器都执行,一个验证为true,另一个为false。

所以我尝试延期。上面的示例第一次正常工作。如果用户再次发出事件,则延迟不会再次解决。我期待这一点,因为承诺只能解决一次。

另一种方式是,如果我只使用纯jQuery监听器,它们都会被触发,最后一个连接的监听器显示或隐藏元素。但我需要立刻评估所有听众。

我的问题是,我怎么能解决这个问题?有人可以给我一个如何实现这个的提示吗?

问候克尔斯滕

1 个答案:

答案 0 :(得分:0)

感谢@jfriend00给我一个提示。

这是我最终得到的一个例子:

var el = $( '#formfield-3' ),
    conditions = $( el ).data( 'conditions' ),
    targetConditions = {};

$( el ).on( 'condition.check', function () {
    var show = false;

    $.each( targetConditions, function ( key, target ) {
        switch ( key ) {
            case 'show':
                $.each( target, function ( key, value ) {
                    if ( ! show ) {
                        show = value.indexOf( true ) !== - 1;
                    }
                } );

                break;
        }
    } );

    if ( show ) {
        $( el ).parent( '.forminput-group' ).show();
    } else {
        $( el ).parent( '.forminput-group' ).hide();
    }
} );

$( conditions ).each( function () {
    var condition = this;

    if ( ! targetConditions[this.type] ) {
        targetConditions[this.type] = {};
    }

    if ( ! targetConditions[this.type][this.target] ) {
        targetConditions[this.type][this.target] = [];
    }

    if ( ! targetConditions[this.type][this.target][this.id] ) {
        targetConditions[this.type][this.target][this.id] = false;
    }

    $( el ).hide();

    $( this.listener ).on( 'change', function () {
        targetConditions[condition.type][condition.target][condition.id] = false;

        switch ( condition.condition ) {
            case 'selected':
                if ( $( '#' + condition.target ).is( ':checked' ) ) {
                    targetConditions[condition.type][condition.target][condition.id] = true;
                }

                break;
        }

        $( el ).trigger( 'condition.check' );
    } );
} );

这是我用来测试它的工作表单元素标记:

<input id="formfield-1" name="sample" type="radio" value="1">
<input id="formfield-2" name="sample" type="radio" value="2">

<select id="formfield-3" data-conditions="[{"id":1,"target":"formfield-1","listener":"input[name=sample]:radio","type":"show","condition":"selected","value":null,"element":"select"},{"id":2,"target":"formfield-2","listener":"input[name=sample]:radio","type":"show","condition":"selected","value":null,"element":"select"}]">
    <option>Please select</option>
    <option>Sample Value</option>
</select>

这将在无线电组上创建两个侦听器,无论选择什么,都将显示选择框。

这只是一个非常小的演示,但我希望如果其他人有这样的问题,我可以帮忙解决这个问题:)

非常感谢