无法让 $(this) 在 jQueryUI 自动完成中工作

Posted

技术标签:

【中文标题】无法让 $(this) 在 jQueryUI 自动完成中工作【英文标题】:Can't get $(this) working in jQueryUI autocomplete 【发布时间】:2011-05-16 23:43:40 【问题描述】:

我正在尝试使用 jQueryUI 创建一个通用的自动完成脚本。自动完成应该适用于每个:

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

现在我正在尝试使用 $(this) 访问源函数中的“foo”或“bar”,但是在提醒时我总是得到“未定义”。

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

我做错了什么?

【问题讨论】:

目的是什么?要根据所选自动完成的 id 选择来源? 他想创建一个通用函数来自动完成传入的任何字段 id。 @Hollister,谢谢,但这并没有澄清。你经常这样“帮助”吗?为什么他需要根据自动完成附加到的元素来选择源?听起来他需要为每个自动完成元素创建一次代码块,或者为每种类型的代码块创建一次。这不是你做 DRY 的方式,通过在源代码控制定义结构中放置一个 if 块。它只会产生更复杂的代码。 @drachenstern 使用输入字段的 ID,我确定服务器端要返回哪些值。是的,这是一次 DRY 尝试。 你经常这样“评论”吗?显然,自动完成源列表必须匹配给定元素中预期的数据类型。他通过传入 id 来做到这一点。如果没有看到他的完整设计,我认为没有必要评论 DRY 方面。为了我们的利益,这显然是一个简化的示例。 【参考方案1】:

为您选择的每个项目分别设置自动完成,使用闭包来保存对相关元素的引用。类似于以下内容:

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

替代(编辑)

我不明白为什么使用each() 会有这么大的阻力:它有效,代码非常清晰易读,并且没有引入效率问题;但如果你决心避免使用each(),这里有一个替代方案……

*请注意:以下方法(有点)依赖于 jQuery Autocomplete 的内部结构,所以我推荐第一个选项......但选择权在你。

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

至少在/除非他们改变从autocomplete 插件中调用source() 函数的方式之前,这将起作用。

所以,你有两个选择……适合每个人。

【讨论】:

它可能有效,但我认为 each 在这里是不好的形式。现在查看源代码以确定是否有更好的选择。 刚刚测试过它确实有效。尚不确定这是否是最佳解决方案。 @bart ~ 我知道它有效,我只是认为它的形式不好。但是,如果有道理的话,糟糕的形式可能是你的,而不是@lee 的。你会回答我上面的问题吗? 无需破解自动完成界面的设计工作方式,这看起来还不错。如果使用 hack,它会比这更脆弱。 @drachenstern, @bart:使用each() 没有问题——恕我直言,它非常清楚代码的作用,并且不会产生任何不良副作用。也就是说,我发布了另一个不使用each() 的选项。第二个选项确实有点依赖于 jQuery Autocomplete 的内部结构,所以我推荐第一个选项......但它最终是你的选择。【参考方案2】:

要访问该输入元素,您应该能够执行以下操作:

$(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】:

$(this) 将来自您新创建的函数,因此不起作用。将您的 id 声明移到 source 上方,它应该可以工作。

【讨论】:

他不能将 $(this) 放在“源”之上,因为这会将它放在选项列表中,而不是他想要的。【参考方案4】:

Marwelin 是正确的。 'this' 将引用嵌套在其中的新创建的函数。通过在函数外部创建 var id 并在函数内部使用它,可以轻松解决此问题。

【讨论】:

【参考方案5】:

从字面上看,这个就是答案。不是 $('this')$(this) 只是 this

例子:

$(".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

【讨论】:

以上是关于无法让 $(this) 在 jQueryUI 自动完成中工作的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django 的 JQueryUI 自动完成搜索不起作用

jQueryUI自动完成在没有匹配时在下拉列表中显示“其他”并让用户能够选择它

调整 div 大小时无法让 Google 地图高度自动调整大小

jQueryUI 自动完成选项 - 样式问题

当内容长于高度时,可以让 jqueryUI 对话框滚动条从顶部开始吗?

如何让 jQueryUI 拖放与触摸设备一起使用