摘要:在寫示例的時候,用到了下拉框,但是原生的下拉框是在是有點難看,然后模仿著寫了點,一個是直接在寫好的上進行美化,一個是用生成,然后定義類名及相應的事件來處理效果圖直接是在上美化文件請選擇你喜歡的文字萬水千山,陪你一起看萬水千山,陪你一起看萬水
在寫示例的時候,用到了下拉框,但是原生的下拉框是在是有點難看,然后模仿著寫了點,一個是直接在寫好的Dom上進行美化,一個是用js生成,然后定義類名及相應的事件來處理1.效果圖 2.直接是在Dom上美化
html文件
請選擇你喜歡的文字
- 萬水千山,陪你一起看
- 萬水千山,陪你一起看1
- 萬水千山,陪你一起看2
- 萬水千山,陪你一起看3
- 萬水千山,陪你一起看4
css文件
ul{ margin: 0; padding: 0; list-style: none; } /* 下拉框包含層 */ #selectedItem{ width: 240px; cursor: pointer; } /* 已選中的選項 */ #promptText{ position: relative; padding-left: 10px; width: 230px; height: 30px; line-height: 30px; border: 1px solid #d3d3d3; border-radius: 4px; background: #fff; color: #999; font-size: 14px; } /* 圖標 */ #arrows{ position: absolute; top: 0; right: 0; width: 30px; height: 30px; vertical-align: middle; } #arrows:focus{ outline: none; } /* 下拉可選項包含層 */ .choiceDescription{ position: absolute; display: none; /*overflow: hidden;*/ margin-top: 2px; width: 240px; border: 1px solid #ccc; border-radius: 4px; box-shadow: 0 1px 6px rgba(0, 0, 0, .1); background: #fff; } .show{ display: block; } /* 下拉可選項 */ .item{ height: 30px; line-height: 30px; padding-left: 10px; font-size: 15px; color: #666; } .item:hover{ color: #fff; background: rgba(49, 255, 195, 0.67); }
js文件
(function() { let choiceDescription = document.getElementsByClassName("choiceDescription")[0]; let arrows = document.getElementById("arrows"); /* 用于判斷是否是下拉 */ let isDown = false; let selectedItem = document.getElementById("selectedItem"); /* 對點擊下拉進行監(jiān)聽 */ selectedItem.addEventListener("click", function() { isDown = !isDown; if(isDown) { /* 如果是下拉狀態(tài),則顯示下拉的選項,并把圖標顯示為向下的圖標 */ choiceDescription.className += " show"; arrows.src = "../images/arrowdown.png"; } else { choiceDescription.className = "choiceDescription"; arrows.src = "../images/arrowup.png"; } }); choiceDescription.addEventListener("click", function(e) { let promptText = document.getElementById("spanText"); let selectElement = e.target; /* 判斷是否點擊的是li標簽,防止點擊了li標簽以外的空白位置 */ while(selectElement.tagName !== "LI") { /* 如果點中的是當前容器層 */ if(selectElement == choiceDescription) { selectElement = null; break; } /* 若果不是,則再找父級容器 */ selectElement = selectElement.parentNode; } /* innerText、innerHTML、value * innerText 是指html標簽里的文字信息,單純的文本,不會有html標簽,存在兼容性 * innerHTML 是指包含在html標簽里的所有子元素,包括空格、html標簽 * value 表單里的元素屬性值 * */ if(selectElement) { promptText.innerHTML = e.target.innerHTML; } }); })()
在已有的Dom節(jié)點上對Dom綁定事件,我這里的寬度是固定死的,相對來說不是很友好
3.js自動生成進行美化html文件
*css文件
html, body, ul{ margin: 0; padding: 0; } ul{ list-style: none; } #select{ padding: 30px 40px 0; } /* 下拉框 */ .dropDown{ position: relative; display: inline-block; min-width: 120px; box-sizing: border-box; color: #515a6e; font-size: 14px; } /* 已選中的值包含層 */ .selectedOption{ position: relative; box-sizing: border-box; outline: none; user-select: none; cursor: pointer; background: #fff; border-radius: 4px; border: 1px solid #dcdee2; transition: all .2s ease-in-out; } .selectedValue{ display: block; overflow: hidden; height: 28px; line-height: 28px; font-size: 12px; text-overflow: ellipsis; white-space: nowrap; padding-left: 8px; padding-right: 24px; } /* 圖標 */ .arrowDown{ position: absolute; display: inline-block; top: 50%; right: 8px; margin-top: -7px; font-size: 14px; color: #808695; transition: all .2s ease-in-out; /* 字體抗鋸齒渲染 */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .arrowDown:before{ content: ""; display: block; width: 6px; height: 6px; background-color: transparent; border-left: 2px solid #808695; border-bottom: 2px solid #808695; transform: rotate(-45deg); } /* 所有選項的包含層 */ .optionsContainer{ position: absolute; top: 30px; left: 0; min-width: 120px; max-height: 200px; margin: 5px 0; padding: 5px 0; background: #fff; box-sizing: border-box; border-radius: 4px; box-shadow: 0 1px 6px rgba(0, 0, 0, .2); z-index: 2; transform-origin: center top 0px; transition: all 0.3s; will-change: top, left; transform: scale(1, 0); opacity: 0; } /* 每個選項 */ .optionsItem{ line-height: normal; padding: 7px 16px; color: #515a6e; font-size: 12px; white-space: nowrap; cursor: pointer; transition: background .2s ease-in-out; } .itemSelected, .optionsItem:hover{ color: #2d8cf0; background-color: #f3f3f3; }
對下拉框初始化
/* 私有方法:初始化下拉框 */ _initSelector({ /* 傳入id,class,tag,用于掛載下拉框 */ elementSelector = "", /* 傳入的下拉框選項 */ options = [{ name: "請選擇你喜歡的顏色", value: "0" }], defaultText = "請選擇你喜歡的顏色" }) { /* 找到要掛載的Dom節(jié)點 */ this.parentElement = document.querySelector(elementSelector) || document.body; this.options = options; this.defaultText = defaultText; /* 下拉框的顯示與隱藏狀態(tài) */ this.downStatus = false; /* 下拉框默認選中的值 */ this.defaultValue = ""; this._createElement(); },
創(chuàng)建元素節(jié)點
/* 創(chuàng)建Dom節(jié)點 */ _createElement() { /* 創(chuàng)建下拉框最外層 */ let dropDown = document.createElement("div"); dropDown.className = "dropDown"; /* 已選中的選項值 */ let selectedOption = document.createElement("div"); selectedOption.className = "selectedOption"; /* 選中的值 */ let selectedValue = document.createElement("span"); selectedValue.className = "selectedValue"; /* 先賦值為默認值 */ selectedValue.innerText = this.defaultText; /* 向下的圖標 */ let downIcon = document.createElement("i"); downIcon.className = "arrowDown"; /* 將已選中的值的層添加到Dom節(jié)點中 */ selectedOption.appendChild(selectedValue); selectedOption.appendChild(downIcon); /* 創(chuàng)建選項的外層容器 */ let optionsContainer = document.createElement("div"); optionsContainer.className = "optionsContainer"; /* 用ul來包含選項層 */ let ulOptionsList = document.createElement("ul"); ulOptionsList.className = "ulOptionsList"; /* 循環(huán)創(chuàng)建每個選項 */ this.options.forEach((item) => { let optionsItem = document.createElement("li"); /* 是否是選中狀態(tài) */ if(item.name == this.defaultText) { optionsItem.className = "optionsItem itemSelected"; } else { optionsItem.className = "optionsItem"; } optionsItem.innerText = item.name; ulOptionsList.appendChild(optionsItem); }); /* 添加到每個對應的元素里面 */ optionsContainer.appendChild(ulOptionsList); dropDown.appendChild(selectedOption); dropDown.appendChild(optionsContainer); this.parentElement.appendChild(dropDown); /* 設置Dom元素,掛載、綁定事件 */ /* 已選中的選項的包含層 */ this.selectedOption = selectedOption; /* 選中的值 */ this.selectedValue = selectedValue; /* 下拉框選項包含層 */ this.optionsContainer = optionsContainer; this._handleShowOptions(this.parentElement); this._unifyWidth(selectedOption); },
顯示與隱藏相關事件
/* 顯示與隱藏事件 */ _handleShowOptions(element) { element.addEventListener("click", (e) => { let clickNode = e.target; this._unifyWidth(this.selectedOption); /* 點擊的是否是下拉框 */ if(this._isOptionNode(clickNode, this.selectedOption)) { if(this.downStatus) { this._hiddenDropDown(); } else { this._showDropDown(); } } else if(clickNode.className == "optionsItem") { this._handleSelected(clickNode); } else { this._hiddenDropDown(); } }) }, /* 判斷是否是下拉框選項 */ _isOptionNode(clickNode, target) { if (!clickNode || clickNode === document) return false; return clickNode === target ? true : this._isOptionNode(clickNode.parentNode, target); }, /* 顯示下拉框選項 */ _showDropDown() { this.optionsContainer.style.transform = "scale(1, 1)"; this.optionsContainer.style.opacity = "1"; this.selectedOption.className = "selectedOption"; this.downStatus = true; }, /* 隱藏下拉框選項 */ _hiddenDropDown() { this.optionsContainer.style.transform = "scale(1, 0)"; this.optionsContainer.style.opacity = "0"; this.selectedOption.className = "selectedOption"; this.downStatus = false; },
定義點擊事件
/* 對每個選項的點擊事件 */ _handleSelected(clickNode) { this.selectedValue.innerText = clickNode.innerText; clickNode.className = "optionsItem itemSelected"; this._siblingsDom(clickNode, function(clickNode) { if(clickNode) { clickNode.className = "optionsItem"; } }); this._hiddenDropDown(); }, /* 兄弟節(jié)點處理函數(shù) */ _siblingsDom(clickNode, callback) { /* arguments 是一個對應于傳遞給函數(shù)的參數(shù)的類數(shù)組對象 * arguments對象是所有(非箭頭)函數(shù)中都可用的局部變量 * 包含傳遞給函數(shù)的每個參數(shù),第一個參數(shù)在索引0處 * arguments對象不是一個 Array,它類似于Array, * 但除了length屬性和索引元素之外沒有任何Array屬性 * */ (function (ele) { /* arguments.callee * 指向當前執(zhí)行的函數(shù) * */ callback(ele); if (ele && ele.previousSibling) { arguments.callee(ele.previousSibling); } })(clickNode.previousSibling); (function (ele) { callback(ele); if (ele && ele.nextSibling) { arguments.callee(ele.nextSibling); } })(clickNode.nextSibling); },
判斷寬度
/* 判斷寬度 */ _unifyWidth(selectedOption) { /* 找到所有的li標簽 */ let optionsItem = document.querySelectorAll(".optionsItem"); let standardWidth = selectedOption.offsetWidth; /* 對每個li標簽設置寬度 */ optionsItem.forEach((item) => { standardWidth = item.offsetWidth > standardWidth ? item.offsetWidth : standardWidth; item.style.width = standardWidth - 32 + "px"; selectedOption.style.width = standardWidth + "px"; }); }
(function() { /* 定義selector下拉框 */ let Selector = function(params) { /* 初始化 */ this._initSelector(params); }; Selector.prototype = { /* 將上面的方法全部放在Selector原型上 */ }; /* 掛載到window上*/ window.$Selector = Selector; })();
關于原型與原型鏈,可以查看我記錄的js面試
使用js生成的話,相對來說,代碼長點,我這里的話,對寬度有做判斷,但是不完美
關于DOMContentLoaded可以查看這篇文章DOMContentLoaded
正在努力學習中,若對你的學習有幫助,留下你的印記唄(點個贊咯^_^)
往期好文推薦:
判斷iOS和Android及PC端
純css實現(xiàn)瀑布流(multi-column多列及flex布局)
實現(xiàn)單行及多行文字超出后加省略號
微信小程序之購物車和父子組件傳值及calc的注意事項
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99883.html
摘要:前端小白也能快速學會的博客園博客美化全攻略呦,博客園的自我修養(yǎng)是什么第一條,別只顧收藏和偷師呀,記得點推薦或關注本人喔美化方法論簡介一般而言,需要選一個默認的,然后在該基礎上調整。或者也可進博客園園子頁面,發(fā)狀態(tài)博客園團隊,申請開通權限。 前端小白也能快速學會的博客園博客美化全攻略 A呦V,博客園er的自我修養(yǎng)是什么?第一條,別只顧收藏和偷師呀,記得點推薦或關注本人喔~ 美化方法論簡...
摘要:允許以特定的方式去定義匹配某個區(qū)域的特定元素。在規(guī)定一個框的寬高之外給這個框加內邊距和邊框。和默認值在規(guī)定的一個框的寬高之內給這個框加內邊距和邊框。 1. box-sizing:允許以特定的方式去定義匹配某個區(qū)域的特定元素。 content-box:在規(guī)定一個框的寬高之外給這個框加內邊距和邊框。 border-box:(textarea和select默認值)在規(guī)定的一個框的寬高之內給這...
摘要:允許以特定的方式去定義匹配某個區(qū)域的特定元素。在規(guī)定一個框的寬高之外給這個框加內邊距和邊框。和默認值在規(guī)定的一個框的寬高之內給這個框加內邊距和邊框。 1. box-sizing:允許以特定的方式去定義匹配某個區(qū)域的特定元素。 content-box:在規(guī)定一個框的寬高之外給這個框加內邊距和邊框。 border-box:(textarea和select默認值)在規(guī)定的一個框的寬高之內給這...
摘要:允許以特定的方式去定義匹配某個區(qū)域的特定元素。在規(guī)定一個框的寬高之外給這個框加內邊距和邊框。和默認值在規(guī)定的一個框的寬高之內給這個框加內邊距和邊框。 1. box-sizing:允許以特定的方式去定義匹配某個區(qū)域的特定元素。 content-box:在規(guī)定一個框的寬高之外給這個框加內邊距和邊框。 border-box:(textarea和select默認值)在規(guī)定的一個框的寬高之內給這...
閱讀 1634·2023-04-26 02:11
閱讀 2979·2023-04-25 16:18
閱讀 3711·2021-09-06 15:00
閱讀 2630·2019-08-30 15:55
閱讀 1934·2019-08-30 13:20
閱讀 2051·2019-08-26 18:36
閱讀 3121·2019-08-26 11:40
閱讀 2538·2019-08-26 10:11