javascript 什么是innerHTML加速网页的替代方案

qni6mghb  于 2022-12-25  发布在  Java
关注(0)|答案(1)|浏览(104)

我正在做一个项目,我为这个项目创建了一个自定义下拉国际国家代码选择部分,为此我使用innerHTML注入了所有SVG标志图标,我注意到在使用了240行innerHTML之后,我的网站的性能/加载速度受到了innerHTML的负面影响。

    • 请看我的JS代码-**

我也读了很多文章在互联网上,innerHTML是非常缓慢的,但我还没有找到任何替代innerHTML,你能请指导我一点我的JS代码,以提高我的应用程序的性能。

    • 注意:**我也怀疑SVG旗帜图标是我的应用加载缓慢的真正罪魁祸首吗?因为它包含239个SVG旗帜图标。也许这个SVG图标需要时间在我的网页上渲染。如果这是真正的罪魁祸首,你能指导我优化代码以加快加载速度吗?
// Autoclick on the parent div to hide the Dropdown after loading a page (Bug)
  window.addEventListener('load', () => {
      document.querySelector(".country-code-selector").click();
  });

  document.addEventListener('DOMContentLoaded', () => {

      const head = document.getElementsByTagName('head')[0];
      const link = document.createElement('link');
      link.rel = 'stylesheet';
      link.type = 'text/css';
      link.href = 'https://amitdutta.co.in/flag/css/flag-icon.css';
      head.appendChild(link);

      // Get dropdowns and form
      const dropdowns = document.querySelectorAll('[cc-data-dropdown]');
      const form = document.querySelector('.country-code-selector form');

      // Check if dropdowns exist on page
      if (dropdowns.length > 0) {
          // Loop through dropdowns and create custom dropdown for each select element
          dropdowns.forEach(dropdown => {
              createCustomDropdown(dropdown);
          });
      }

      // Check if form element exist on page
      if (form !== null) {
          // When form is submitted console log the value of the select field
          form.addEventListener('submit', (e) => {
              e.preventDefault();
              console.log('Selected country:', form.querySelector('[name="country"]').value);
          });
      }

      // Create custom dropdown
      function createCustomDropdown(dropdown) {
          // Get all options and convert them from nodelist to array
          const options = dropdown.querySelectorAll('option');
          const optionsArr = Array.prototype.slice.call(options);

          optionsArr[0].innerHTML = '<span class="flag-icon flag-icon-afg"></span> Afganistan (+69)';
          optionsArr[1].innerHTML = '<span class="flag-icon flag-icon-alb"></span> Albania (+355)';
          optionsArr[2].innerHTML = '<span class="flag-icon flag-icon-dza"></span> Algeria (+213)';
          optionsArr[3].innerHTML = '<span class="flag-icon flag-icon-asm"></span> American Samoa (+1-684)';
          optionsArr[4].innerHTML = '<span class="flag-icon flag-icon-and"></span> Andorra (+376)';
          optionsArr[5].innerHTML = '<span class="flag-icon flag-icon-ago"></span> Angola (+244)';
          optionsArr[6].innerHTML = '<span class="flag-icon flag-icon-aia"></span> Anguilla (+1-264)';
          optionsArr[7].innerHTML = '<span class="flag-icon flag-icon-ata"></span> Antarctica (+672)';
          optionsArr[8].innerHTML = '<span class="flag-icon flag-icon-atg"></span> Antigua and Barbuda (+1-268)';
          optionsArr[9].innerHTML = '<span class="flag-icon flag-icon-arg"></span> Argentina (+54)';
          optionsArr[10].innerHTML = '<span class="flag-icon flag-icon-arm"></span> Armenia (+374)';
          optionsArr[11].innerHTML = '<span class="flag-icon flag-icon-abw"></span> Aruba (+297)';
          optionsArr[12].innerHTML = '<span class="flag-icon flag-icon-aus"></span> Australia (+61)';
          optionsArr[13].innerHTML = '<span class="flag-icon flag-icon-aut"></span> Austria (+43)';
          optionsArr[14].innerHTML = '<span class="flag-icon flag-icon-aze"></span> Azerbaijan (+994)';
          optionsArr[15].innerHTML = '<span class="flag-icon flag-icon-bhs"></span> Bahamas (+1-242)';
          optionsArr[16].innerHTML = '<span class="flag-icon flag-icon-bhr"></span> Bahrain (+973)';
          optionsArr[17].innerHTML = '<span class="flag-icon flag-icon-bgd"></span> Bangladesh (+880)';
          optionsArr[18].innerHTML = '<span class="flag-icon flag-icon-brb"></span> Barbados (+1-246)';
          optionsArr[19].innerHTML = '<span class="flag-icon flag-icon-blr"></span> Belarus (+375)';
          optionsArr[20].innerHTML = '<span class="flag-icon flag-icon-bel"></span> Belgium (+32)';
          optionsArr[21].innerHTML = '<span class="flag-icon flag-icon-blz"></span> Belize (+501)';
          optionsArr[22].innerHTML = '<span class="flag-icon flag-icon-ben"></span> Benin (+229)';
          optionsArr[23].innerHTML = '<span class="flag-icon flag-icon-bmu"></span> Bermuda (+1-441)';
          optionsArr[24].innerHTML = '<span class="flag-icon flag-icon-btn"></span> Bhutan (+975)';
          optionsArr[25].innerHTML = '<span class="flag-icon flag-icon-bol"></span> Bolivia (+591)';
          optionsArr[26].innerHTML = '<span class="flag-icon flag-icon-bih"></span> Bosnia and Herzegovina (+387)';
          optionsArr[27].innerHTML = '<span class="flag-icon flag-icon-bwa"></span> Botswana (+267)';
          optionsArr[28].innerHTML = '<span class="flag-icon flag-icon-bra"></span> Brazil (+55)';
          optionsArr[29].innerHTML = '<span class="flag-icon flag-icon-iot"></span> British Indian Ocean Territory (+246)';
          optionsArr[30].innerHTML = '<span class="flag-icon flag-icon-vgb"></span> British Virgin Islands (+1-284)';
          optionsArr[31].innerHTML = '<span class="flag-icon flag-icon-brn"></span> Brunei (+673)';
          optionsArr[32].innerHTML = '<span class="flag-icon flag-icon-bgr"></span> Bulgaria (+359)';
          optionsArr[33].innerHTML = '<span class="flag-icon flag-icon-bfa"></span> Burkina Faso (+226)';
          optionsArr[34].innerHTML = '<span class="flag-icon flag-icon-bdi"></span> Burundi (+257)';
          optionsArr[35].innerHTML = '<span class="flag-icon flag-icon-khm"></span> Cambodia (+855)';
          optionsArr[36].innerHTML = '<span class="flag-icon flag-icon-cmr"></span> Cameroon (+237)';
          optionsArr[37].innerHTML = '<span class="flag-icon flag-icon-can"></span> Canada (+1)';
          optionsArr[38].innerHTML = '<span class="flag-icon flag-icon-cpv"></span> Cape Verde (+238)';
          optionsArr[39].innerHTML = '<span class="flag-icon flag-icon-cym"></span> Cayman Islands (+1-345)';
          optionsArr[40].innerHTML = '<span class="flag-icon flag-icon-caf"></span> Central African Republic (+236)';
          optionsArr[41].innerHTML = '<span class="flag-icon flag-icon-tcd"></span> Chad (+235)';
          optionsArr[42].innerHTML = '<span class="flag-icon flag-icon-chl"></span> Chile (+56)';
          optionsArr[43].innerHTML = '<span class="flag-icon flag-icon-chn"></span> China (+86)';
          optionsArr[44].innerHTML = '<span class="flag-icon flag-icon-cxr"></span> Christmas Island (+61)';
          optionsArr[45].innerHTML = '<span class="flag-icon flag-icon-cck"></span> Cocos Islands (+61)';
          optionsArr[46].innerHTML = '<span class="flag-icon flag-icon-col"></span> Colombia (+57)';
          optionsArr[47].innerHTML = '<span class="flag-icon flag-icon-com"></span> Comoros (+269)';
          optionsArr[48].innerHTML = '<span class="flag-icon flag-icon-cok"></span> Cook Islands (+682)';
          optionsArr[49].innerHTML = '<span class="flag-icon flag-icon-cri"></span> Costa Rica (+506)';
          optionsArr[50].innerHTML = '<span class="flag-icon flag-icon-hrv"></span> Croatia (+385)';
          optionsArr[51].innerHTML = '<span class="flag-icon flag-icon-cub"></span> Cuba (+53)';
          optionsArr[52].innerHTML = '<span class="flag-icon flag-icon-cuw"></span> Curacao (+599)';
          optionsArr[53].innerHTML = '<span class="flag-icon flag-icon-cyp"></span> Cyprus (+357)';
          optionsArr[54].innerHTML = '<span class="flag-icon flag-icon-cze"></span> Czech Republic (+420)';
          optionsArr[55].innerHTML = '<span class="flag-icon flag-icon-cod"></span> Democratic Republic of the Congo (+243)';
          optionsArr[56].innerHTML = '<span class="flag-icon flag-icon-dnk"></span> Denmark (+45)';
          optionsArr[57].innerHTML = '<span class="flag-icon flag-icon-dji"></span> Djibouti (+253)';
          optionsArr[58].innerHTML = '<span class="flag-icon flag-icon-dma"></span> Dominica (+1-767)';
          optionsArr[59].innerHTML = '<span class="flag-icon flag-icon-dom"></span> Dominican Republic (+1-809)';
          optionsArr[60].innerHTML = '<span class="flag-icon flag-icon-tls"></span> East Timor (+670)';
          optionsArr[61].innerHTML = '<span class="flag-icon flag-icon-ecu"></span> Ecuador (+593)';
          optionsArr[62].innerHTML = '<span class="flag-icon flag-icon-egy"></span> Egypt (+20)';
          optionsArr[63].innerHTML = '<span class="flag-icon flag-icon-slv"></span> El Salvador (+503)';
          optionsArr[64].innerHTML = '<span class="flag-icon flag-icon-gnq"></span> Equatorial Guinea (+240)';
          optionsArr[65].innerHTML = '<span class="flag-icon flag-icon-eri"></span> Eritrea (+291)';
          optionsArr[66].innerHTML = '<span class="flag-icon flag-icon-est"></span> Estonia (+372)';
          optionsArr[67].innerHTML = '<span class="flag-icon flag-icon-eth"></span> Ethiopia (+251)';
          optionsArr[68].innerHTML = '<span class="flag-icon flag-icon-flk"></span> Falkland Islands (+500)';
          optionsArr[69].innerHTML = '<span class="flag-icon flag-icon-fro"></span> Faroe Islands (+298)';
          optionsArr[70].innerHTML = '<span class="flag-icon flag-icon-fji"></span> Fiji (+679)';
          // More 169 Countries (Currently not added here) -
          optionsArr[71].innerHTML = 'No Data Found';

          // Create custom dropdown element and add class dropdown to it
          // Insert it in the DOM after the select field
          const customDropdown = document.createElement('div');
          customDropdown.classList.add('cc-dropdown');
          dropdown.insertAdjacentElement('afterend', customDropdown);

          // Create element for selected option
          // Add class to this element, text from the first option in select field and append it to custom dropdown
          const selected = document.createElement('div');
          selected.classList.add('cc-dropdown-selected');
          selected.innerHTML = 'Tel-Code';
          customDropdown.appendChild(selected);

          // Create element for dropdown menu, add class to it and append it to custom dropdown
          // Add click event to selected element to toggle dropdown menu
          const menu = document.createElement('div');
          menu.classList.add('cc-dropdown-menu');
          customDropdown.appendChild(menu);
          selected.addEventListener('click', toggleDropdown.bind(menu));

          // Create serach input element
          // Add class, type and placeholder to this element and append it to menu element
          const search = document.createElement('input');
          search.placeholder = 'Search Your Country...';
          search.type = 'text';
          search.classList.add('cc-dropdown-menu-search');
          menu.appendChild(search);

          // Create wrapper element for menu items, add class to it and append to menu element
          const menuItemsWrapper = document.createElement('div');
          menuItemsWrapper.classList.add('cc-dropdown-menu-items');
          menu.appendChild(menuItemsWrapper);

          // Loop through all options and create custom option for each option and append it to items wrapper element
          // Add click event for each custom option to set clicked option as selected option
          optionsArr.forEach(option => {
              const item = document.createElement('div');
              item.classList.add('cc-dropdown-menu-item');
              item.dataset.value = option.value;
              item.innerHTML = option.innerHTML;
              menuItemsWrapper.appendChild(item);

              item.addEventListener('click', setSelected.bind(item, selected, dropdown, menu));
          });

          // Add selected class to first custom option
          // menuItemsWrapper.querySelector('div').classList.add('selected');

          // Add input event to search input element to filter items
          // Add click event to document element to close custom dropdown if clicked outside of it
          // Hide original dropdown(select)
          search.addEventListener('input', filterItems.bind(search, optionsArr, menu));
          document.addEventListener('click', closeIfClickedOutside.bind(customDropdown, menu));
          dropdown.style.display = 'none';

      }

      // Toggle dropdown
      function toggleDropdown() {
          // Check if dropdown is opened and if it is close it, otherwise open it and focus search input

          if (this.offsetParent !== null) {
              this.style.display = 'none';
          } else {
              this.style.display = 'block';
              this.querySelector('input').focus();
          }
      }

      // Set selected option
      function setSelected(selected, dropdown, menu) {
          // Get value and label from clicked custom option
          const value = this.dataset.value;
          const label = this.innerHTML;

          // Change the text on selected element
          // Change the value on select field  

          filterDate = /(<span\b[^<>]*><\/span>\s*)\w+(?:\s+\w+)*\s*\((\+[\d-]+)\)/g;
          selected.innerHTML = label.replace(filterDate, `$1$2`);
          dropdown.value = value;

          // Close the menu
          // Reset search input value
          // Remove selected class from previously selected option and show all divs if they were filtered
          // Add selected class to clicked option
          menu.style.display = 'none';
          menu.querySelector('input').value = '';
          menu.querySelectorAll('div').forEach(div => {
              if (div.classList.contains('selected')) {
                  div.classList.remove('selected');
              }
              if (div.offsetParent === null) {
                  div.style.display = 'block';
              }
          });
          this.classList.add('selected');
      }

      // Filter items
      function filterItems(itemsArr, menu) {
          // Get all custom options
          // Get the value of search input and convert it to all lowercase characters
          // Get filtered items
          // Get the indexes of filtered items
          const customOptions = menu.querySelectorAll('.cc-dropdown-menu-items div');
          const value = this.value.toLowerCase();
          const filteredItems = itemsArr.filter(item => item.value.toLowerCase().includes(value));
          const indexesArr = filteredItems.map(item => itemsArr.indexOf(item));

          // Check if option is not inside indexes array and hide it and if it is inside indexes array and it is hidden show it

          var options = itemsArr.length;
          itemsArr.forEach(option => {
              if (!indexesArr.includes(itemsArr.indexOf(option))) {
                  customOptions[itemsArr.indexOf(option)].style.display = 'none';
                  options -= 1;
                  if (options <= 0) {
                      customOptions[itemsArr.length - 1].style.display = 'block';
                  }
              } else {
                  if (customOptions[itemsArr.indexOf(option)].offsetParent === null) {
                      customOptions[itemsArr.indexOf(option)].style.display = 'block';
                  }
              }
          });
      }

      // Close dropdown if clicked outside dropdown element
      function closeIfClickedOutside(menu, e) {
          if (e.target.closest('.cc-dropdown') === null && e.target !== this && menu.offsetParent !== null) {
              menu.style.display = 'none';
          }
      }

  });
