web-dev-qa-db-ja.com

jQueryUIオートコンプリートで$(this)を機能させることができません

JQueryUIを使用して一般的なオートコンプリートスクリプトを作成しようとしています。オートコンプリートは次のすべてで機能するはずです。

<input type='text' class='autocomplete' id='foo'/>
<input type='text' class='autocomplete' id='bar'/>
...

$(this)を使用してソース関数の「foo」または「bar」にアクセスしようとしていますが、アラートを出すと常に「undefined」になります。

$('input.autocomplete').autocomplete({
    source: function(req, add){
        var id = $(this).attr('id');
        alert(id);
    }
});

私は何が間違っているのですか?

30
bart

クロージャを使用して関連する要素への参照を保持し、選択したアイテムごとに個別にオートコンプリートを設定します。次のようなもの:

_$('input.autocomplete').each(function(i, el) {
    el = $(el);
    el.autocomplete({
        source: function(req, add) {
            var id = el.attr('id');
            alert(id);
        }
    });
});
_

代替(編集)

each()の使用にこのような抵抗がある理由がわかりません。それは機能し、コードは非常に明確で読みやすく、効率に問題はありません。しかし、each()を避けようと決心した場合は、別の方法があります...

*注意:次のアプローチは(少し)jQueryオートコンプリートの内部に依存しているため、最初のオプションをお勧めします...しかし、選択はあなた次第です。

_$('input.autocomplete').autocomplete({
        source: function(req, add) {
            var id = this.element.attr('id');
            alert(id);
        }
    });
});
_

これは、少なくともsource()関数がautocompleteプラグイン内から呼び出される方法を変更するまで/変更しない限り機能します。

したがって、2つのオプションがあります...誰にとっても何か。

57
Lee

その入力要素にアクセスするには、次のことができるはずです。

$(this.element).val();

もちろん、それは価値を得るだけです。次のように他の属性にアクセスできます。

$(this.element).attr('value'); // just another way to get the value
$(this.element).attr('id');

また、 select event でその要素にアクセスしたい場合は、次のように行うことができます。

$(event.target).attr('value');
$(event.target).attr('id');
3
SeanWM

$(this)は新しく作成された関数から取得されるため、機能しません。 id宣言をsourceの上に移動すると、機能するはずです。

0
Marwelln

マーウェリンは正しいです。 「this」は、ネストされた新しく作成された関数を参照します。これは、関数の外部でvar idを作成し、関数内で使用することで簡単に修正できます。

0
Glycerine

文字通りthisが答えです。 not$( 'this')or$(this)just- これ

例:

$(".peoplepicker").autocomplete({
    source: function (request, response) {
        var url = "/data/myResource";

        var thisControl = this.element; // <<---

        $.ajax({
            url: url,
            type: "GET",
            headers: {
                Accept: "application/json;odata=nometadata"
            },
            async: true,
            cache: false,
            beforeSend: function () {
                thisControl.parent().parent().find(".srchstat").hide();    // <<===
                thisControl.parent().parent().find(".searching").fadeIn(); // <<===
            },
... [snipped]

thisControl = this.element;を使用すると、後でthisControlのスコープ内でターゲットコントロールを操作できます。このような:

thisControl.css("color","red");

または

thisControl.parent().parent().find(".searching").fadeIn();

これがお役に立てば幸いです。 fwiw:これが本番アプリでの動作方法です。

/* I am using: */
/*! jQuery v3.3.1 
/*! jQuery UI - v1.12.1 - 2020-02-03
0
Joe Johnston