【发布时间】:2014-10-06 17:41:14
【问题描述】:
我正在使用来自网页中元素的 data-* 属性的关键字填充自动完成下拉列表的 datalist 元素,并且在对它们进行排序和删除重复项时,我希望保留以大写开头的关键字而不是小写关键字。
我用于获取唯一关键字的代码也可能会使用一些优化来提高效率,尽管在 Web Worker 中运行它意味着这不是优先事项。
我尝试了使用 caseFirst:upper 选项的 localeCompare 技巧,但没有成功(或者如果重复删除代码更智能,也许可以)
TL;DR 我希望大写的 Foo/Bar/Baz 出现在自动完成下拉列表中,而不是 foo/bar/baz
<!DOCTYPE HTML><html lang="en"><head><meta charset="utf-8">
<title>Populate Autocomplete</title>
<script type="text/javascript">
function acEntries(dl,kwlist) {
var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"}),
worker = new Worker(window.URL.createObjectURL(blob));
Array.prototype.slice.call(document.querySelectorAll("dd[data-"+dl.toLowerCase()+"]")).forEach(function(g){
var ds = g.dataset.fooTopics;
if(!ds)return; /* Ensure there is a data- attribute of CSV keywords to include in the kwlist array */
kwlist = kwlist.concat(ds.split(","));
})
worker.postMessage(kwlist); /* Asynchronously remove duplicate keywords and sort */
worker.onmessage = function (ev) {
var d = document.getElementById(dl),t = d.firstChild.content,v = ev.data,
observer = new MutationObserver(function(mo) {
t.firstChild.setAttribute("value",v.shift());
if(v.length<1){observer.disconnect()}
requestAnimationFrame(function(){d.appendChild(t.cloneNode(true))}); /* add the next keyword to datalist */
}),
config = {childList:true};
t.firstChild.setAttribute("value",v.shift());
observer.observe(d,config); /* watch for keywords being added to datalist */
d.appendChild(t.cloneNode(true)); /* add the first keyword to the datalist */
worker.terminate();
}
}
</script></head><body onload="acEntries('Foo-topics',[])">
<dl><dt></dt>
<dd data-foo-topics="Foo,bar,Baz">Foobar Baz</dd>
<dd data-foo-topics="Floo,Bar,Blaz">Floobar Blaz</dd>
<dd data-foo-topics="foo,Blah,baz">Fooblah Baz</dd>
</dl>
<input type="search" list="Foo-topics" placeholder="Foo-topics" autocomplete="off" aria-autocomplete="list">
<datalist id="Foo-topics"><template><option></template></datalist>
<script type="text/js-worker">
self.addEventListener('message', msgRcvd);
function msgRcvd(er) {
var arr = er.data.sort(function(a, b) {
return a.localeCompare(b, {sensitivity:'base',caseFirst:'upper'});
}),
len = arr.length, nw = (len >= 1 ? [arr[0]] : []);
for(var i = 1; i < len; i++) {
if(nw[nw.length -1].toLowerCase() != arr[i].toLowerCase()) {
nw.push(arr[i]);
}
}
self.postMessage(nw);
}
</script></body></html>
【问题讨论】:
标签: javascript arrays sorting web-worker case-insensitive