.cc-dropdown-menu-items::-webkit-scrollbar-track {
     background-color: #323757;
     width: 2px;
}
 .cc-dropdown-menu-items::-webkit-scrollbar {
     background-color: #323757;
     width: 14px;
}
 .cc-dropdown-menu-items::-webkit-scrollbar-thumb {
     background-color: #e8576f;
     border: 4px solid #323757;
     z-index: -1;
     width: 2px;
     min-height: 50px;
}
 #phone-number {
     width: calc(100% - 120px);
     margin-left: 120px;
}
 .frm div:nth-child(3) .inputBox .tx {
     margin-left: 120px;
}
 .frm div:nth-child(3) .inputBox {
     display: flex;
}
 .frm div:nth-child(3) .inputBox .ln {
     margin-left: 120px;
     width: calc(100% - 120px);
}
 .cc-dropdown {
     position: relative;
}
 .cc-dropdown-selected {
     display: flex;
     align-items: center;
     justify-content: center;
     width: 116px;
     height: 40px;
     padding: 0 20px 0 10px;
     position: relative;
     cursor: pointer;
     transition: box-shadow .3s ease;
     background-color: #323757;
     border-radius: 3px;
     font-size: 15px;
     color: #fff;
}
 .cc-dropdown-selected::after {
     top: calc(50% - 2px);
     right: 10px;
     border: solid transparent;
     content: '';
     height: 0;
     width: 0;
     position: absolute;
     border-top-color:#000;
     border-width: 4px;
     margin-left: -4px;
}
 .cc-dropdown-selected:hover {
     box-shadow: 0 0 5px rgba(0,0,0,0.1);
}
 .cc-dropdown-menu {
     position: absolute;
     top: 100%;
     left: 0;
     width: 273px;
     border: 3px solid #323757;
     margin-right: -2px;
     border-top: 0;
     background-color: #fff;
     z-index: +9;
     margin-top: 10px;
}
 .cc-dropdown-menu-items {
     max-height: 200px;
     width: 270px;
     overflow-y: auto;
     overflow-x: hidden;
     z-index: +9;
}
 .cc-dropdown-menu-search {
     display: block;
     width: 270px;
     border: 0;
     border-right: 3px solid #323757;
     padding: 14px 0px 14px 10px;
     font-size: 15px;
     font-weight: 550;
     color: #fff;
     outline: 0;
     background-color: #323757;
}
 .cc-dropdown-menu-search::placeholder {
     color: rgb(214, 214, 214)!important;
}
 .cc-dropdown-menu-item {
     width: 267px;
     border-bottom: 1px solid #323757a6;
     font-size: 14px;
     font-weight: 550;
     cursor: pointer;
     z-index: +9;
     user-select: none;
     padding: 10px 18px 10px 10px;
}
 .cc-dropdown-menu-items .flag-icon {
     height: 15px;
     width: 26px;
     margin-right: 3px;
}
 .cc-dropdown-menu-item:last-child {
     border-bottom: 0;
}
 .cc-dropdown-menu-item:hover {
     background-color: rgb(228, 228, 228);
}
 .cc-dropdown-menu-item.selected {
     border: none;
}
 .cc-dropdown-selected .flag-icon {
     margin-right: 5px!important;
}
 .cc-dropdown-menu-item.selected, .cc-dropdown-menu-item.selected:hover {
     background-color: #323757c2;
     color: #ffffff;
}
 .cc-dropdown-menu-item:last-child {
     pointer-events: none;
}
<div class="country-code-selector">
   <form class="cc-form">
      <div class="cc-form-group">
         <select id="country" name="country" cc-data-dropdown>
            <option value="Afganistan"></option>
            <option value="Albania"></option>
            <option value="Algeria"></option>
            <option value="American Samoa"></option>
            <option value="Andorra"></option>
            <option value="Angola"></option>
            <option value="Anguilla"></option>
            <option value="Antarctica"></option>
            <option value="Antigua and Barbuda"></option>
            <option value="Argentina"></option>
            <option value="Armenia"></option>
            <option value="Aruba"></option>
            <option value="Australia"></option>
            <option value="Austria"></option>
            <option value="Azerbaijan"></option>
            <option value="Bahamas"></option>
            <option value="Bahrain"></option>
            <option value="Bangladesh"></option>
            <option value="Barbados"></option>
            <option value="Belarus"></option>
            <option value="Belgium"></option>
            <option value="Belize"></option>
            <option value="Benin"></option>
            <option value="Bermuda"></option>
            <option value="Bhutan"></option>
            <option value="Bolivia"></option>
            <option value="Bosnia and Herzegovina"></option>
            <option value="Botswana"></option>
            <option value="Brazil"></option>
            <option value="British Indian Ocean Territory"></option>
            <option value="British Virgin Islands"></option>
            <option value="Brunei"></option>
            <option value="Bulgaria"></option>
            <option value="Burkina Faso"></option>
            <option value="Burundi"></option>
            <option value="Cambodia"></option>
            <option value="Cameroon"></option>
            <option value="Canada"></option>
            <option value="Cape Verde"></option>
            <option value="Cayman Islands"></option>
            <option value="Central African Republic"></option>
            <option value="Chad"></option>
            <option value="Chile"></option>
            <option value="China"></option>
            <option value="Christmas Island"></option>
            <option value="Cocos Islands"></option>
            <option value="Colombia"></option>
            <option value="Comoros"></option>
            <option value="Cook Islands"></option>
            <option value="Costa Rica"></option>
            <option value="Croatia"></option>
            <option value="Cuba"></option>
            <option value="Curacao"></option>
            <option value="Cyprus"></option>
            <option value="Czech Republic"></option>
            <option value="Democratic Republic of the Congo"></option>
            <option value="Denmark"></option>
            <option value="Djibouti"></option>
            <option value="Dominica"></option>
            <option value="Dominican Republic"></option>
            <option value="East Timor"></option>
            <option value="Ecuador"></option>
            <option value="Egypt"></option>
            <option value="El Salvador"></option>
            <option value="Equatorial Guinea"></option>
            <option value="Eritrea"></option>
            <option value="Estonia"></option>
            <option value="Ethiopia"></option>
            <option value="Falkland Islands"></option>
            <option value="Faroe Islands"></option>
            <option value="Fiji"></option>
            <option></option>
         </select>
      </div>
   </form>
