简体   繁体   中英

What's the most efficient way to perform an action based on matching form input values using jQuery?

Let's say I have three related text input fields:

<input name="x1" class="xField" value="" /><div class="note" style="display:none;">Match</div>
<input name="x2" class="xField" value="" /><div class="note" style="display:none;">Match</div>
<input name="x3" class="xField" value="" /><div class="note" style="display:none;">Match</div>

Now, when the value of any of these changes, and it matches the value of another one of the related fields, I want to "un-hide" the .note div next to each input with matching value.

So, this is what I have so far:

$(function() {
    $(".xField").change(updateCommentsDisplay);

    function updateCommentsDisplay() {
        var $aVisibleNotes = [];

        $(".xField").each(function() {
            // If more than one field with the same value, add the next note div to an array
            if ($(".xField[value="+$(this).val()).length > 1)
                $aVisibleNotes.push($(this).next(".note");
        });

        $.each($aVisibleNotes, function(){
            $(this).show();
        });
    }
});

This just doesn't feel efficient. I feel like I should be able to do this without loops. Any suggestions?

To do it without loops, simply use selectors. Also specify not(this) if you don't want the input to show the note following it.

$(".xField").keyup(function(){
    var val=$(this).val();       
    $('.xField[value='+val+']').not(this).next(":hidden").show();
});

You can combine selectors to get the result....xField, same value, different input = show the next note.

$('.xField').change(function() {
    var x = $(this);
    $('.xField[value="' + x.val() + '"]')
            .not(this).next('.note').show();
});

Instead of looping through each input just use a selector to find the inputs whose value matches:

$(function() {
    $(".xField").change(function(){
        var field_val = $(this).val();
        $(".xField[value='" + field_val + "']").show();
    });
});

For one thing, you should save the results of $(".xField');

So:

$(function() {
    var xFields = $('.xField');
    xFields.change(updateCommentsDisplay);

    function updateCommentsDisplay() {
        var $aVisibleNotes = [];

        xFields.each(function() {
            // If more than one field with the same value, add the next note div to an array
            if(xFields.find('[value="' + $(this).val() + '"]').size() > 1)
                $aVisibleNotes.push($(this).next(".note");
        });

        $.each($aVisibleNotes, function(){
            $(this).show();
        });
    }
});

It also might be faster to use an actual value comparison instead of the Sizzle engine to find matches. You'd want to test it on jsperf, but I have a hunch.

turn them on and off if matches or no matches:

$(".xField").change(function() {
        updateCommentsDisplay();
});

function updateCommentsDisplay() {
    $(".xField").each(function() {
        if ($(".xField[value=" + $(this).val() + "]").length > 1) {
            $(this).next(".note").show();
        }
        else {
            $(this).next(".note").hide();
        };
    });
};

See it in action: http://jsfiddle.net/MarkSchultheiss/UrBEk/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM