HTML下拉框样式美化

news2025/7/28 17:25:01

        在网页中,下拉框的样式最难美化,默认样式巨丑,好在现在已经有各种框架实现了下拉框的样式美化,主要思路都是通过JS代码将下拉框元素用更容易设置样式的div进行替换,再将对应选项及事件进行关联。

        最近一项目需要修改很久以前的页面,用户需求又需要美化下拉框样式,又不能引入第三方的框架,只好自己动手写了一个JS插件,实现下拉框的样式美化。

1、插件效果

        页面包含两个下拉框,一个3个选项,一个多个选项,一个选项内容较短,一个较长,页面代码如下:

    <form>
        <div class="div-form">
            <div class="div-form-row">
                <span class="form-title">selected: </span>
                <div class="form-input">
                    <select name="s1" onchange="selectChange('1','2')">
                        <option value="1">1111</option>
                        <option value="2" selected>2222</option>
                        <option value="3">3333</option>
                    </select>
                </div>
            </div>

            <div class="div-form-row">
                <span class="form-title">select time zone: </span>
                <div class="form-input">
                    <select name="s2">
                        <option value="1">(GMT-12:00) International Date Line West</option>
                        <option value="2">(GMT-11:00) Midway Island, Samoa</option>
                        <option value="3">(GMT-10:00) Hawaii</option>
                        <option value="4">(GMT-09:00) Alaska</option>
                        <option value="5">(GMT-08:00) Pacific Time, Tijuana</option>
                        <option value="6">(GMT-07:00) Arizona, Mazatlan</option>
                        <option value="7">(GMT-07:00-1) Chihuahua, La Paz</option>
                        <option value="8">(GMT-07:00-2) Mountain Time</option>
                        <option value="9">(GMT-06:00) Central America</option>
                        <option value="10">(GMT-06:00-1) Central Time</option>
                        <option value="11" selected>(GMT-06:00-2) Guadalajara, Mexico City, Monterrey</option>
                        <option value="12">(GMT-06:00-3) Saskatchewan</option>
                        <option value="13">(GMT-05:00) Bogota, Lima, Quito</option>
                        <option value="14">(GMT-05:00-1) Eastern Time</option>
                        <option value="15">(GMT-05:00-2) Indiana</option>
                        <option value="16">(GMT-04:00) Atlantic Time</option>
                        <option value="17">(GMT-04:00-1) Caracas, La Paz</option>
                        <option value="18">(GMT-04:00-2) Santiago</option>
                        <option value="19">(GMT-03:30) Newfoundland</option>
                    </select>
                </div>
            </div>
        </div>
    </form>

        未引入插件时,页面效果如下图所示:

        引入插件js和样式:

 <script src="select.js"></script>
 <link rel="stylesheet" href="select.css">

        引入插件后,页面效果如下图:

        主要变化是整个下拉框使用边框包裹,下拉框展开和收起状态右侧箭头方向改变,选项列表设置了最高高度,超过高度出现滚动条,选中的选项自定背景色展示。