</div>
wljmcqd8

wljmcqd81#

每次赋值给.innerHTML时,整个DOM都要重新渲染,所以不要分别赋值给每个<option>,创建一个包含所有选项的字符串,然后一次性赋值给<select>.innerHTML

// Autoclick on the parent div to hide the Dropdown after loading a page (Bug)
window.addEventListener('load', () => {
  document.querySelector(".country-code-selector").click();
});

document.addEventListener('DOMContentLoaded', () => {

  const head = document.getElementsByTagName('head')[0];
  const link = document.createElement('link');
  link.rel = 'stylesheet';
  link.type = 'text/css';
  link.href = 'https://amitdutta.co.in/flag/css/flag-icon.css';
  head.appendChild(link);

  // Get dropdowns and form
  const dropdowns = document.querySelectorAll('[cc-data-dropdown]');
  const form = document.querySelector('.country-code-selector form');

  // Check if dropdowns exist on page
  if (dropdowns.length > 0) {
    // Loop through dropdowns and create custom dropdown for each select element
    dropdowns.forEach(dropdown => {
      createCustomDropdown(dropdown);
    });
  }

  // Check if form element exist on page
  if (form !== null) {
    // When form is submitted console log the value of the select field
    form.addEventListener('submit', (e) => {
      e.preventDefault();
      console.log('Selected country:', form.querySelector('[name="country"]').value);
    });
  }

  // Create custom dropdown
  function createCustomDropdown(dropdown) {
    let optionsStr = '';
    optionsStr += '<option><span class="flag-icon flag-icon-afg"></span> Afganistan (+69)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-alb"></span> Albania (+355)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-dza"></span> Algeria (+213)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-asm"></span> American Samoa (+1-684)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-and"></span> Andorra (+376)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-ago"></span> Angola (+244)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-aia"></span> Anguilla (+1-264)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-ata"></span> Antarctica (+672)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-atg"></span> Antigua and Barbuda (+1-268)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-arg"></span> Argentina (+54)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-arm"></span> Armenia (+374)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-abw"></span> Aruba (+297)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-aus"></span> Australia (+61)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-aut"></span> Austria (+43)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-aze"></span> Azerbaijan (+994)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bhs"></span> Bahamas (+1-242)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bhr"></span> Bahrain (+973)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bgd"></span> Bangladesh (+880)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-brb"></span> Barbados (+1-246)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-blr"></span> Belarus (+375)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bel"></span> Belgium (+32)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-blz"></span> Belize (+501)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-ben"></span> Benin (+229)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bmu"></span> Bermuda (+1-441)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-btn"></span> Bhutan (+975)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bol"></span> Bolivia (+591)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bih"></span> Bosnia and Herzegovina (+387)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bwa"></span> Botswana (+267)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bra"></span> Brazil (+55)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-iot"></span> British Indian Ocean Territory (+246)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-vgb"></span> British Virgin Islands (+1-284)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-brn"></span> Brunei (+673)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bgr"></span> Bulgaria (+359)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bfa"></span> Burkina Faso (+226)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-bdi"></span> Burundi (+257)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-khm"></span> Cambodia (+855)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cmr"></span> Cameroon (+237)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-can"></span> Canada (+1)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cpv"></span> Cape Verde (+238)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cym"></span> Cayman Islands (+1-345)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-caf"></span> Central African Republic (+236)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-tcd"></span> Chad (+235)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-chl"></span> Chile (+56)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-chn"></span> China (+86)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cxr"></span> Christmas Island (+61)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cck"></span> Cocos Islands (+61)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-col"></span> Colombia (+57)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-com"></span> Comoros (+269)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cok"></span> Cook Islands (+682)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cri"></span> Costa Rica (+506)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-hrv"></span> Croatia (+385)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cub"></span> Cuba (+53)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cuw"></span> Curacao (+599)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cyp"></span> Cyprus (+357)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cze"></span> Czech Republic (+420)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-cod"></span> Democratic Republic of the Congo (+243)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-dnk"></span> Denmark (+45)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-dji"></span> Djibouti (+253)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-dma"></span> Dominica (+1-767)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-dom"></span> Dominican Republic (+1-809)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-tls"></span> East Timor (+670)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-ecu"></span> Ecuador (+593)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-egy"></span> Egypt (+20)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-slv"></span> El Salvador (+503)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-gnq"></span> Equatorial Guinea (+240)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-eri"></span> Eritrea (+291)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-est"></span> Estonia (+372)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-eth"></span> Ethiopia (+251)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-flk"></span> Falkland Islands (+500)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-fro"></span> Faroe Islands (+298)</option>';
    optionsStr += '<option><span class="flag-icon flag-icon-fji"></span> Fiji (+679)</option>';
    // More 169 Countries (Currently not added here) -
    optionsStr += '</option>No Data Found</option>';

    dropdown.innerHTML = optionsStr;

    // Get all options and convert them from nodelist to array
    const options = dropdown.querySelectorAll('option');
    const optionsArr = Array.prototype.slice.call(options);
    // Create custom dropdown element and add class dropdown to it
    // Insert it in the DOM after the select field
    const customDropdown = document.createElement('div');
    customDropdown.classList.add('cc-dropdown');
    dropdown.insertAdjacentElement('afterend', customDropdown);

    // Create element for selected option
    // Add class to this element, text from the first option in select field and append it to custom dropdown
    const selected = document.createElement('div');
    selected.classList.add('cc-dropdown-selected');
    selected.innerHTML = 'Tel-Code';
    customDropdown.appendChild(selected);

    // Create element for dropdown menu, add class to it and append it to custom dropdown
    // Add click event to selected element to toggle dropdown menu
    const menu = document.createElement('div');
    menu.classList.add('cc-dropdown-menu');
    customDropdown.appendChild(menu);
    selected.addEventListener('click', toggleDropdown.bind(menu));

    // Create serach input element
    // Add class, type and placeholder to this element and append it to menu element
    const search = document.createElement('input');
    search.placeholder = 'Search Your Country...';
    search.type = 'text';
    search.classList.add('cc-dropdown-menu-search');
    menu.appendChild(search);

    // Create wrapper element for menu items, add class to it and append to menu element
    const menuItemsWrapper = document.createElement('div');
    menuItemsWrapper.classList.add('cc-dropdown-menu-items');
    menu.appendChild(menuItemsWrapper);

    // Loop through all options and create custom option for each option and append it to items wrapper element
    // Add click event for each custom option to set clicked option as selected option
    optionsArr.forEach(option => {
      const item = document.createElement('div');
      item.classList.add('cc-dropdown-menu-item');
      item.dataset.value = option.value;
      item.innerHTML = option.innerHTML;
      menuItemsWrapper.appendChild(item);

      item.addEventListener('click', setSelected.bind(item, selected, dropdown, menu));
    });

    // Add selected class to first custom option
    // menuItemsWrapper.querySelector('div').classList.add('selected');

    // Add input event to search input element to filter items
    // Add click event to document element to close custom dropdown if clicked outside of it
    // Hide original dropdown(select)
    search.addEventListener('input', filterItems.bind(search, optionsArr, menu));
    document.addEventListener('click', closeIfClickedOutside.bind(customDropdown, menu));
    dropdown.style.display = 'none';

  }

  // Toggle dropdown
  function toggleDropdown() {
    // Check if dropdown is opened and if it is close it, otherwise open it and focus search input

    if (this.offsetParent !== null) {
      this.style.display = 'none';
    } else {
      this.style.display = 'block';
      this.querySelector('input').focus();
    }
  }

  // Set selected option
  function setSelected(selected, dropdown, menu) {
    // Get value and label from clicked custom option
    const value = this.dataset.value;
    const label = this.innerHTML;

    // Change the text on selected element
    // Change the value on select field  

    filterDate = /(<span\b[^<>]*><\/span>\s*)\w+(?:\s+\w+)*\s*\((\+[\d-]+)\)/g;
    selected.innerHTML = label.replace(filterDate, `$1$2`);
    dropdown.value = value;

    // Close the menu
    // Reset search input value
    // Remove selected class from previously selected option and show all divs if they were filtered
    // Add selected class to clicked option
    menu.style.display = 'none';
    menu.querySelector('input').value = '';
    menu.querySelectorAll('div').forEach(div => {
      if (div.classList.contains('selected')) {
        div.classList.remove('selected');
      }
      if (div.offsetParent === null) {
        div.style.display = 'block';
      }
    });
    this.classList.add('selected');
  }

  // Filter items
  function filterItems(itemsArr, menu) {
    // Get all custom options
    // Get the value of search input and convert it to all lowercase characters
    // Get filtered items
    // Get the indexes of filtered items
    const customOptions = menu.querySelectorAll('.cc-dropdown-menu-items div');
    const value = this.value.toLowerCase();
    const filteredItems = itemsArr.filter(item => item.value.toLowerCase().includes(value));
    const indexesArr = filteredItems.map(item => itemsArr.indexOf(item));

    // Check if option is not inside indexes array and hide it and if it is inside indexes array and it is hidden show it

    var options = itemsArr.length;
    itemsArr.forEach(option => {
      if (!indexesArr.includes(itemsArr.indexOf(option))) {
        customOptions[itemsArr.indexOf(option)].style.display = 'none';
        options -= 1;
        if (options <= 0) {
          customOptions[itemsArr.length - 1].style.display = 'block';
        }
      } else {
        if (customOptions[itemsArr.indexOf(option)].offsetParent === null) {
          customOptions[itemsArr.indexOf(option)].style.display = 'block';
        }
      }
    });
  }

  // Close dropdown if clicked outside dropdown element
  function closeIfClickedOutside(menu, e) {
    if (e.target.closest('.cc-dropdown') === null && e.target !== this && menu.offsetParent !== null) {
      menu.style.display = 'none';
    }
  }

});
.cc-dropdown-menu-items::-webkit-scrollbar-track {
  background-color: #323757;
  width: 2px;
}

