如何按人气排序选择下拉菜单?

时间:2014-11-11 15:15:28

标签: jquery

我有一个选择下拉列表,每天都会被很多不同的人使用。

我们的想法是为用户个性化此选择。

因此,例如,用户做出以下选择:

- Option a: 5 times
- Option c: 3 times
- Option f: 1 time

然后我们希望选择a,c,f,b,d,e。 简而言之,我们希望该用户最受欢迎的项目能够显示在最顶层。

现在,我确定我知道我可以使用jquery和cookie来制作这样的东西,但我想知道是否已经有解决方案可以做到这一点。

编辑: 我已经用谷歌搜索了这个,但没有找到任何与我正在寻找的东西接近的东西。

4 个答案:

答案 0 :(得分:2)

如果您想为用户个性化您的网站,我建议您避免使用仅限客户端的解决方案并依赖服务器端。例如,您永远不知道用户的localStorage何时会被删除。 此外,您可能希望将来对其他数据进行个性化设置,但这可能无法实现可扩展性。

我的解决方案是在数据库上保留一个额外的表,使用您的用户ID的外键(我假设您保留它们),这样可以保持他的偏好。您应该在用户做出的每个选择之后更新此表格(例如,将表单发布到您的网站 - >更新该表格。)

现在,无论何时加载您想要个性化的页面,都可以根据用户的偏好,即根据数据库中的新表格,将您选择的选项下载到客户端。

答案 1 :(得分:1)

要对select进行个性化设置,以便显示按“最常用”顺序排序的option列表,我们可以充分利用世界在你的愿望清单中。让我们使用jQuery和cookies创建一个。而且,制作一个可以使用的可重复使用的解决方案。具有额外的优势,您可以根据自己的喜好进行修改。

在我们这样做之前,请注意一点。如果您希望个性化很多东西,那么最好是在服务器端执行并在应用程序中创建个性化子系统。对于此类方案,不建议依赖客户端cookie。但是,如果您的用例只是像这样的一次性场景,您只需要通过提供超出工作功能集的额外增强功能来增强用户体验,而无需更改服务器端代码,那么在客户端实现这样的功能是完全合理的。这正是为什么cookie和localstorage存在的原因。就像广告客户使用跟踪Cookie一样,这也像跟踪Cookie一样,可以更频繁地跟踪用户的使用情况。不是吗?

那就是说,让我们创建一个你可以按原样使用的jQuery插件。它还允许您将其应用于多个select。我们称之为.mfu()

注意 :这里的代码只是一个粗略的演示。它没有经过优化,可能需要重新分解。目前,如果您没有为所有id提供唯一的select,则此插件将失败,因为它依赖于id来附加和检索频率。

您可以在此处查看完整演示:http://jsfiddle.net/abhitalks/u5z868d0/

select中选择一个选项,然后在小提琴中单击“ run ”。您将看到最常用的选项一直保持最佳状态。


我们将从一个空白的插件模板开始,如下所示:

(function ($) {
    $.fn.extend({   
        mfu: function () { 
            ....
            return this.each(function () { 
                ...
            });
        }
    }); 
})(jQuery);

我们遍历调用该插件的每个select,然后返回所有这些链接进行链接。

然后,您可以在所有选择上调用此插件,如下所示:

$(select).mfu();

我们将option详细信息与对象数组中的频率一起存储在调用插件的选择器中指定的所有select。对象数组如下所示:

[
    {
        'id': 'drop1', 
        'mfu': 
            [
                { 'value': 'a', 'caption': 'Red', 'frequency': 0 },
                { 'value': 'b', 'caption': 'Green', 'frequency': 0 },
                ...
            ]
    }, 
    {
        'id': 'drop2', 
        'mfu': 
            [
                { 'value': '1', 'caption': 'One', 'frequency': 0 },
                { 'value': '2', 'caption': 'Two', 'frequency': 0 },
                ...
            ]
    }
];

现在,让我们开始编写插件。首先要做的是初始化一些东西。我们会在每个option中存储每个{{1>}的“频率”,以用于Cookie中的“最常用”项目。因此,我们的初始化代码将包含在初始化时读取cookie的代码,并加载对象数组中的“最常用”项。我们还需要回写cookie,所以让我们创建一个函数来自己完成。因为,我们将使用对象数组,我们将使用JSON将select写入cookie,并将stringify()写入。

所以,我们的插件现在看起来像这样:

parse()

我们已将Cookie名称硬编码为“ mfu ”。我们还为cookie设置了一个远期到期日。在现实代码中,您必须考虑动态设置它。然后是cookie的例行读/写功能。我们读取cookie并将MFU列表加载到变量(function ($) { $.fn.extend({ mfu: function () { var self = this, cookieName = 'mfu', defaultExpiry = new Date(2050, 1, 1), getCookie = function(name) { var results = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); return results ? unescape(results[2]) : null; }, setCookie = function(name, value) { var cookieString = name + "=" + escape(JSON.stringify(value)); cookieString += "; expires=" + defaultExpiry.toGMTString(); document.cookie = cookieString; }, mfuStored = getCookie(cookieName), mfuList = JSON.parse(mfuStored) ; return self.each(function () { ... }); } }); })(jQuery); 中,这是一个对象数组。

