欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

原生JS實(shí)現(xiàn)自定義下拉單選選擇框功能

 更新時(shí)間:2018年10月12日 08:38:41   作者:山海之間  
最近,把項(xiàng)目中用到的下拉框組件重新封裝了一下,以構(gòu)造函數(shù)的方式進(jìn)行封裝,主要方法和事件定義在原型上,下面是主要的實(shí)現(xiàn)代碼并添加了比較詳細(xì)的注釋,分享出來(lái)供大家參考

瀏覽器自帶的原生下拉框不太美觀,而且各個(gè)瀏覽器表現(xiàn)也不一致,UI一般給的下拉框也是和原生的下拉框差別比較大的,這就需要自己寫一個(gè)基本功能的下拉菜單/下拉選擇框了。最近,把項(xiàng)目中用到的下拉框組件重新封裝了一下,以構(gòu)造函數(shù)的方式進(jìn)行封裝,主要方法和事件定義在原型上,下面是主要的實(shí)現(xiàn)代碼并添加了比較詳細(xì)的注釋,分享出來(lái)供大家參考。代碼用了ES6部分寫法如需兼容低版本瀏覽器請(qǐng)把相關(guān)代碼轉(zhuǎn)成es5寫法,或者直接bable轉(zhuǎn)下。

先放個(gè)預(yù)覽圖吧,后面有最終的動(dòng)態(tài)效果圖:(樣式和交互參考了阿里和Iview UI庫(kù))

下面是主要的HTML代碼(包含部分js調(diào)用代碼):

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Diy Select</title>
  <link rel="stylesheet" href="index.css" rel="external nofollow" >
</head>
<body>
  <div id="main" class="main"></div>

  <script src="index.js"></script>
  <script>
    document.addEventListener("DOMContentLoaded",function(){
      const select1 = new $Selector({
        eleSelector:"#main",
        options:[
          {name:"選項(xiàng)1",value:"0"},
          {name:"選項(xiàng)2",value:"1"},
          {name:"選項(xiàng)3",value:"2"}
        ],
        defaultText:"選項(xiàng)2"
      });
    })
  </script>
</body>
</html>

頁(yè)面中定義了id為main的div,即為選擇框所要添加到的元素。傳入?yún)?shù)即可。

接著就是樣式CSS部分了,沒(méi)啥說(shuō)的了,手動(dòng)滑稽:

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

.main {
  padding: 40px;
}

.my-select {
  display: inline-block;
  width: auto;
  min-width: 80px;
  box-sizing: border-box;
  vertical-align: middle;
  color: #515a6e;
  font-size: 14px;
  line-height: normal;
  position: relative;
}

.select-selection {
  display: block;
  box-sizing: border-box;
  outline: 0;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  cursor: pointer;
  position: relative;
  background-color: #fff;
  border-radius: 4px;
  border: 1px solid #dcdee2;
  transition: all .2s ease-in-out;
}

.select-selection:hover,
.select-selection.select-focus {
  border-color: #57a3f3;
  box-shadow: 0 0 0 2px rgba(45, 140, 240, .2);
}

.select-selected-value {
  display: block;
  height: 28px;
  line-height: 28px;
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-left: 8px;
  padding-right: 24px;
}

.icon-select-arrow {
  position: absolute;
  top: 50%;
  right: 8px;
  line-height: 1;
  margin-top: -7px;
  font-size: 14px;
  color: #808695;
  transition: all .2s ease-in-out;
  display: inline-block;
  font-style: normal;
  font-weight: 400;
  font-variant: normal;
  text-transform: none;
  text-rendering: auto;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  vertical-align: middle;
}

.icon-select-arrow::before {
  content: "";
  display: block;
  width: 6px;
  height: 6px;
  background-color: transparent;
  border-left: 1.5px solid #808695;
  border-bottom: 1.5px solid #808695;
  transform: rotate(-45deg);
}

.select-dropdown {
  width: auto;
  min-width: 80px;
  max-height: 200px;
  overflow: auto;
  margin: 5px 0;
  padding: 5px 0;
  background-color: #fff;
  box-sizing: border-box;
  border-radius: 4px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, .2);
  position: absolute;
  z-index: 2;
  transform-origin: center top 0px;
  transition: all 0.3s;
  will-change: top, left;
  top: 30px;
  left: 0;
  transform: scale(1, 0);
  opacity: 0;
}