.cc-dropdown-menu-items::-webkit-scrollbar {
  background-color: #323757;
  width: 14px;
}

.cc-dropdown-menu-items::-webkit-scrollbar-thumb {
  background-color: #e8576f;
  border: 4px solid #323757;
  z-index: -1;
  width: 2px;
  min-height: 50px;
}

#phone-number {
  width: calc(100% - 120px);
  margin-left: 120px;
}

.frm div:nth-child(3) .inputBox .tx {
  margin-left: 120px;
}

.frm div:nth-child(3) .inputBox {
  display: flex;
}

.frm div:nth-child(3) .inputBox .ln {
  margin-left: 120px;
  width: calc(100% - 120px);
}

.cc-dropdown {
  position: relative;
}

.cc-dropdown-selected {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 116px;
  height: 40px;
  padding: 0 20px 0 10px;
  position: relative;
  cursor: pointer;
  transition: box-shadow .3s ease;
  background-color: #323757;
  border-radius: 3px;
  font-size: 15px;
  color: #fff;
}

.cc-dropdown-selected::after {
  top: calc(50% - 2px);
  right: 10px;
  border: solid transparent;
  content: '';
  height: 0;
  width: 0;
  position: absolute;
  border-top-color: #000;
  border-width: 4px;
  margin-left: -4px;
}

