自动完成文本中间的部分

huangapple go评论74阅读模式
英文:

Autocomplete in the Middle of text

问题

我想要一个自动完成列表,它也可以在文本中间工作。我正在使用来自W3Schools的自动完成功能。

例如,自动完成的项目是:马拉维,马来西亚,墨西哥。我的目标是,即使我在输入框中键入“exi”,也能显示墨西哥。现在,我必须键入第一个M才能考虑墨西哥。

关于这个问题有很多使用jQuery的主题,但我希望使用纯JavaScript实现这个功能。

function autocomplete(inp, arr) {
  /*自动完成函数接受两个参数,
  文本字段元素和可能自动完成的值数组:*/
  var currentFocus;
  /*当有人在文本字段中输入时执行一个函数:*/
  inp.addEventListener("input", function(e) {
    var a, b, i, val = this.value;
    /*关闭任何已经打开的自动完成值列表*/
    closeAllLists();
    if (!val) {
      return false;
    }
    currentFocus = -1;
    /*创建一个包含项目(值)的DIV元素:*/
    a = document.createElement("DIV");
    a.setAttribute("id", this.id + "autocomplete-list");
    a.setAttribute("class", "autocomplete-items");
    /*将DIV元素附加为自动完成容器的子元素:*/
    this.parentNode.appendChild(a);
    /*对于数组中的每个项目...*/
    for (i = 0; i < arr.length; i++) {
      /*检查项目是否以与文本字段值相同的字母开头:*/
      if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
        /*为每个匹配的元素创建一个DIV元素:*/
        b = document.createElement("DIV");
        /*使匹配的字母加粗:*/
        b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
        b.innerHTML += arr[i].substr(val.length);
        /*插入一个输入字段,该字段将保存当前数组项的值:*/
        b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
        /*当有人点击项目值(DIV元素)时执行一个函数:*/
        b.addEventListener("click", function(e) {
          /*将值插入自动完成文本字段:*/
          inp.value = this.getElementsByTagName("input")[0].value;
          /*关闭自动完成值列表,
          (或任何其他已打开的自动完成值列表):*/
          closeAllLists();
        });
        a.appendChild(b);
      }
    }
  });
  /*在键盘上按键时执行一个函数:*/
  inp.addEventListener("keydown", function(e) {
    var x = document.getElementById(this.id + "autocomplete-list");
    if (x) x = x.getElementsByTagName("div");
    if (e.keyCode == 40) {
      /*如果按下箭头DOWN键,
      增加currentFocus变量:*/
      currentFocus++;
      /*并使当前项目更可见:*/
      addActive(x);
    } else if (e.keyCode == 38) { //上
      /*如果按下箭头UP键,
      减少currentFocus变量:*/
      currentFocus--;
      /*并使当前项目更可见:*/
      addActive(x);
    } else if (e.keyCode == 13) {
      /*如果按下回车键,阻止表单提交,*/
      e.preventDefault();
      if (currentFocus > -1) {
        /*并模拟对“active”项目的点击:*/
        if (x) x[currentFocus].click();
      }
    }
  });

  function addActive(x) {
    /*一个将项目分类为“active”的函数:*/
    if (!x) return false;
    /*首先删除所有项目上的“active”类:*/
    removeActive(x);
    if (currentFocus >= x.length) currentFocus = 0;
    if (currentFocus < 0) currentFocus = (x.length - 1);
    /*添加类“autocomplete-active”:*/
    x[currentFocus].classList.add("autocomplete-active");
  }

  function removeActive(x) {
    /*一个从所有自动完成项目中删除“active”类的函数:*/
    for (var i = 0; i < x.length; i++) {
      x[i].classList.remove("autocomplete-active");
    }
  }

  function closeAllLists(elmnt) {
    /*关闭文档中的所有自动完成列表,
    除了作为参数传递的一个:*/
    var x = document.getElementsByClassName("autocomplete-items");
    for (var i = 0; i < x.length; i++) {
      if (elmnt != x[i] && elmnt != inp) {
        x[i].parentNode.removeChild(x[i]);
      }
    }
  }
  /*当有人点击文档时执行一个函数:*/
  document.addEventListener("click", function(e) {
    closeAllLists(e.target);
  });
}

