li as select item using vanilla Javascript

后端 未结 1 374
予麋鹿
予麋鹿 2021-01-17 02:11



        
1条回答
  •  无人及你
    2021-01-17 02:29

    I really like your custom drop-down menu, especially the CSS you included to give some animation to your menu's expand/collapse actions. I've included a modified version of your snippet, and I hope you'll find it to be of help. I'll explain the revisions I made in what is to follow.

    First off, let me begin by noting that I have some minor adjustments to the HTML content. In particular, I included an field before the entire drop-down menu markup with a corresponding element. This has been added to provide a quick manner of illustrating how to capture the value of a particular item from within the selection menu. Now, when you click on one of the drop-down menu's list items, that item's value will be inserted in said field.

    Next, you'll probably notice that I've added a few class or id attributes to some relevant HTML elements. This is largely as a matter of convenience and to make their selection (through the appropriate JavaScript selectors) easier. One important addition, however, are the data-attributes used on the .dropdown-menu unordered list element. It is a somewhat common pattern seen in normal element is assigned to be the value of the data-optValue attribute on the clicked

  • element.

     let targ = evt.target;
      if (menu.contains(targ)) {
        selectionInput.value = targ.dataset.optvalue;
      }
    

    In the event the target is not a descendant node of menu, it stands to be reasoned that the user either did not click on an entry of the dropdown-menu or that it was the button element. NOTE: As an alternative to assigning the field's value as the value contained in the custom data- attribute, one could also do as shown below:

    if (evt.target !== selectMenu && evt.target !== button) {
      selectionInput.value = evt.target.innerHTML;
    }
    

    I would (at least from a personal point-of-view), discourage this, as it could complicate things should you, for example, add more HTML content nested within the individual

  • tags of the drop-down menu.


    Finally, we conclude with adding a simple event handler. In this case, I've attached the click event to the selectMenu element (i.e., the top-level > tag) passing it the aforementioned clickHandler() function as a callback.

    const selectMenu = document.querySelector('#custom-select'),
          selectionInput = document.querySelector('#input-field'),
          dropdown = document.querySelectorAll('.dropdown'),
          dropdownArray = Array.prototype.slice.call(dropdown,0),
          button = document.querySelector('a[data-toggle="dropdown"]'),
          menu = document.querySelector('.dropdown-menu'),
          arrow = button.querySelector('i.icon-arrow');
    
    // Event callback function:
    function clickHandler(evt) {  
      evt.preventDefault();
      menu.classList.toggle('show');
      menu.classList.toggle('hide');
      arrow.classList.toggle('open');
      arrow.classList.toggle('close');
      
      let targ = evt.target;
      if (menu.contains(targ)) {
        selectionInput.value = targ.dataset.optvalue;
      }
    }
    
    // 'Click' event registration:
    selectMenu.addEventListener('click', clickHandler, false);
    
    
    
    // Purely your code below:
    Element.prototype.hasClass = function(className) {
      return this.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(this.className);
    };
    .text-center {
      text-align: center;
    }
    
    *,
    *:before,
    *:after {
      -webkit-border-sizing: border-box;
      -moz-border-sizing: border-box;
      border-sizing: border-box;
    }
    
    .container {
      width: 350px;
      margin: 50px auto;
    }
    .container > ul {
      list-style: none;
      padding: 0;
      margin: 0 0 20px 0;
    }
    
    .title {
      font: normal 40px/1.4 'Pacifico', sans-serif;
      text-align: center;
      color: #2980B9;
    }
    
    .dropdown a { text-decoration: none; }
    .dropdown [data-toggle="dropdown"] {
      position: relative;
      display: block;
      color: white;
      background: #2980B9;
      -webkit-box-shadow: 0 1px 0 #409ad5 inset,
                          0 -1px 0 #20638f inset;
      -moz-box-shadow:    0 1px 0 #409ad5 inset, 
                          0 -1px 0 #20638f inset;
      box-shadow:         0 1px 0 #409ad5 inset,
                          0 -1px 0 #20638f inset;
      text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
      padding: 10px;
    }
    .dropdown [data-toggle="dropdown"]:hover { background: #2c89c6; }
    .dropdown .icon-arrow {
      position: absolute;
      display: block;
      font-size: 0.7em;
      color: #fff;
      top: 14px;
      right: 10px;
    }
    .dropdown .icon-arrow.open {
      -webkit-transform: rotate(-180deg);
      -moz-transform:    rotate(-180deg);
      -ms-transform:     rotate(-180deg);
      transform:         rotate(-180deg);
      -webkit-transition: -webkit-transform 0.6s;
      -moz-transition:    -moz-transform 0.6s;
      -o-transition:      -o-transform 0.6s;
      transition:         transform 0.6s;
    }
    .dropdown .icon-arrow.close {
      -webkit-transform: rotate(0);
      -moz-transform:    rotate(0);
      -ms-transform:     rotate(0);
      transform:         rotate(0);
      -webkit-transition: -webkit-transform 0.6s;
      -moz-transition:    -moz-transform 0.6s;
      -o-transition:      -o-transform 0.6s;
      transition:         transform 0.6s;
    }
    .dropdown .icon-arrow:before { content: '\25BC'; }
    .dropdown .dropdown-menu {
      max-height: 0;
      overflow: hidden;
      list-style: none;
      padding: 0;
      margin: 0;
    }
    .dropdown .dropdown-menu li { padding: 0; }
    .dropdown .dropdown-menu li a {
      display: block;
      color: #6f6f6f;
      background: #EEE;
      -webkit-box-shadow: 0 1px 0 white inset,
                          0 -1px 0 #d5d5d5 inset;
      -moz-box-shadow:    0 1px 0 white inset,
                          0 -1px 0 #d5d5d5 inset;
      box-shadow:         0 1px 0 white inset,
                          0 -1px 0 #d5d5d5 inset;
      text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.3);
      padding: 10px 10px;
    }
    .dropdown .dropdown-menu li a:hover {
      background: #f6f6f6;
    }
    .dropdown .show,
    .dropdown .hide {
      -webkit-transform-origin: 50% 0;
      -moz-transform-origin: 50% 0;
      -ms-transform-origin: 50% 0;
      transform-origin: 50% 0;
    }
    .dropdown .show {
      display: block;
      max-height: 9999px;
      -webkit-transform: scaleY(1);
      -moz-transform:    scaleY(1);
      -ms-transform:     scaleY(1);
      transform:         scaleY(1);
      -webkit-animation: showAnimation 0.5s ease-in-out;
      -moz-animation:    showAnimation 0.5s ease-in-out;
      animation:         showAnimation 0.5s ease-in-out;
      -webkit-transition: max-height 1s ease-in-out;
      -moz-transition:    max-height 1s ease-in-out;
      -o-transition:      max-height 1s ease-in-out;
      transition:         max-height 1s ease-in-out;
    }
    .dropdown .hide {
      max-height: 0;
      -moz-transform: scaleY(0);
      -ms-transform: scaleY(0);
      -webkit-transform: scaleY(0);
      transform: scaleY(0);
      animation: hideAnimation 0.4s ease-out;
      -moz-animation: hideAnimation 0.4s ease-out;
      -webkit-animation: hideAnimation 0.4s ease-out;
      -moz-transition: max-height 0.6s ease-out;
      -o-transition: max-height 0.6s ease-out;
      -webkit-transition: max-height 0.6s ease-out;
      transition: max-height 0.6s ease-out;
    }
    
    @keyframes showAnimation {
      0% {
        -moz-transform: scaleY(0.1);
        -ms-transform: scaleY(0.1);
        -webkit-transform: scaleY(0.1);
        transform: scaleY(0.1);
      }
      40% {
        -moz-transform: scaleY(1.04);
        -ms-transform: scaleY(1.04);
        -webkit-transform: scaleY(1.04);
        transform: scaleY(1.04);
      }
      60% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.04);
        -ms-transform: scaleY(1.04);
        -webkit-transform: scaleY(1.04);
        transform: scaleY(1.04);
      }
      100% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.02);
        -ms-transform: scaleY(1.02);
        -webkit-transform: scaleY(1.02);
        transform: scaleY(1.02);
      }
      100% {
        -moz-transform: scaleY(1);
        -ms-transform: scaleY(1);
        -webkit-transform: scaleY(1);
        transform: scaleY(1);
      }
    }
    @-moz-keyframes showAnimation {
      0% {
        -moz-transform: scaleY(0.1);
        -ms-transform: scaleY(0.1);
        -webkit-transform: scaleY(0.1);
        transform: scaleY(0.1);
      }
      40% {
        -moz-transform: scaleY(1.04);
        -ms-transform: scaleY(1.04);
        -webkit-transform: scaleY(1.04);
        transform: scaleY(1.04);
      }
      60% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.04);
        -ms-transform: scaleY(1.04);
        -webkit-transform: scaleY(1.04);
        transform: scaleY(1.04);
      }
      100% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.02);
        -ms-transform: scaleY(1.02);
        -webkit-transform: scaleY(1.02);
        transform: scaleY(1.02);
      }
      100% {
        -moz-transform: scaleY(1);
        -ms-transform: scaleY(1);
        -webkit-transform: scaleY(1);
        transform: scaleY(1);
      }
    }
    @-webkit-keyframes showAnimation {
      0% {
        -moz-transform: scaleY(0.1);
        -ms-transform: scaleY(0.1);
        -webkit-transform: scaleY(0.1);
        transform: scaleY(0.1);
      }
      40% {
        -moz-transform: scaleY(1.04);
        -ms-transform: scaleY(1.04);
        -webkit-transform: scaleY(1.04);
        transform: scaleY(1.04);
      }
      60% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.04);
        -ms-transform: scaleY(1.04);
        -webkit-transform: scaleY(1.04);
        transform: scaleY(1.04);
      }
      100% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.02);
        -ms-transform: scaleY(1.02);
        -webkit-transform: scaleY(1.02);
        transform: scaleY(1.02);
      }
      100% {
        -moz-transform: scaleY(1);
        -ms-transform: scaleY(1);
        -webkit-transform: scaleY(1);
        transform: scaleY(1);
      }
    }
    @keyframes hideAnimation {
      0% {
        -moz-transform: scaleY(1);
        -ms-transform: scaleY(1);
        -webkit-transform: scaleY(1);
        transform: scaleY(1);
      }
      60% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.02);
        -ms-transform: scaleY(1.02);
        -webkit-transform: scaleY(1.02);
        transform: scaleY(1.02);
      }
      100% {
        -moz-transform: scaleY(0);
        -ms-transform: scaleY(0);
        -webkit-transform: scaleY(0);
        transform: scaleY(0);
      }
    }
    @-moz-keyframes hideAnimation {
      0% {
        -moz-transform: scaleY(1);
        -ms-transform: scaleY(1);
        -webkit-transform: scaleY(1);
        transform: scaleY(1);
      }
      60% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.02);
        -ms-transform: scaleY(1.02);
        -webkit-transform: scaleY(1.02);
        transform: scaleY(1.02);
      }
      100% {
        -moz-transform: scaleY(0);
        -ms-transform: scaleY(0);
        -webkit-transform: scaleY(0);
        transform: scaleY(0);
      }
    }
    @-webkit-keyframes hideAnimation {
      0% {
        -moz-transform: scaleY(1);
        -ms-transform: scaleY(1);
        -webkit-transform: scaleY(1);
        transform: scaleY(1);
      }
      60% {
        -moz-transform: scaleY(0.98);
        -ms-transform: scaleY(0.98);
        -webkit-transform: scaleY(0.98);
        transform: scaleY(0.98);
      }
      80% {
        -moz-transform: scaleY(1.02);
        -ms-transform: scaleY(1.02);
        -webkit-transform: scaleY(1.02);
        transform: scaleY(1.02);
      }
      100% {
        -moz-transform: scaleY(0);
        -ms-transform: scaleY(0);
        -webkit-transform: scaleY(0);
        transform: scaleY(0);
      }
    }

0 讨论(0)
提交回复
热议问题