您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
原生js实现简洁的下拉菜单
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/463933/1175343/MyDropdown.js
//构造方法 function MyDropdown(options){ //_count是某实例下的菜单个数 this._count = 0; this._zIndex = 1000; this._config = options; window._MyDropdownPosIndex = (window._MyDropdownPosIndex||this._zIndex)+1; //实例总个数 window._MyDropdownInsCount = (window._MyDropdownInsCount||0)+1; //当前第几个实例 this.insCount = window._MyDropdownInsCount; if(this._config) { this.config(options); this.createStyle(); } //返回对象类型 this.type = function(obj) { return Object.prototype.toString .call(obj) .replace(/^\[object (.+)\]$/, '$1') .toLowerCase(); } } MyDropdown.prototype.createStyle = function() { if(document.querySelector("#MyDropdownStyle")) { return; } let = style = ` <style> .my-dropdown-wrapper { display: none; position: absolute; background-color: #f1f1f1; min-width: 160px; overflow: auto; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .my-dropdown-wrapper a { color: black; padding: 12px 16px; text-decoration: none; display: block; } .my-dropdown-wrapper a:hover {background-color: #ddd;} .my-dropdown-wrapper a.selected {background-color: #ddd;} .show {display: block;} .my-dropdown-item-icon svg{width: 24px;height: 24px;float: left;} .close { width: 24px; height: 24px; display: inline-block; line-height: 24px; text-align: center; font-size: 18px; float: right; } </style> ` document.body.insertAdjacentHTML("beforeend", style); } //设置用户配置 MyDropdown.prototype.config = function(options) { var _this = this; //设置用户配置 _this._config = options || _this._config; if(_this._config.toggleEvent && _this._config.toggleEvent.toLowerCase() === 'mouseover') { _this._config.toggleEvent = 'mouseenter'; } //绑定事件源按钮点击事件 document.querySelectorAll(_this._config.el||".my-dropdown-btn").forEach(function(item){ item.addEventListener(_this._config.toggleEvent||'click', function(e){ _this.create(this); _this.show(this); e.stopPropagation(); return false; }); }); //点击空白,菜单消失 document.addEventListener('click', function(e){ if (!e.target.matches(_this._config.el||'.my-dropdown-btn')) { _this.hide(); } }); } //创建菜单 MyDropdown.prototype.create = function(objBtn, options) { var _this = this; options = options || _this._config; if(options.el) { _this._config.el = options.el; } if(objBtn) { if (!objBtn.dataset.count) { objBtn.dataset.count = _this._count++; objBtn.classList.add('my-btn'+_this.insCount+objBtn.dataset.count); } } var count = objBtn.dataset.count || 0; //已存在则返回 if(document.querySelector(`#myDropdownWrapper${_this.insCount}${count}`)) { return; } var mouseenterClass = ""; if(_this._config.toggleEvent && _this._config.toggleEvent.toLowerCase() === 'mouseenter') { mouseenterClass = " mouseenter"; } //生成菜单 这里count是某实例下的菜单个数,_this.insCount是实例个数 var menu = `<div id="myDropdownWrapper${_this.insCount}${count}" class="my-dropdown-wrapper${mouseenterClass}" style="overflow:auto;${options.maxWidth?'max-width:'+options.maxWidth+';':''}${options.maxHeight?'max-height:'+options.maxHeight+';':''}" data-count="${count}">`; if(options.items) { for(var i in options.items){ var item = options.items[i]; //处理icon选项 var iconHtml = ''; if(item.icon){ if(_this.type(item.icon) === 'object'){ iconHtml = item.icon.html ? item.icon.html : ''; } else { iconHtml = item.icon ? item.icon : ''; } } //处理op选项 var opHtml = ''; if(item.op){ if(_this.type(item.op) === 'object'){ opHtml = item.op.html ? item.op.html : ''; } else { opHtml = item.op ? item.op : ''; } } //生成菜单项 menu += `<a href="javascript:;" class="my-dropdown-item ${item.selected?'selected':''}" data-index="${i}" data-value="${item.value}"><span class="my-dropdown-item-icon">${iconHtml}</span>${item.name}<span class="my-dropdown-item-op">${opHtml}</span></a>`; } } menu += `</div>`; //追加到body中 document.body.insertAdjacentHTML("beforeend", menu); //绑定菜单事件 if(_this._config.toggleEvent && _this._config.toggleEvent.toLowerCase() === 'mouseenter') { //绑定菜单列表 document.querySelector("#myDropdownWrapper" + _this.insCount + count).addEventListener("mouseleave", function(e){ _this.hide(this); }); } //绑定菜单item点击事件 document.querySelectorAll("#myDropdownWrapper" + _this.insCount + count + " .my-dropdown-item").forEach(function(item){ item.addEventListener("click", function(e){ if(typeof this.dataset.index !== 'undefined' && options.items[this.dataset.index]) { options.items[this.dataset.index].fn(e); } }); }); //绑定菜单项icon按钮点击事件 document.querySelectorAll("#myDropdownWrapper" + _this.insCount + count + " .my-dropdown-item-icon").forEach(function(item){ //if(!item.innerHTML) return; item.addEventListener("click", function(e){ if(typeof this.parentElement.dataset.index !== 'undefined' && options.items[this.parentElement.dataset.index] && options.items[this.parentElement.dataset.index].icon && options.items[this.parentElement.dataset.index].icon.fn) { var _this_item = this; (function(e){ options.items[_this_item.parentElement.dataset.index].icon.fn(e); e.stopPropagation(); return false; })(e); } }); }); //绑定菜单项操作按钮点击事件 document.querySelectorAll("#myDropdownWrapper" + _this.insCount + count + " .my-dropdown-item-op").forEach(function(item){ //if(!item.innerHTML) return; item.addEventListener("click", function(e){ if(typeof this.parentElement.dataset.index !== 'undefined' && options.items[this.parentElement.dataset.index] && options.items[this.parentElement.dataset.index].op && options.items[this.parentElement.dataset.index].op.fn) { var _this_item = this; (function(e){ options.items[_this_item.parentElement.dataset.index].op.fn(e); e.stopPropagation(); return false; })(e); } }); }); if(options.created) options.created(document.querySelector(`#myDropdownWrapper${_this.insCount}${count}`)); }; //菜单显示 MyDropdown.prototype.show = function(objBtn, callback) { var count = objBtn.dataset.count || 0; var myDropdownWrapper = document.getElementById("myDropdownWrapper"+this.insCount+count); if(objBtn){ myDropdownWrapper.style.top = (objBtn.offsetTop + objBtn.offsetHeight) + "px"; myDropdownWrapper.style.left = objBtn.offsetLeft + "px"; } if (myDropdownWrapper.classList.contains('show')) { if(this._config.toggleEvent && this._config.toggleEvent.toLowerCase() === 'mouseenter'){ return; } //隐藏菜单 myDropdownWrapper.classList.remove('show'); if(this._config.hidden) this._config.hidden(); } else { if(this._config.toggleEvent && this._config.toggleEvent.toLowerCase() === 'mouseenter'){ this.hide(); } //显示菜单 myDropdownWrapper.style.zIndex = window._MyDropdownPosIndex++; myDropdownWrapper.classList.add('show'); callback = callback || this._config.shown; if(callback) callback(myDropdownWrapper); } //myDropdownWrapper.classList.toggle("show"); } //菜单隐藏 MyDropdown.prototype.hide = function(objMenu, callback) { if(objMenu) { //单个菜单隐藏 if (objMenu.classList.contains('show')) { objMenu.classList.remove('show'); callback = callback || this._config.hidden; if(callback) callback(objMenu); } } else { var mouseenterClass = ''; if(this._config.toggleEvent && this._config.toggleEvent.toLowerCase() === 'mouseenter'){ mouseenterClass = ".mouseenter"; } //所有菜单隐藏 var dropdowns = document.querySelectorAll(".my-dropdown-wrapper" + mouseenterClass); for (var i = 0; i < dropdowns.length; i++) { var openDropdown = dropdowns[i]; if (openDropdown.classList.contains('show')) { openDropdown.classList.remove('show'); callback = callback || this._config.hidden; if(callback) callback(openDropdown); } } } }; //使用示例 //测试1 // var clicked = function(e) { // console.log("clicked", e.target.dataset.value) // } // new MyDropdown({ // el: ".my-dropdown-btn", // maxWidth: '200px', // maxHeight: '400px', // //支持click mouseenter dblclick等,默认click // toggleEvent: 'mouseenter', // items: [ // { // name: 'Home', // value: 'home', // icon: '', // fn: clicked // }, // { // name: 'About', // value: 'about', // icon: '', // selected: false, // fn: clicked // }, // { // name: 'Contact', // value: 'contact', // icon: '', // fn: clicked, // //icon也支持对象传值,同样具有html和fn属性 // op: { // html: `<span class="close">×</span>`, // fn: function(e) { // console.log('op clicked'); // } // } // } // ], // created: function(menu) { // console.log('After created callback'); // }, // shown: function(menu) { // console.log('After shown callback'); // }, // hidden: function(menu) { // console.log('After hidden callback'); // } // }); // //测试2 // var clicked2 = function(e) { // console.log("clicked2", e.target.dataset.value) // } // new MyDropdown({ // el: ".my-dropdown-btn2", // items: [ // { // name: 'Home2', // value: 'home2', // icon: '', // fn: clicked2 // }, // { // name: 'About2', // value: 'about2', // icon: '', // selected: false, // fn: clicked2 // }, // { // name: 'Contact2', // value: 'contact2', // icon: '', // fn: clicked2 // } // ], // created: function(menu) { // console.log('After created callback'); // }, // shown: function(menu) { // console.log('After shown callback'); // }, // hidden: function(menu) { // console.log('After hidden callback'); // } // });
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址