jQuery 1.9.1 property selector

2019-02-06 00:37发布

问题:

Background

As of jQuery 1.9 the .attr(..) method no longer returns property values, instead we now have to use .prop(..). Unfortunately this also applies to attributes specified via an attributes selector i.e. $("input[value=]")

See http://jquery.com/upgrade-guide/1.9/#attr-versus-prop-

and a good SO discussion on the differences between .attr and .prop :

.prop() vs .attr()

My Situation

I'm currently using selectors like $("input[value=]") and $("select[value=]") to select input elements that have no value set. However, this no longer works with jQuery 1.9, instead I'm now doing something like this:

var hasValue = function () { return !!($(this).val().length); };
var hasNoValue = function () { return !($(this).val().length); };
$("input").filter(hasValue);
$("select").filter(hasValue);

My actual selectors are a little larger, checking multiple elements with or without values so now I'm having to split my 1 selector string into multiple selectors with .filter(..) method calls in between.

Question

Is there an equivalent to $("[value=]"), $("[value!=]"), $("[value='abc']") which uses the property instead of the attribute? And if not, is there a cleaner way than using the .filter(hasValue) and .filter(hasNoValue) methods?

Thanks

回答1:

Using .filter seems to be the only way, but it's not too bad and you can actually make it a little more accurate by using .val:

$(":input").filter(function () { return $(this).val() === ""; });

If this really is that reprehensible to you, you could create a custom selector.

$.expr[':'].emptyInput = function (elem) {
    return $(elem).is(":input") && $(elem).val() === "";
};

http://jsfiddle.net/ExplosionPIlls/zaZPp/

EDIT: You may also be able to get away with using this.value instead of $(elem).val().



回答2:

According to the upgrade guide:

However, when a selector like "input[value=abc]" is used, it should always select by the value attribute and not any change made to the property by the user, for example from them typing into a text input. As of jQuery 1.9, this behaves correctly and consistently. Earlier versions of jQuery would sometimes use the property when they should have used the attribute.

So this answers your first question - there is not a direct equivalent, the point is to use the attribute instead of the property.

Your code seems fine, but if you want to be more standardized and re-usable you could create an additional filter. Like so:

(function($) {
    $.expr[':'].hasValue = function(element) {
        var $element = $(element);
        return element.is(':input') && element.val();
    };
}(window.jQuery));

This will allow you to select stuff like that:

// Select input elements with value and select elements without value.
$('input:hasValue,select:not(:hasValue)');

And other various combinations you need.



回答3:

I came across this and just wanted to post another solution I found that works in some situations where some of the other suggested solutions are not appropriate.

Simply add this event handler to your code

    $('input').on('keyup', function(){  
        var value = $(this).val();
        $(this).attr('value', value);
    });