我正在用网页中元素的data-*属性中的关键字填充自动完成下拉列表的数据列表元素,在对它们进行排序和删除重复项时,我更喜欢保留以大写开头的关键字而不是小写关键字。
我获取唯一关键字的代码可能也需要一些优化来提高效率,尽管在网络工作者中运行它意味着这不是优先事项。
我尝试了一个localeCompare技巧来处理caseFirst:上部选项,但这并没有起到作用(或者如果重复删除代码更聪明的话,也许可以)
TL;DR我希望大写的Foo/Bar/Baz位于自动完成下拉列表中,而不是Foo/Bar/Biz
<!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>
在http://htmlpad.org/ArrayComplete/edit
我在看《三个医生》,有人建议"简单地反转极性!"然后我突然想到了…
既然localeCompare排序总是先对数组进行小写排序,而不是从arr[0]开始并向前检查,然后将uniques推到nw[]的末尾,为什么不从末尾或arr[len]开始并向后检查,然后取消将unique斯推到nw]]的开头呢?
function msgRcvd(er) {
var arr = er.data.sort(function(a, b) {
return a.localeCompare(b, {sensitivity:'base'});
}),
len = arr.length, nw = (len >= 1 ? [arr[len - 1]] : []);
while(len--) {
if(nw[0].toLowerCase() != arr[len].toLowerCase()) {
nw.unshift(arr[len]);
}
}
self.postMessage(nw);
}
带有len的while循环,而不是带有i++的for循环
我颠倒了极性,完美的Whovian解决方案:)