.select-item {
  line-height: normal;
  padding: 7px 16px;
  clear: both;
  color: #515a6e;
  font-size: 12px !important;
  white-space: nowrap;
  list-style: none;
  cursor: pointer;
  transition: background .2s ease-in-out;
}

.select-item.select-item-selected,
.select-item:hover {
  color: #2d8cf0;
  background-color: #f3f3f3;
}

樣式部分就不做什么解釋了,下面放入壓軸的JS,同樣也無(wú)需過(guò)多解釋,注釋寫的很詳細(xì)了,上代碼:

/* jshint esversion: 6 */
(function (window, document) {
  let Selector = function (option) {
    //執(zhí)行初始化方法,
    this._init(option);
  };

  Selector.prototype = {
    //初始化傳入?yún)?shù)并定義初始化的相關(guān)變量
    _init({
      eleSelector = "", //傳入的選擇器 id,class,tag等,用于將選擇框渲染到此選擇器所在的元素
      options = [{
        name: "請(qǐng)選擇",
        value: "0",
      }], //傳入的下拉框?qū)ο螅琻ame為選擇的文字,value為值
      defaultText = "請(qǐng)選擇" //提供的默認(rèn)選擇的值
    }) {
      
      //將傳入的數(shù)據(jù)綁定到this上
      this.parentEle = document.querySelector(eleSelector) || document.body; //要邦定的dom 
      this.options = options; //選擇值數(shù)組對(duì)象
      this.defaultText = defaultText; //默認(rèn)值

      this.dropboxShow = false; //定義存儲(chǔ)下拉框的顯示隱藏狀態(tài)
      this.defaultValue = ""; //定義村赤默認(rèn)選中的值
      this._creatElement(); //初始化后執(zhí)行創(chuàng)建元素方法
    },

    //創(chuàng)建下拉選擇框dom
    _creatElement() {
      //選擇框最外層的包裹元素
      let wrapEle = document.createElement("div");
      wrapEle.className = "my-select";

      //根據(jù)傳入的值獲取選擇框默認(rèn)的值和內(nèi)容
      this.options.forEach(item => {
        if (item.name === "this.defaultText") {
          this.defaultValue = item.value;
        }
      });

      let selectWarpBox = document.createElement("div"); //選擇框包裹元素
      selectWarpBox.className = "select-selection";

      let inputHideBox = document.createElement("input"); //隱藏保存選擇值得元素
      inputHideBox.type = "hidden";
      inputHideBox.value = this.defaultValue;

      let selectShowBox = document.createElement("div"); //選擇框默認(rèn)展示框
      let selectNameBox = document.createElement("span"); //選擇框展現(xiàn)的值ele
      selectNameBox.className = "select-selected-value";
      selectNameBox.id = "select-option";
      selectNameBox.innerText = this.defaultText; //將傳入的默認(rèn)值賦值
      let selectIcon = document.createElement("i"); //圖標(biāo)ele
      selectIcon.className = "arrow-down icon-select-arrow";
      //將span和角標(biāo)添加到外層div
      selectShowBox.appendChild(selectNameBox);
      selectShowBox.appendChild(selectIcon);

      selectWarpBox.appendChild(inputHideBox);
      selectWarpBox.appendChild(selectShowBox);

      //下拉框
      let dropbox = document.createElement("div"),
        ulbox = document.createElement("ul");

      dropbox.id = "select-drop";
      dropbox.className = "select-dropdown";
      ulbox.className = "select-dropdown-list";
      //遍歷傳入的選項(xiàng)數(shù)組對(duì)象,生成下拉菜單的li元素并賦值
      this.options.forEach((item) => {
        let itemLi = document.createElement("li");
        if (this.defaultText === item.name) {
          itemLi.className = "select-item select-item-selected";
        } else {
          itemLi.className = "select-item";
        }

        itemLi.setAttribute("data-value", item.value);
        itemLi.innerText = item.name;
        ulbox.appendChild(itemLi);

      });
      //將下拉框ul推入到包裹元素
      dropbox.appendChild(ulbox);

      wrapEle.appendChild(selectWarpBox);
      wrapEle.appendChild(dropbox);

      this.parentEle.appendChild(wrapEle); //將生成的下拉框添加到所選元素中

      //把需要操作的dom掛載到當(dāng)前實(shí)例
      //this.wrapEle = wrapEle;   //最外層包裹元素
      this.eleSelect = selectWarpBox; //選擇框
      this.eleDrop = dropbox; //下拉框
      this.eleSpan = selectNameBox; //顯示文字的span節(jié)點(diǎn)

      //綁定事件處理函數(shù)
      this._bind(this.parentEle);
    },

    //點(diǎn)擊下拉框事件處理函數(shù)
    _selectHandleClick() {
      if (this.dropboxShow) {
        this._selectDropup();
      } else {
        this._selectDropdown();
      }
    },

    //收起下拉選項(xiàng)
    _selectDropup() {
      this.eleDrop.style.transform = "scale(1,0)";
      this.eleDrop.style.opacity = "0";
      this.eleSelect.className = "select-selection";
      this.dropboxShow = false;
    },

    //展示下拉選項(xiàng)
    _selectDropdown() {
      this.eleDrop.style.transform = "scale(1,1)";
      this.eleDrop.style.opacity = "1";
      this.eleSelect.className = "select-selection select-focus";
      this.dropboxShow = true;
    },

    //點(diǎn)擊下拉選項(xiàng)進(jìn)行賦值
    _dropItemClick(ele) {
      this.defaultValue = ele.getAttribute("data-value");
      //document.querySelector("#select-value").value = ele.getAttribute("data-value");
      this.eleSpan.innerText = ele.innerText;
      ele.className = "select-item select-item-selected";
      //對(duì)點(diǎn)擊選中的其他所有兄弟元素修改class去除選中樣式
      this._siblingsDo(ele, function (ele) {
        if (ele) {
          ele.className = "select-item";
        }
      });
      this._selectDropup();
    },

    //node遍歷是否是子元素包裹元素
    _getTargetNode(ele, target) {
      //ele是內(nèi)部元素,target是你想找到的包裹元素
      if (!ele || ele === document) return false;
      return ele === target ? true : this._getTargetNode(ele.parentNode, target);
    },

    //兄弟元素遍歷處理函數(shù)
    _siblingsDo(ele, fn) {

      (function (ele) {
        fn(ele);
        if (ele && ele.previousSibling) {
          arguments.callee(ele.previousSibling);
        }
      })(ele.previousSibling);

      (function (ele) {
        fn(ele);
        if (ele && ele.nextSibling) {
          arguments.callee(ele.nextSibling);
        }
      })(ele.nextSibling);

    },

    //綁定下拉框事件處理函數(shù)
    _bind(parentEle) {
      let _this = this;
      //事件委托到最外層包裹元素進(jìn)行綁定處理
      parentEle.addEventListener("click", function (e) {
        const ele = e.target;
        
        //遍歷當(dāng)前點(diǎn)擊的元素,如果是選中框內(nèi)的元素執(zhí)行
        if (_this._getTargetNode(ele, _this.eleSelect)) {
          if (_this.dropboxShow) {
            _this._selectDropup();
          } else {
            _this._selectDropdown();
          }
        } else if (ele.className === "select-item") { //如果是點(diǎn)擊的下拉框的選項(xiàng)執(zhí)行
          _this._dropItemClick(ele);
        } else { //點(diǎn)擊其他地方隱藏下拉框
          _this._selectDropup();
        }

      });

    }

  };
  //將構(gòu)造函數(shù)掛載到全局window
  window.$Selector = Selector;
})(window, document);