接下来,我们遍历调用插件的每个mfuList,然后在我们的对象数组中搜索每个select的{​​{1}}。如果没有找到,这意味着它已经第一次运行(和/或cookie不可用),在这种情况下我们创建新对象来保存频率。如果找到,我们会在id中找到select,然后检查频率是否在cookie-read-load上可用。如果未找到,我们会创建新对象以保存option详细信息。

完成后,我们会为当前select排序对象数组,然后按排序顺序替换option select。如果需要,我们还可以向用户显示频率。

现在,剩下的就是绑定每个select上的option事件,以更新对象数组中所选change的频率,并将其保存回cookie中。在此演示中,我们将其保存在select事件中。在现实生活中,您可以在页面卸载时保存cookie。

所以,现在我们的完整插件看起来像这样:

option

这就是它的全部。现在,您可以根据需要进一步改进和改进此代码,否则可以按原样使用。

答案 2 :(得分:0)

我已经对此做了一些小POC,你有数据用户点击了这个POC可能会为你使用的选项吗?

HTML code:

<select id="selectbox">
    <option data-sort="9">option 1</option>
    <option data-sort="8">option 2</option>
    <option data-sort="1">option 3</option>
    <option data-sort="3">option 4</option>
    <option data-sort="4">option 5</option>
    <option data-sort="5">option 6</option>
    <option data-sort="6">option 7</option>
    <option data-sort="1">option 8</option>
    <option data-sort="1">option 9</option>
    <option data-sort="3">option 10</option>
    <option data-sort="4">option 11</option>
    <option data-sort="7">option 12</option>
    <option data-sort="8">option 13</option>
    <option data-sort="2">option 14</option>
    <option data-sort="1">option 15</option>
    <option data-sort="4">option 16</option>
</select>

JQuery代码:

function srt(on,descending) {
         on = on && on.constructor === Object ? on : {};
         return function(a,b){
           if (on.string || on.key) {
             a = on.key ? a[on.key] : a;
             a = on.string ? String(a).toLowerCase() : a;
             b = on.key ? b[on.key] : b;
             b = on.string ? String(b).toLowerCase() : b;
             // if key is not present, move to the end 
             if (on.key && (!b || !a)) {
              return !a && !b ? 1 : !a ? 1 : -1;
             }
           }
           return descending ? ~~(on.string ? b.localeCompare(a) : a < b)
                             : ~~(on.string ? a.localeCompare(b) : a > b);
          };
        }
        var boxarray=[];
        $("#selectbox").click(function(){
            boxarray=[];
            $("#selectbox option").each(function(){
                var cValue = $(this).val();
                var Cattr = $(this).attr("data-sort");
                var newObj = {"sort":Cattr,"value":cValue};
                boxarray.push(newObj);
            });
            boxarray.sort(srt({key:'sort',string:true},true));
            console.log(boxarray);
            var optionsString = "";
            for(i=0;i<boxarray.length;i++){
              optionsString+= '<option data-sort="'+boxarray[i].sort+'">'+boxarray[i].value+'</option>';
            }
            console.log(optionsString);
            document.getElementById("selectbox").innerHTML = "";
            document.getElementById("selectbox").innerHTML = optionsString; 
        });

代码笔网址: http://codepen.io/naveenkumarpg/pen/emBdgV/

希望这可以帮助你。

答案 3 :(得分:0)

正如其他人所说,如果完成服务器端会更好,特别是因为用户可以禁用javascript。

但是,这个例子假设选择已经填充,并且根据需要重建选择列表(demo):

var indx,
    xref = {},
    newHtml = '',
    $select = $('select'),
    opts = $select.find('option')
    // build array of options & count repeats
    .map(function () {
        var v = this.value;
        if (xref[v]) {
            xref[v]++
        } else {
            xref[v] = 1;
        }
        return v;
    })
    // sort options by adding "0" or "1" in front 
    // to perform a weighted sort so duplicates get sorted first
    .sort(function(a, b){
        var x = xref[a] > 1 ? '0' + a : '1' + a,
            y = xref[b] > 1 ? '0' + b : '1' + b;
        return x === y ? 0 : x > y ? 1 : -1;
    }),
    // return unique array values
    arr = $.grep(opts, function (v, k) {
        return $.inArray(v, opts) === k;
    });

// replace current options with new list
for (indx = 0; indx < arr.length; indx++) {
    newHtml += '<option value="' + arr[indx] + '">' + arr[indx] + '</option>';
}
$select.html(newHtml);