2、实现步骤

        首先在页面加载事件处理方法中添加方法进行下拉框的渲染动作:

    win.addListener(win, 'load', function () {
        renderSelects();
    });

        再来看 renderSelects()方法:

    win.renderSelects = function (className) {
        var selectList;
        if (typeof className != "string" || className.trim().length == 0) {
            selectList = document.querySelectorAll('select');
        } else {
            selectList = document.getElementsByClassName(className);
        }
        for (var i = 0; i < selectList.length; i++) {
            renderOneSelect(selectList[i]);
        }
    }

        此方法主要将页面中的下拉框通过选择器选取出来,再循坏调用单个的渲染方法进行渲染。此方法可以传入下拉框的样式类名,传入后选择器匹配的下拉框才会进行自定义样式渲染,未传入参数时页面内全部的下拉框都会进行渲染。

        再看单个下拉框的渲染 renderOneSelect(el),这里的el是单个的下拉框元素。先添加一个临时的段落元素pTemp,然后用此段落元素,与下拉框进行替换,占住下拉框原来的位子,等待div构造的下拉框结构拼接好后再将pTemp替换掉:

 renderOneSelect(el){
     var pTemp = document.createElement("p");
     el.replaceWith(pTemp);
     
     var divSelect = document.createElement("div"); //div构造的下拉框结构
     // ... 一系列构造过程
     
     pTemp.replaceWith(divSelect); //用构造好的div替换掉 pTemp
 } 

        用div构造的下拉框实际的元素结构如下图所示:

        整个下拉框用div.div-select包裹,原有下拉框select元素放到div.div-select内,其后添加div.div-options,div.div-options内部包含了两个div,第一个div.div-selected,用于展示下拉框当前选中的选项,第二个用于展示所有的下拉框选项,单个选项用div.div-option展示,当前选中的选项添加 option-selected 样式,与其他选项区别展示。选项的内容使用span元素包裹展示,用于控制长度,超过长度出现省略号,添加title,当鼠标悬停时展示完整的选项内容。

        div元素构造好之后就是给各元素添加事件处理了。

        div.div-select添加click事件处理,点击时进行选项列表的展开和收起操作:

   selectClick = function (el) {
        if (el.hasClass("select-open")) {
            el.removeClass("select-open")
        } else {
            el.addClass("select-open");
        }
    }

        div.div-select添加blur事件处理,失去焦点时收起选项列表:

    selectBlur = function (el) {
        if (el.hasClass("select-open")) {
            el.removeClass("select-open")
        }
    }

        div.div-option添加click事件处理,点击时选中该选项,同步设置原有select选项的选中状态,设置原有select的selectIndex,调用原有select的onchange方法:

 optionClick = function (el) {
        var _value = el.get("value");
        var select = el.parentElement.parentElement.parentElement.children[0];
        var originIndex = select.selectedIndex;
        var optionLength = select.children.length;
        for (var i = 0; i < optionLength; i++) {
            if (select.children[i].get("value") == _value) {
                select.children[i].set("selected", "");
            } else {
                select.children[i].remove("selected");
            }
        }
        var selected = el.parentElement.parentElement.children[0];
        selected.innerHTML = el.innerHTML;
        var newIndex = 0;
        for (var i = 0; i < el.parentElement.children.length; i++) {
            var tempEl = el.parentElement.children[i];
            tempEl.removeClass("option-selected");
            if (tempEl.get("value") == _value && tempEl.innerHTML == el.innerHTML) {
                newIndex = i;
            }
        }
        el.addClass("option-selected");

        //设置下拉框 selectedIndex 并触发onchange事件
        if (originIndex != newIndex) {
            select.selectedIndex = newIndex;
            eval(select.get("onchange"));
        }

3、其他问题

        实际项目中,个别页面个别select的选中状态是通过js设置selectedIndex指定的,渲染代码不能通过option的selected参数获取选中状态,就不能正确的渲染选中状态,此时需要在下拉框完成渲染后,调用一个根据selectedIndex渲染选中状态的方法:

   HTMLElement.prototype.renderSelected = function () {
        var ele = this;
        if (this.nodeName == "SELECT") {
            var index = ele.selectedIndex;
            var divOptions = ele.parentElement.children[1];
            if (!!divOptions && divOptions.nodeName == "DIV" && divOptions.hasClass("div-options") && index >= 0) {
                divOptions.children[0].innerHTML = divOptions.children[1].children[index].innerHTML;
                divOptions.children[1].children[index].addClass("option-selected");
            }
        }
    };

        还有的页面,下拉框的选项列表是通过异步方法动态获取的,在页面onload方法中执行渲染时,选项列表还是空的,渲染完成后可能选项列表才获取到,这种情况就只能手动的在异步方法完成后调用渲染方法。

        代码下载:https://download.csdn.net/download/evanyanglibo/87490754

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/367972.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国内售价仅10元的鸭子滑梯玩具TK卖到20美元,相关视频获400万+播放!

在TikTok上玩具一直是增速极快的一个类目&#xff0c;不同于很多其他品类在疫情期间取得了巨大增长但在疫情后销售大幅下降的现象不同&#xff0c;全球玩具市场继续表现并保持稳定的较高的销售水平。美国市场研究机构NPD的统计&#xff0c;2021年&#xff0c;全球玩具市场的销售…

Spring Bean 生命周期,好像人的一生

简单说说IoC和Bean IoC&#xff0c;控制反转&#xff0c;想必大家都知道&#xff0c;所谓的控制反转&#xff0c;就是把new对象的权利交给容器&#xff0c;所有的对象都被容器控制&#xff0c;这就叫所谓的控制反转。 控制反转 Bean&#xff0c;也不是什么新鲜玩意儿&#xf…

Pycharm远程服务器常见问题

2023年02月23日 问题描述&#xff1a;Pycharm远程服务器跑代码时&#xff0c;不小心把Pycharm关掉了&#xff0c;但服务器代码还在运行&#xff1f; 解决办法&#xff1a;kill进程 先用watch -n 0.5 nvidia_smi查看进程&#xff0c;然后kill -9 <进程> 1、nvidia-smi…

九龙证券|4D毫米波雷达成市场新宠,相关概念股大涨,会贡献多少业绩?

近日&#xff0c;4D毫米波雷达成为A股新宠&#xff0c;相关概念股如经纬恒润&#xff08;688326.SH&#xff09;一周内涨幅接近20%&#xff0c;威孚高科&#xff08;000581.SZ&#xff09;5个买卖日内涨幅超越25%。 有音讯称特斯拉将在3月1日投资者活动日会宣告新款Model 3的全…

适合视力障碍者的Linux

导读有哪些最适合视障用户的 Linux 发行版&#xff1f;让我们一起来看看。 如果有人视力障碍或失明&#xff0c;他们可能会依赖声音提示或其他交互方式&#xff08;如盲文&#xff09;来阅读和交流。 他们怎样才能使用 Linux 发行版&#xff1f; 嗯&#xff0c;一般来说&…

springboot图书进销存销售管理入库信息系统9f27q-java idea

目录 第一章 绪论 5 1.1 研究背景 5 1.2系统研究现状 5 1.3 系统实现的功能 6 1.4系统实现的特点 6 1.5 本文的组织结构 6 第二章开发技术与环境配置 7 2.1 Java语言简介 7 2.2JSP技术 8 2.5 mysql数据库介绍 9 2.6 B/S架构 9 第三章系统分析与设计 11 3.1 可行性分析 11 3.1…

红帽Linux技术-cp命令

cp是一个复制文件或者目录的命令&#xff0c;其作用是将一个或多个文件或目录从源位置复制到目标位置。 格式&#xff1a;cp [选项] 源文件或目录 目标文件或目录 常用选项&#xff1a; -r&#xff1a;复制目录及其子目录下的所有文件和目录&#xff1b; -p&#xff1a;保留…

五、运行时数据区内部结构、JVM中的线程

内存是非常重要的系统资源&#xff0c;是硬盘和cpu的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM内存布局规定了Java在运行过程种内存申请、分配‘、管理的策略&#xff0c;保证了JVM的高效稳定运行&#xff0c;不同的JVM对于内存的划分方式和管理机制…

STM32 OTA应用开发——通过USB实现OTA升级

STM32 OTA应用开发——通过USB实现OTA升级 目录STM32 OTA应用开发——通过USB实现OTA升级前言1 环境搭建2 功能描述3 BootLoader的制作4 APP的制作5 烧录下载配置6 运行测试结束语前言 什么是OTA&#xff1f; 百度百科&#xff1a;空中下载技术&#xff08;Over-the-Air Techn…

Zabbix4.0架构理解-zabbix的工作方式

目录 1.1、zabbix4.0架构图 1.2、zabbix的进程 1、 zabbix server 2、zabbix agent 3、 zabbix proxy 4、 java gateway 5、zabbix get 1.3、zabbix的几种工作方式 1、通过zabbix agent 2、通过zabbix proxy 3、通过 zabbix java gateway 4、其他 1.3、zabbix 数据走…

虹科案例 | Redis企业版数据库:金融行业客户案例解读

传统银行无法提供无缝的全渠道客户体验、无法实时检测欺诈、无法获得业务洞察力、用户体验感较差、品牌声誉受损和业务损失&#xff1f;Redis企业版数据库具有低延迟、高吞吐和可用性性能&#xff0c;实施Redis企业版数据库&#xff0c;可以使金融机构实现即时的客户体验、实现…

python+django篮球NBA周边商城vue

目 录 第一章 绪 论 1 1.1背景及意义 1 1.2国内外研究概况 1 1.3 研究的内容 1 第二章 关键技术的研究 3 2.1 vue技术介绍 3 myproject/ <-- 高级别的文件夹 |-- myproject/ <-- Django项目文件夹 | |-- myproje…

分阶段构建golang运行环境Dockerfile镜像

在开始这项工作之前大家可以先去看一下docker官方给出关于空镜像scratch的说明&#xff0c;采用官方简单的一句话就是&#xff1a;scratch是一个明确的空图像&#xff0c;特别是对于“从头开始”构建图像。分阶段构建镜像就会用到scratch这个空镜像&#xff0c;这样的好处是可以…

pnpm / yarn / npm管理依赖包

pnpm pnpm官网&#xff1a;https://pnpm.io/zh/ pnpm安装方式有很多&#xff0c;详见官网。 用最简单的npm来安装pnpm&#xff1a;npm install -g pnpm pnpm安装依赖包 pnpm install # 安装所有项目中的依赖包 pnpm install vue # 安装依赖到dependencies pnpm in…

硬件系统工程师宝典(11)-----去耦电容布局“有讲究”

各位同学大家好&#xff0c;欢迎继续做客电子工程学习圈&#xff0c;今天我们继续来讲这本书&#xff0c;硬件系统工程师宝典。 上篇我们说到在电源完整性分析的目标就是要做到电源的干净、稳定和快速响应&#xff0c;以及针对不同噪声处理的实现方法。今天我们来看看去耦电容…

JS词法环境和执行上下文

前言 JavaScript是一门解释性动态语言&#xff0c;但同时它也是一门充满神秘感的语言。如果要成为一名优秀的JS开发者&#xff0c;那么对JavaScript程序的内部执行原理要有所了解。 本文以最新的ECMA规范中的第八章节为基础&#xff0c;理清JavaScript的词法环境和执行上下文…

嵌入式常问问题和知识

12、并发和并行的区别&#xff1f; 最本质的区别就是&#xff1a;并发是轮流处理多个任务&#xff0c;并行是同时处理多个任务。 你吃饭吃到一半&#xff0c;电话来了&#xff0c;你一直到吃完了以后才去接&#xff0c;这就说明你不支持并发也不支持并行。 你吃饭吃到一半&…

【ROS学习笔记2】使用vscode开发ROS全流程

【ROS学习笔记2】使用vscode开发ROS全流程 写在前面&#xff0c;本系列笔记参考的是AutoLabor的教程&#xff0c;具体项目地址在 这里 文章目录【ROS学习笔记2】使用vscode开发ROS全流程一、安装终端工具Terminator二、安装VsCode及插件三、使用VsCode开发全流程1、创建工作空…

亚马逊短期疲软,但长期前景乐观

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 由于投资者对亚马逊(AMZN)前景的担忧&#xff0c;导致该公司的股价在过去一年中下跌了39%。然而猛兽财经认为亚马逊近期面临的不利因素只是暂时的&#xff0c;该公司还是有充分的条件可以在医疗保健和物流领域获得重大增长机…

ACM 记忆化搜索

一.记忆化搜索概述 1.概念 搜索是一种简单有效但是效率又很低下的算法结构&#xff0c;其低效的原因主要在于存在很多重叠子问题。而记忆化搜索则是在搜索的基础上&#xff0c;利用数组来记录已经计算出来的重叠子问题状态&#xff0c;进行合理化的剪枝&#xff0c;从而降低时…