/*包含世界上所有国家名称的数组:*/
var countries = ["阿富汗", "阿尔巴尼亚", "阿尔及利亚", "安道尔", "安哥拉", "安圭拉", "安提瓜和巴布达", "阿根廷", "亚美尼亚", "阿鲁巴", "澳大利亚", "奥地利", "阿塞拜疆", "巴哈马", "巴林", "孟加拉国", "巴巴多斯", "白俄罗斯", "比利时", "伯利兹", "贝宁", "百慕大", "不丹", "玻利维亚", "波斯尼亚和黑塞哥维那", "博茨瓦纳", "巴西", "英属维尔京群岛", "文莱", "保加利亚", "布基纳法索", "布隆迪", "柬埔寨", "喀麦隆", "加拿大", "佛得角", "开曼群岛", "中非共和国", "乍得", "智利", "中国", "哥伦比亚", "刚果", "库克群岛", "哥斯达黎加", "科特

<details>
<summary>英文:</summary>

I would like to have autocomplete list which works also in the middle of the text. I am using Autocomplete from W3Schools. 

For example autocomplete items are: *Malawi, Malaysia, Mexico*. My goal is to have diplayed Mexico, even when I type &quot;exi&quot; into the input. Now I have to type the first M to even get Mexico into account.

There are plenty of topics about this with jQuery, but I would like to have that ability with vanilla JavaScript.


&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;

&lt;!-- language: lang-js --&gt;

    function autocomplete(inp, arr) {
      /*the autocomplete function takes two arguments,
      the text field element and an array of possible autocompleted values:*/
      var currentFocus;
      /*execute a function when someone writes in the text field:*/
      inp.addEventListener(&quot;input&quot;, function(e) {
        var a, b, i, val = this.value;
        /*close any already open lists of autocompleted values*/
        closeAllLists();
        if (!val) {
          return false;
        }
        currentFocus = -1;
        /*create a DIV element that will contain the items (values):*/
        a = document.createElement(&quot;DIV&quot;);
        a.setAttribute(&quot;id&quot;, this.id + &quot;autocomplete-list&quot;);
        a.setAttribute(&quot;class&quot;, &quot;autocomplete-items&quot;);
        /*append the DIV element as a child of the autocomplete container:*/
        this.parentNode.appendChild(a);
        /*for each item in the array...*/
        for (i = 0; i &lt; arr.length; i++) {
          /*check if the item starts with the same letters as the text field value:*/
          if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
            /*create a DIV element for each matching element:*/
            b = document.createElement(&quot;DIV&quot;);
            /*make the matching letters bold:*/
            b.innerHTML = &quot;&lt;strong&gt;&quot; + arr[i].substr(0, val.length) + &quot;&lt;/strong&gt;&quot;;
            b.innerHTML += arr[i].substr(val.length);
            /*insert a input field that will hold the current array item&#39;s value:*/
            b.innerHTML += &quot;&lt;input type=&#39;hidden&#39; value=&#39;&quot; + arr[i] + &quot;&#39;&gt;&quot;;
            /*execute a function when someone clicks on the item value (DIV element):*/
            b.addEventListener(&quot;click&quot;, function(e) {
              /*insert the value for the autocomplete text field:*/
              inp.value = this.getElementsByTagName(&quot;input&quot;)[0].value;
              /*close the list of autocompleted values,
              (or any other open lists of autocompleted values:*/
              closeAllLists();
            });
            a.appendChild(b);
          }
        }
      });
      /*execute a function presses a key on the keyboard:*/
      inp.addEventListener(&quot;keydown&quot;, function(e) {
        var x = document.getElementById(this.id + &quot;autocomplete-list&quot;);
        if (x) x = x.getElementsByTagName(&quot;div&quot;);
        if (e.keyCode == 40) {
          /*If the arrow DOWN key is pressed,
          increase the currentFocus variable:*/
          currentFocus++;
          /*and and make the current item more visible:*/
          addActive(x);
        } else if (e.keyCode == 38) { //up
          /*If the arrow UP key is pressed,
          decrease the currentFocus variable:*/
          currentFocus--;
          /*and and make the current item more visible:*/
          addActive(x);
        } else if (e.keyCode == 13) {
          /*If the ENTER key is pressed, prevent the form from being submitted,*/
          e.preventDefault();
          if (currentFocus &gt; -1) {
            /*and simulate a click on the &quot;active&quot; item:*/
            if (x) x[currentFocus].click();
          }
        }
      });

      function addActive(x) {
        /*a function to classify an item as &quot;active&quot;:*/
        if (!x) return false;
        /*start by removing the &quot;active&quot; class on all items:*/
        removeActive(x);
        if (currentFocus &gt;= x.length) currentFocus = 0;
        if (currentFocus &lt; 0) currentFocus = (x.length - 1);
        /*add class &quot;autocomplete-active&quot;:*/
        x[currentFocus].classList.add(&quot;autocomplete-active&quot;);
      }

      function removeActive(x) {
        /*a function to remove the &quot;active&quot; class from all autocomplete items:*/
        for (var i = 0; i &lt; x.length; i++) {
          x[i].classList.remove(&quot;autocomplete-active&quot;);
        }
      }

      function closeAllLists(elmnt) {
        /*close all autocomplete lists in the document,
        except the one passed as an argument:*/
        var x = document.getElementsByClassName(&quot;autocomplete-items&quot;);
        for (var i = 0; i &lt; x.length; i++) {
          if (elmnt != x[i] &amp;&amp; elmnt != inp) {
            x[i].parentNode.removeChild(x[i]);
          }
        }
      }
      /*execute a function when someone clicks in the document:*/
      document.addEventListener(&quot;click&quot;, function(e) {
        closeAllLists(e.target);
      });
    }

    /*An array containing all the country names in the world:*/
    var countries = [&quot;Afghanistan&quot;, &quot;Albania&quot;, &quot;Algeria&quot;, &quot;Andorra&quot;, &quot;Angola&quot;, &quot;Anguilla&quot;, &quot;Antigua &amp; Barbuda&quot;, &quot;Argentina&quot;, &quot;Armenia&quot;, &quot;Aruba&quot;, &quot;Australia&quot;, &quot;Austria&quot;, &quot;Azerbaijan&quot;, &quot;Bahamas&quot;, &quot;Bahrain&quot;, &quot;Bangladesh&quot;, &quot;Barbados&quot;, &quot;Belarus&quot;, &quot;Belgium&quot;, &quot;Belize&quot;, &quot;Benin&quot;, &quot;Bermuda&quot;, &quot;Bhutan&quot;, &quot;Bolivia&quot;, &quot;Bosnia &amp; Herzegovina&quot;, &quot;Botswana&quot;, &quot;Brazil&quot;, &quot;British Virgin Islands&quot;, &quot;Brunei&quot;, &quot;Bulgaria&quot;, &quot;Burkina Faso&quot;, &quot;Burundi&quot;, &quot;Cambodia&quot;, &quot;Cameroon&quot;, &quot;Canada&quot;, &quot;Cape Verde&quot;, &quot;Cayman Islands&quot;, &quot;Central Arfrican Republic&quot;, &quot;Chad&quot;, &quot;Chile&quot;, &quot;China&quot;, &quot;Colombia&quot;, &quot;Congo&quot;, &quot;Cook Islands&quot;, &quot;Costa Rica&quot;, &quot;Cote D Ivoire&quot;, &quot;Croatia&quot;, &quot;Cuba&quot;, &quot;Curacao&quot;, &quot;Cyprus&quot;, &quot;Czech Republic&quot;, &quot;Denmark&quot;, &quot;Djibouti&quot;, &quot;Dominica&quot;, &quot;Dominican Republic&quot;, &quot;Ecuador&quot;, &quot;Egypt&quot;, &quot;El Salvador&quot;, &quot;Equatorial Guinea&quot;, &quot;Eritrea&quot;, &quot;Estonia&quot;, &quot;Ethiopia&quot;, &quot;Falkland Islands&quot;, &quot;Faroe Islands&quot;, &quot;Fiji&quot;, &quot;Finland&quot;, &quot;France&quot;, &quot;French Polynesia&quot;, &quot;French West Indies&quot;, &quot;Gabon&quot;, &quot;Gambia&quot;, &quot;Georgia&quot;, &quot;Germany&quot;, &quot;Ghana&quot;, &quot;Gibraltar&quot;, &quot;Greece&quot;, &quot;Greenland&quot;, &quot;Grenada&quot;, &quot;Guam&quot;, &quot;Guatemala&quot;, &quot;Guernsey&quot;, &quot;Guinea&quot;, &quot;Guinea Bissau&quot;, &quot;Guyana&quot;, &quot;Haiti&quot;, &quot;Honduras&quot;, &quot;Hong Kong&quot;, &quot;Hungary&quot;, &quot;Iceland&quot;, &quot;India&quot;, &quot;Indonesia&quot;, &quot;Iran&quot;, &quot;Iraq&quot;, &quot;Ireland&quot;, &quot;Isle of Man&quot;, &quot;Israel&quot;, &quot;Italy&quot;, &quot;Jamaica&quot;, &quot;Japan&quot;, &quot;Jersey&quot;, &quot;Jordan&quot;, &quot;Kazakhstan&quot;, &quot;Kenya&quot;, &quot;Kiribati&quot;, &quot;Kosovo&quot;, &quot;Kuwait&quot;, &quot;Kyrgyzstan&quot;, &quot;Laos&quot;, &quot;Latvia&quot;, &quot;Lebanon&quot;, &quot;Lesotho&quot;, &quot;Liberia&quot;, &quot;Libya&quot;, &quot;Liechtenstein&quot;, &quot;Lithuania&quot;, &quot;Luxembourg&quot;, &quot;Macau&quot;, &quot;Macedonia&quot;, &quot;Madagascar&quot;, &quot;Malawi&quot;, &quot;Malaysia&quot;, &quot;Maldives&quot;, &quot;Mali&quot;, &quot;Malta&quot;, &quot;Marshall Islands&quot;, &quot;Mauritania&quot;, &quot;Mauritius&quot;, &quot;Mexico&quot;, &quot;Micronesia&quot;, &quot;Moldova&quot;, &quot;Monaco&quot;, &quot;Mongolia&quot;, &quot;Montenegro&quot;, &quot;Montserrat&quot;, &quot;Morocco&quot;, &quot;Mozambique&quot;, &quot;Myanmar&quot;, &quot;Namibia&quot;, &quot;Nauro&quot;, &quot;Nepal&quot;, &quot;Netherlands&quot;, &quot;Netherlands Antilles&quot;, &quot;New Caledonia&quot;, &quot;New Zealand&quot;, &quot;Nicaragua&quot;, &quot;Niger&quot;, &quot;Nigeria&quot;, &quot;North Korea&quot;, &quot;Norway&quot;, &quot;Oman&quot;, &quot;Pakistan&quot;, &quot;Palau&quot;, &quot;Palestine&quot;, &quot;Panama&quot;, &quot;Papua New Guinea&quot;, &quot;Paraguay&quot;, &quot;Peru&quot;, &quot;Philippines&quot;, &quot;Poland&quot;, &quot;Portugal&quot;, &quot;Puerto Rico&quot;, &quot;Qatar&quot;, &quot;Reunion&quot;, &quot;Romania&quot;, &quot;Russia&quot;, &quot;Rwanda&quot;, &quot;Saint Pierre &amp; Miquelon&quot;, &quot;Samoa&quot;, &quot;San Marino&quot;, &quot;Sao Tome and Principe&quot;, &quot;Saudi Arabia&quot;, &quot;Senegal&quot;, &quot;Serbia&quot;, &quot;Seychelles&quot;, &quot;Sierra Leone&quot;, &quot;Singapore&quot;, &quot;Slovakia&quot;, &quot;Slovenia&quot;, &quot;Solomon Islands&quot;, &quot;Somalia&quot;, &quot;South Africa&quot;, &quot;South Korea&quot;, &quot;South Sudan&quot;, &quot;Spain&quot;, &quot;Sri Lanka&quot;, &quot;St Kitts &amp; Nevis&quot;, &quot;St Lucia&quot;, &quot;St Vincent&quot;, &quot;Sudan&quot;, &quot;Suriname&quot;, &quot;Swaziland&quot;, &quot;Sweden&quot;, &quot;Switzerland&quot;, &quot;Syria&quot;, &quot;Taiwan&quot;, &quot;Tajikistan&quot;, &quot;Tanzania&quot;, &quot;Thailand&quot;, &quot;Timor L&#39;Este&quot;, &quot;Togo&quot;, &quot;Tonga&quot;, &quot;Trinidad &amp; Tobago&quot;, &quot;Tunisia&quot;, &quot;Turkey&quot;, &quot;Turkmenistan&quot;, &quot;Turks &amp; Caicos&quot;, &quot;Tuvalu&quot;, &quot;Uganda&quot;, &quot;Ukraine&quot;, &quot;United Arab Emirates&quot;, &quot;United Kingdom&quot;, &quot;United States of America&quot;, &quot;Uruguay&quot;, &quot;Uzbekistan&quot;, &quot;Vanuatu&quot;, &quot;Vatican City&quot;, &quot;Venezuela&quot;, &quot;Vietnam&quot;, &quot;Virgin Islands (US)&quot;, &quot;Yemen&quot;, &quot;Zambia&quot;, &quot;Zimbabwe&quot;];

    /*initiate the autocomplete function on the &quot;myInput&quot; element, and pass along the countries array as possible autocomplete values:*/
    autocomplete(document.getElementById(&quot;myInput&quot;), countries);

&lt;!-- language: lang-html --&gt;

    &lt;!--Make sure the form has the autocomplete function switched off:--&gt;
    &lt;form autocomplete=&quot;off&quot; action=&quot;/action_page.php&quot;&gt;
      &lt;div class=&quot;autocomplete&quot; style=&quot;width:300px;&quot;&gt;
        &lt;input id=&quot;myInput&quot; type=&quot;text&quot; name=&quot;myCountry&quot; placeholder=&quot;Country&quot;&gt;
      &lt;/div&gt;
      &lt;input type=&quot;submit&quot;&gt;
    &lt;/form&gt;

&lt;!-- end snippet --&gt;



</details>


# 答案1
**得分**: 2

将以下代码行

```javascript
if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase())

更改为:

if (arr[i].toUpperCase().includes(val.toUpperCase()))
英文:

All you need to change the following:

if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase())

To:

if (arr[i].toUpperCase().includes(val.toUpperCase()))

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

function autocomplete(inp, arr) {
/*the autocomplete function takes two arguments,
the text field element and an array of possible autocompleted values:*/
var currentFocus;
/*execute a function when someone writes in the text field:*/
inp.addEventListener(&quot;input&quot;, function(e) {
var a, b, i, val = this.value;
/*close any already open lists of autocompleted values*/
closeAllLists();
if (!val) { return false;}
currentFocus = -1;
/*create a DIV element that will contain the items (values):*/
a = document.createElement(&quot;DIV&quot;);
a.setAttribute(&quot;id&quot;, this.id + &quot;autocomplete-list&quot;);
a.setAttribute(&quot;class&quot;, &quot;autocomplete-items&quot;);
/*append the DIV element as a child of the autocomplete container:*/
this.parentNode.appendChild(a);
/*for each item in the array...*/
for (i = 0; i &lt; arr.length; i++) {
/*check if the item starts with the same letters as the text field value:*/
if (arr[i].toUpperCase().includes(val.toUpperCase())) {
/*create a DIV element for each matching element:*/
b = document.createElement(&quot;DIV&quot;);
/*make the matching letters bold:*/
b.innerHTML = &quot;&lt;strong&gt;&quot; + arr[i].substr(0, val.length) + &quot;&lt;/strong&gt;&quot;;
b.innerHTML += arr[i].substr(val.length);
/*insert a input field that will hold the current array item&#39;s value:*/
b.innerHTML += &quot;&lt;input type=&#39;hidden&#39; value=&#39;&quot; + arr[i] + &quot;&#39;&gt;&quot;;
/*execute a function when someone clicks on the item value (DIV element):*/
b.addEventListener(&quot;click&quot;, function(e) {
/*insert the value for the autocomplete text field:*/
inp.value = this.getElementsByTagName(&quot;input&quot;)[0].value;
/*close the list of autocompleted values,
(or any other open lists of autocompleted values:*/
closeAllLists();
});
a.appendChild(b);
}
}
});
/*execute a function presses a key on the keyboard:*/
inp.addEventListener(&quot;keydown&quot;, function(e) {
var x = document.getElementById(this.id + &quot;autocomplete-list&quot;);
if (x) x = x.getElementsByTagName(&quot;div&quot;);
if (e.keyCode == 40) {
/*If the arrow DOWN key is pressed,
increase the currentFocus variable:*/
currentFocus++;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 38) { //up
/*If the arrow UP key is pressed,
decrease the currentFocus variable:*/
currentFocus--;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 13) {
/*If the ENTER key is pressed, prevent the form from being submitted,*/
e.preventDefault();
if (currentFocus &gt; -1) {
/*and simulate a click on the &quot;active&quot; item:*/
if (x) x[currentFocus].click();
}
}
});
function addActive(x) {
/*a function to classify an item as &quot;active&quot;:*/
if (!x) return false;
/*start by removing the &quot;active&quot; class on all items:*/
removeActive(x);
if (currentFocus &gt;= x.length) currentFocus = 0;
if (currentFocus &lt; 0) currentFocus = (x.length - 1);
/*add class &quot;autocomplete-active&quot;:*/
x[currentFocus].classList.add(&quot;autocomplete-active&quot;);
}
function removeActive(x) {
/*a function to remove the &quot;active&quot; class from all autocomplete items:*/
for (var i = 0; i &lt; x.length; i++) {
x[i].classList.remove(&quot;autocomplete-active&quot;);
}
}
function closeAllLists(elmnt) {
/*close all autocomplete lists in the document,
except the one passed as an argument:*/
var x = document.getElementsByClassName(&quot;autocomplete-items&quot;);
for (var i = 0; i &lt; x.length; i++) {
if (elmnt != x[i] &amp;&amp; elmnt != inp) {
x[i].parentNode.removeChild(x[i]);
}
}
}
/*execute a function when someone clicks in the document:*/
document.addEventListener(&quot;click&quot;, function (e) {
closeAllLists(e.target);
});
}
/*An array containing all the country names in the world:*/
var countries = [&quot;Afghanistan&quot;,&quot;Albania&quot;,&quot;Algeria&quot;,&quot;Andorra&quot;,&quot;Angola&quot;,&quot;Anguilla&quot;,&quot;Antigua &amp; Barbuda&quot;,&quot;Argentina&quot;,&quot;Armenia&quot;,&quot;Aruba&quot;,&quot;Australia&quot;,&quot;Austria&quot;,&quot;Azerbaijan&quot;,&quot;Bahamas&quot;,&quot;Bahrain&quot;,&quot;Bangladesh&quot;,&quot;Barbados&quot;,&quot;Belarus&quot;,&quot;Belgium&quot;,&quot;Belize&quot;,&quot;Benin&quot;,&quot;Bermuda&quot;,&quot;Bhutan&quot;,&quot;Bolivia&quot;,&quot;Bosnia &amp; Herzegovina&quot;,&quot;Botswana&quot;,&quot;Brazil&quot;,&quot;British Virgin Islands&quot;,&quot;Brunei&quot;,&quot;Bulgaria&quot;,&quot;Burkina Faso&quot;,&quot;Burundi&quot;,&quot;Cambodia&quot;,&quot;Cameroon&quot;,&quot;Canada&quot;,&quot;Cape Verde&quot;,&quot;Cayman Islands&quot;,&quot;Central Arfrican Republic&quot;,&quot;Chad&quot;,&quot;Chile&quot;,&quot;China&quot;,&quot;Colombia&quot;,&quot;Congo&quot;,&quot;Cook Islands&quot;,&quot;Costa Rica&quot;,&quot;Cote D Ivoire&quot;,&quot;Croatia&quot;,&quot;Cuba&quot;,&quot;Curacao&quot;,&quot;Cyprus&quot;,&quot;Czech Republic&quot;,&quot;Denmark&quot;,&quot;Djibouti&quot;,&quot;Dominica&quot;,&quot;Dominican Republic&quot;,&quot;Ecuador&quot;,&quot;Egypt&quot;,&quot;El Salvador&quot;,&quot;Equatorial Guinea&quot;,&quot;Eritrea&quot;,&quot;Estonia&quot;,&quot;Ethiopia&quot;,&quot;Falkland Islands&quot;,&quot;Faroe Islands&quot;,&quot;Fiji&quot;,&quot;Finland&quot;,&quot;France&quot;,&quot;French Polynesia&quot;,&quot;French West Indies&quot;,&quot;Gabon&quot;,&quot;Gambia&quot;,&quot;Georgia&quot;,&quot;Germany&quot;,&quot;Ghana&quot;,&quot;Gibraltar&quot;,&quot;Greece&quot;,&quot;Greenland&quot;,&quot;Grenada&quot;,&quot;Guam&quot;,&quot;Guatemala&quot;,&quot;Guernsey&quot;,&quot;Guinea&quot;,&quot;Guinea Bissau&quot;,&quot;Guyana&quot;,&quot;Haiti&quot;,&quot;Honduras&quot;,&quot;Hong Kong&quot;,&quot;Hungary&quot;,&quot;Iceland&quot;,&quot;India&quot;,&quot;Indonesia&quot;,&quot;Iran&quot;,&quot;Iraq&quot;,&quot;Ireland&quot;,&quot;Isle of Man&quot;,&quot;Israel&quot;,&quot;Italy&quot;,&quot;Jamaica&quot;,&quot;Japan&quot;,&quot;Jersey&quot;,&quot;Jordan&quot;,&quot;Kazakhstan&quot;,&quot;Kenya&quot;,&quot;Kiribati&quot;,&quot;Kosovo&quot;,&quot;Kuwait&quot;,&quot;Kyrgyzstan&quot;,&quot;Laos&quot;,&quot;Latvia&quot;,&quot;Lebanon&quot;,&quot;Lesotho&quot;,&quot;Liberia&quot;,&quot;Libya&quot;,&quot;Liechtenstein&quot;,&quot;Lithuania&quot;,&quot;Luxembourg&quot;,&quot;Macau&quot;,&quot;Macedonia&quot;,&quot;Madagascar&quot;,&quot;Malawi&quot;,&quot;Malaysia&quot;,&quot;Maldives&quot;,&quot;Mali&quot;,&quot;Malta&quot;,&quot;Marshall Islands&quot;,&quot;Mauritania&quot;,&quot;Mauritius&quot;,&quot;Mexico&quot;,&quot;Micronesia&quot;,&quot;Moldova&quot;,&quot;Monaco&quot;,&quot;Mongolia&quot;,&quot;Montenegro&quot;,&quot;Montserrat&quot;,&quot;Morocco&quot;,&quot;Mozambique&quot;,&quot;Myanmar&quot;,&quot;Namibia&quot;,&quot;Nauro&quot;,&quot;Nepal&quot;,&quot;Netherlands&quot;,&quot;Netherlands Antilles&quot;,&quot;New Caledonia&quot;,&quot;New Zealand&quot;,&quot;Nicaragua&quot;,&quot;Niger&quot;,&quot;Nigeria&quot;,&quot;North Korea&quot;,&quot;Norway&quot;,&quot;Oman&quot;,&quot;Pakistan&quot;,&quot;Palau&quot;,&quot;Palestine&quot;,&quot;Panama&quot;,&quot;Papua New Guinea&quot;,&quot;Paraguay&quot;,&quot;Peru&quot;,&quot;Philippines&quot;,&quot;Poland&quot;,&quot;Portugal&quot;,&quot;Puerto Rico&quot;,&quot;Qatar&quot;,&quot;Reunion&quot;,&quot;Romania&quot;,&quot;Russia&quot;,&quot;Rwanda&quot;,&quot;Saint Pierre &amp; Miquelon&quot;,&quot;Samoa&quot;,&quot;San Marino&quot;,&quot;Sao Tome and Principe&quot;,&quot;Saudi Arabia&quot;,&quot;Senegal&quot;,&quot;Serbia&quot;,&quot;Seychelles&quot;,&quot;Sierra Leone&quot;,&quot;Singapore&quot;,&quot;Slovakia&quot;,&quot;Slovenia&quot;,&quot;Solomon Islands&quot;,&quot;Somalia&quot;,&quot;South Africa&quot;,&quot;South Korea&quot;,&quot;South Sudan&quot;,&quot;Spain&quot;,&quot;Sri Lanka&quot;,&quot;St Kitts &amp; Nevis&quot;,&quot;St Lucia&quot;,&quot;St Vincent&quot;,&quot;Sudan&quot;,&quot;Suriname&quot;,&quot;Swaziland&quot;,&quot;Sweden&quot;,&quot;Switzerland&quot;,&quot;Syria&quot;,&quot;Taiwan&quot;,&quot;Tajikistan&quot;,&quot;Tanzania&quot;,&quot;Thailand&quot;,&quot;Timor L&#39;Este&quot;,&quot;Togo&quot;,&quot;Tonga&quot;,&quot;Trinidad &amp; Tobago&quot;,&quot;Tunisia&quot;,&quot;Turkey&quot;,&quot;Turkmenistan&quot;,&quot;Turks &amp; Caicos&quot;,&quot;Tuvalu&quot;,&quot;Uganda&quot;,&quot;Ukraine&quot;,&quot;United Arab Emirates&quot;,&quot;United Kingdom&quot;,&quot;United States of America&quot;,&quot;Uruguay&quot;,&quot;Uzbekistan&quot;,&quot;Vanuatu&quot;,&quot;Vatican City&quot;,&quot;Venezuela&quot;,&quot;Vietnam&quot;,&quot;Virgin Islands (US)&quot;,&quot;Yemen&quot;,&quot;Zambia&quot;,&quot;Zimbabwe&quot;];
/*initiate the autocomplete function on the &quot;myInput&quot; element, and pass along the countries array as possible autocomplete values:*/
autocomplete(document.getElementById(&quot;myInput&quot;), countries);

<!-- language: lang-html -->

&lt;h2&gt;Autocomplete&lt;/h2&gt;
&lt;p&gt;Start typing:&lt;/p&gt;
&lt;!--Make sure the form has the autocomplete function switched off:--&gt;
&lt;form autocomplete=&quot;off&quot; action=&quot;/action_page.php&quot;&gt;
&lt;div class=&quot;autocomplete&quot; style=&quot;width:300px;&quot;&gt;
&lt;input id=&quot;myInput&quot; type=&quot;text&quot; name=&quot;myCountry&quot; placeholder=&quot;Country&quot;&gt;
&lt;/div&gt;
&lt;input type=&quot;submit&quot;&gt;
&lt;/form&gt;

<!-- end snippet -->

答案2

得分: 1

以下是您要翻译的内容:

"Using filter and refactoring most of the W3Schools out of the code, saving 31 lines in the process.


const autocomplete = (inp, arr) => {
let currentFocus = -1;
const closeAllLists = (elmnt) => document.querySelectorAll(".autocomplete-items").forEach((x) => elmnt != x && elmnt !== inp && x.remove());
const removeActive = (x) => x.forEach((item) => item.classList.remove("autocomplete-active"));
const addActive = (x) => {
if (!x) return;
removeActive(x);
if (currentFocus >= x.length) currentFocus = 0;
if (currentFocus < 0) currentFocus = (x.length - 1);
x[currentFocus].classList.add("autocomplete-active");
};
inp.addEventListener("input", e => {
currentFocus = -1;
let val = inp.value.toUpperCase();
closeAllLists();
if (!val) return;
let autocompleteList = arr
.filter(item => item.toUpperCase().includes(val))
.map(item => <div><strong>${item.substr(0, val.length)}</strong>${item.substr(val.length)}<input type='hidden' value='${item}'></div>)
.join('');
const autocompleteDiv = <div id="${inp.id}autocomplete-list" class="autocomplete-items">${autocompleteList}</div>;
inp.closest("div.autocomplete").insertAdjacentHTML('beforeend', autocompleteDiv);
});

inp.addEventListener("keydown", e => {
console.log(e.key, e.keyCode, currentFocus)
let x = inp.nextElementSibling;
if (x) x = x.querySelectorAll("div");
if (e.key === 'Enter') {
e.preventDefault();
if (currentFocus > -1 && x) x[currentFocus].click();
return;
}
if (e.key === 'ArrowDown') currentFocus++;
else if (e.key === 'ArrowUp') currentFocus--;
addActive(x);
});

document.addEventListener("click", e => {
const tgt = e.target;
if (tgt.matches("#myInputautocomplete-list div")) {
inp.value = e.target.querySelector("input").value;
closeAllLists();
} else {
closeAllLists(tgt);
}
});
};

const countries = ["Afghanistan", "Albania", "Mexico", "Zimbabwe"];
autocomplete(document.getElementById("myInput"), countries);

  • {
    box-sizing: border-box;
    }

body {
font: 16px Arial;
}

/the container must be positioned relative:/

.autocomplete {
position: relative;
display: inline-block;
}

input {
border: 1px solid transparent;
background-color: #f1f1f1;
padding: 10px;
font-size: 16px;
}

input[type=text] {
background-color: #f1f1f1;
width: 100%;
}

input[type=submit] {
background-color: DodgerBlue;
color: #fff;
cursor: pointer;
}

.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/position the autocomplete items to be the same width as the container:/
top: 100%;
left: 0;
right: 0;
}

.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}

/when hovering an item:/

.autocomplete-items div:hover {
background-color: #e9e9e9;
}

/when navigating through the items using the arrow keys:/

.autocomplete-active {
background-color: DodgerBlue !important;
color: #ffffff;
}



"

英文:

Using filter and refactoring most of the W3Schools out of the code, saving 31 lines in the process.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const autocomplete = (inp, arr) =&gt; {
let currentFocus = -1;
const closeAllLists = (elmnt) =&gt; document.querySelectorAll(&quot;.autocomplete-items&quot;).forEach((x) =&gt; elmnt != x &amp;&amp; elmnt !== inp &amp;&amp; x.remove());
const removeActive = (x) =&gt; x.forEach((item) =&gt; item.classList.remove(&quot;autocomplete-active&quot;));
const addActive = (x) =&gt; {
if (!x) return;
removeActive(x);
if (currentFocus &gt;= x.length) currentFocus = 0;
if (currentFocus &lt; 0) currentFocus = (x.length - 1);
x[currentFocus].classList.add(&quot;autocomplete-active&quot;);
};
inp.addEventListener(&quot;input&quot;, e =&gt; {
currentFocus = -1;
let val = inp.value.toUpperCase();
closeAllLists();
if (!val) return;
let autocompleteList = arr
.filter(item =&gt; item.toUpperCase().includes(val))
.map(item =&gt; `&lt;div&gt;&lt;strong&gt;${item.substr(0, val.length)}&lt;/strong&gt;${item.substr(val.length)}&lt;input type=&#39;hidden&#39; value=&#39;${item}&#39;&gt;&lt;/div&gt;`)
.join(&#39;&#39;);
const autocompleteDiv = `&lt;div id=&quot;${inp.id}autocomplete-list&quot; class=&quot;autocomplete-items&quot;&gt;${autocompleteList}&lt;/div&gt;`;
inp.closest(&quot;div.autocomplete&quot;).insertAdjacentHTML(&#39;beforeend&#39;, autocompleteDiv);
});
inp.addEventListener(&quot;keydown&quot;, e =&gt; {
console.log(e.key, e.keyCode, currentFocus)
let x = inp.nextElementSibling;
if (x) x = x.querySelectorAll(&quot;div&quot;);
if (e.key === &#39;Enter&#39;) {
e.preventDefault();
if (currentFocus &gt; -1 &amp;&amp; x) x[currentFocus].click();
return;
}
if (e.key === &#39;ArrowDown&#39;) currentFocus++;
else if (e.key === &#39;ArrowUp&#39;) currentFocus--;
addActive(x);
});
document.addEventListener(&quot;click&quot;, e =&gt; {
const tgt = e.target;
if (tgt.matches(&quot;#myInputautocomplete-list div&quot;)) {
inp.value = e.target.querySelector(&quot;input&quot;).value;
closeAllLists();
} else {
closeAllLists(tgt);
}
});
};
const countries = [&quot;Afghanistan&quot;, &quot;Albania&quot;, &quot;Mexico&quot;, &quot;Zimbabwe&quot;];
autocomplete(document.getElementById(&quot;myInput&quot;), countries);

<!-- language: lang-css -->

* {
box-sizing: border-box;
}
body {
font: 16px Arial;
}
/*the container must be positioned relative:*/
.autocomplete {
position: relative;
display: inline-block;
}
input {
border: 1px solid transparent;
background-color: #f1f1f1;
padding: 10px;
font-size: 16px;
}
input[type=text] {
background-color: #f1f1f1;
width: 100%;
}
input[type=submit] {
background-color: DodgerBlue;
color: #fff;
cursor: pointer;
}
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/*position the autocomplete items to be the same width as the container:*/
top: 100%;
left: 0;
right: 0;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}
/*when hovering an item:*/
.autocomplete-items div:hover {
background-color: #e9e9e9;
}
/*when navigating through the items using the arrow keys:*/
.autocomplete-active {
background-color: DodgerBlue !important;
color: #ffffff;
}

<!-- language: lang-html -->

&lt;!--Make sure the form has the autocomplete function switched off:--&gt;
&lt;form autocomplete=&quot;off&quot; action=&quot;/action_page.php&quot;&gt;
&lt;div class=&quot;autocomplete&quot; style=&quot;width:300px;&quot;&gt;
&lt;input id=&quot;myInput&quot; type=&quot;text&quot; name=&quot;myCountry&quot; placeholder=&quot;Country&quot;&gt;
&lt;/div&gt;
&lt;input type=&quot;submit&quot;&gt;
&lt;/form&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年7月13日 13:58:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76676321.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定