.cc-dropdown-selected:hover {
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}

.cc-dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  width: 273px;
  border: 3px solid #323757;
  margin-right: -2px;
  border-top: 0;
  background-color: #fff;
  z-index: +9;
  margin-top: 10px;
}

.cc-dropdown-menu-items {
  max-height: 200px;
  width: 270px;
  overflow-y: auto;
  overflow-x: hidden;
  z-index: +9;
}

.cc-dropdown-menu-search {
  display: block;
  width: 270px;
  border: 0;
  border-right: 3px solid #323757;
  padding: 14px 0px 14px 10px;
  font-size: 15px;
  font-weight: 550;
  color: #fff;
  outline: 0;
  background-color: #323757;
}

.cc-dropdown-menu-search::placeholder {
  color: rgb(214, 214, 214)!important;
}

.cc-dropdown-menu-item {
  width: 267px;
  border-bottom: 1px solid #323757a6;
  font-size: 14px;
  font-weight: 550;
  cursor: pointer;
  z-index: +9;
  user-select: none;
  padding: 10px 18px 10px 10px;
}

.cc-dropdown-menu-items .flag-icon {
  height: 15px;
  width: 26px;
  margin-right: 3px;
}

.cc-dropdown-menu-item:last-child {
  border-bottom: 0;
}