到此,一個(gè)自定義下拉菜單就出爐了,下面是動(dòng)態(tài)效果:

至此,從css自定義的表單元素到下拉框元素都已經(jīng)自定義完畢,使用bootstrap的同學(xué)把這些加進(jìn)去就能基本保持各瀏覽器效果一致性和美觀性了,就到這吧先。

推薦:

感興趣的朋友可以關(guān)注小編的微信公眾號(hào)【碼農(nóng)那點(diǎn)事兒】,更多網(wǎng)頁(yè)制作特效源碼及學(xué)習(xí)干貨哦?。?!

總結(jié)

以上所述是小編給大家介紹的原生js實(shí)現(xiàn)一個(gè)自定義下拉單選選擇框功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • JS中hasOwnProperty方法用法簡(jiǎn)介

    JS中hasOwnProperty方法用法簡(jiǎn)介

    hasOwnProperty(propertyName)方法 是用來(lái)檢測(cè)屬性是否為對(duì)象的自有屬性,如果是,返回true,否者false; 參數(shù)propertyName指要檢測(cè)的屬性名,這篇文章給大家介紹JS中hasOwnProperty方法用法簡(jiǎn)介,感興趣的朋友一起看看吧
    2024-01-01
  • JS數(shù)組操作中的經(jīng)典算法實(shí)例講解

    JS數(shù)組操作中的經(jīng)典算法實(shí)例講解

    下面小編就為大家?guī)?lái)一篇JS數(shù)組操作中的經(jīng)典算法實(shí)例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • JS中的進(jìn)制轉(zhuǎn)換以及作用

    JS中的進(jìn)制轉(zhuǎn)換以及作用

    這篇文章主要介紹了JS中的進(jìn)制轉(zhuǎn)換以及作用的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • JS實(shí)現(xiàn)隨機(jī)生成10個(gè)手機(jī)號(hào)的方法示例

    JS實(shí)現(xiàn)隨機(jī)生成10個(gè)手機(jī)號(hào)的方法示例

    這篇文章主要介紹了JS實(shí)現(xiàn)隨機(jī)生成10個(gè)手機(jī)號(hào)的方法,涉及javascript數(shù)值運(yùn)算與隨機(jī)數(shù)操作相關(guān)使用技巧,需要的朋友可以參考下
    2018-12-12
  • javascript:void(0)用法及常見(jiàn)問(wèn)題解析

    javascript:void(0)用法及常見(jiàn)問(wèn)題解析

    javascript:void(0)?是一個(gè)常見(jiàn)的用法,通常用于創(chuàng)建一個(gè)空操作或者防止頁(yè)面跳轉(zhuǎn),本文主要介紹了javascript:void(0)用法及常見(jiàn)問(wèn)題解析,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • 如何利用模板將HTML從JavaScript中抽離

    如何利用模板將HTML從JavaScript中抽離

    這篇文章主要為大家詳細(xì)介紹了利用模板將HTML從JavaScript中抽離的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • javascript框架設(shè)計(jì)讀書筆記之字符串的擴(kuò)展和修復(fù)

    javascript框架設(shè)計(jì)讀書筆記之字符串的擴(kuò)展和修復(fù)

    本文是司徒正美的《javascript框架設(shè)計(jì)》的第三章第一節(jié)的讀書筆記,簡(jiǎn)單介紹了javascript字符串的擴(kuò)展和修復(fù),小伙伴們參考下吧
    2014-12-12
  • select、radio表單回顯功能實(shí)現(xiàn)避免使用jquery載入賦值

    select、radio表單回顯功能實(shí)現(xiàn)避免使用jquery載入賦值

    select、radio表單回顯避免使用jquery載入賦值,最好的做法是:在jsp頁(yè)面進(jìn)行邏輯判斷,具體實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助
    2013-06-06
  • 淺談JS的原型和原型鏈

    淺談JS的原型和原型鏈

    在原型鏈中,Object是頂級(jí)公民,function是一級(jí)公民,其他的是二級(jí)公民,先記住這句話,下面我們來(lái)講解一下為什么這么說(shuō)。
    2021-06-06
  • JavaScript創(chuàng)建對(duì)象的方式小結(jié)(4種方式)

    JavaScript創(chuàng)建對(duì)象的方式小結(jié)(4種方式)

    這篇文章主要介紹了JavaScript創(chuàng)建對(duì)象的方式,結(jié)合實(shí)例形式總結(jié)分析了四種創(chuàng)建對(duì)象的方式,并附帶分析了JavaScript對(duì)象復(fù)制的技巧,需要的朋友可以參考下
    2015-12-12

最新評(píng)論