.cc-dropdown-menu-item:hover {
  background-color: rgb(228, 228, 228);
}

.cc-dropdown-menu-item.selected {
  border: none;
}

.cc-dropdown-selected .flag-icon {
  margin-right: 5px!important;
}

.cc-dropdown-menu-item.selected,
.cc-dropdown-menu-item.selected:hover {
  background-color: #323757c2;
  color: #ffffff;
}

.cc-dropdown-menu-item:last-child {
  pointer-events: none;
}
<div class="country-code-selector">
  <form class="cc-form">
    <div class="cc-form-group">
      <select id="country" name="country" cc-data-dropdown>
        <option value="Afganistan"></option>
        <option value="Albania"></option>
        <option value="Algeria"></option>
        <option value="American Samoa"></option>
        <option value="Andorra"></option>
        <option value="Angola"></option>
        <option value="Anguilla"></option>
        <option value="Antarctica"></option>
        <option value="Antigua and Barbuda"></option>
        <option value="Argentina"></option>
        <option value="Armenia"></option>
        <option value="Aruba"></option>
        <option value="Australia"></option>
        <option value="Austria"></option>
        <option value="Azerbaijan"></option>
        <option value="Bahamas"></option>
        <option value="Bahrain"></option>
        <option value="Bangladesh"></option>
        <option value="Barbados"></option>
        <option value="Belarus"></option>
        <option value="Belgium"></option>
        <option value="Belize"></option>
        <option value="Benin"></option>
        <option value="Bermuda"></option>
        <option value="Bhutan"></option>
        <option value="Bolivia"></option>
        <option value="Bosnia and Herzegovina"></option>
        <option value="Botswana"></option>
        <option value="Brazil"></option>
        <option value="British Indian Ocean Territory"></option>
        <option value="British Virgin Islands"></option>
        <option value="Brunei"></option>
        <option value="Bulgaria"></option>
        <option value="Burkina Faso"></option>
        <option value="Burundi"></option>
        <option value="Cambodia"></option>
        <option value="Cameroon"></option>
        <option value="Canada"></option>
        <option value="Cape Verde"></option>
        <option value="Cayman Islands"></option>
        <option value="Central African Republic"></option>
        <option value="Chad"></option>
        <option value="Chile"></option>
        <option value="China"></option>
        <option value="Christmas Island"></option>
        <option value="Cocos Islands"></option>
        <option value="Colombia"></option>
        <option value="Comoros"></option>
        <option value="Cook Islands"></option>
        <option value="Costa Rica"></option>
        <option value="Croatia"></option>
        <option value="Cuba"></option>
        <option value="Curacao"></option>
        <option value="Cyprus"></option>
        <option value="Czech Republic"></option>
        <option value="Democratic Republic of the Congo"></option>
        <option value="Denmark"></option>
        <option value="Djibouti"></option>
        <option value="Dominica"></option>
        <option value="Dominican Republic"></option>
        <option value="East Timor"></option>
        <option value="Ecuador"></option>
        <option value="Egypt"></option>
        <option value="El Salvador"></option>
        <option value="Equatorial Guinea"></option>
        <option value="Eritrea"></option>
        <option value="Estonia"></option>
        <option value="Ethiopia"></option>
        <option value="Falkland Islands"></option>
        <option value="Faroe Islands"></option>
        <option value="Fiji"></option>
        <option></option>
      </select>
    </div>
  </form>
</div>

相关问题