html 用input元素仿制select元素(目的:自定义样式)[初学]

本文介绍如何使用HTML input元素和JavaScript仿制select元素以实现自定义样式。方法一利用背景图和绝对定位,但存在点击事件覆盖问题。方法二采用onblur事件,结合onmouseover和onmouseout解决点击问题,实现更接近目标效果。
摘要由CSDN通过智能技术生成

仿制目标

在这里插入图片描述
目标效果:需要一个下拉按钮的样式(实际不是按钮,可以用背景图来实现),选中之后将内容传给select并聚焦,同时下拉栏消失。鼠标悬停在列表内的元素上有样式变化。

思路:

这个文本框明显可以用input元素text代替,传值用JS也很好解决,为了不让内容可以手动输入可以对文本栏设定一个.setAttribute(“readOnly”, true);。至于下拉栏,用一个ul元素加上绝对定位就可以做到。实现过程中遇到的真正的麻烦是让下拉栏消失。

方法一:

  • 首先做一个div.main来装input,通过定义背景图片让下拉箭头样式固定到正确的位置。
  • 将ul写好,定好li大小,将ul绝对定位到div下方。
  • 再写一个固定定位div.cover,定义div.main的z-index=100;div.cover的z-index=98 display=none width=100%,height=100%;ul的z-index=99。
  • 用JS来控制ul和div.cover的消失和出现,原理都是改变样式中的display。在div.cover的点击事件中让ul消失就好了,至于input的点击事件中的改变ul的逻辑就不赘述了。
  • 这个方法有一个致命的问题,也是和select最大的区别,一旦下拉框被input的点击触发,那么同时出现的还有透明的div.cover,这个覆盖了除了下拉列表以外的几乎整个视窗,虽然可以实现点击其他地方,下拉框消失,但是同时也直接无法点击到其他元素了,必须要先触发div.cover的点击事件中的自我隐藏后,才能点击其他的元素,这和目标效果有明显的差别,看起来像,用起来还是有差别的,所以我想到了方法2。

方法2:

  • 分析:点击其他区域隐藏下拉列表主要就是两种事件的触发,input[type=“text”]的失焦,或者某种元素的点击,方法一用元素的点击显然不尽人意,所以我决定用onblur事件来尝试。
  • 样式部分和方法一一致,主要问题是如何用JS设计逻辑使其能够判断失焦时,鼠标点击的是下拉框以外的位置,这个问题之所以重要是因为我发现如果不加以判断,只要失焦就让下拉列表消失,那么下拉列表的内容就一直点不到,因为在点击时input的失焦事件先触发,ul做的下拉列表就直接隐藏了。
  • 所以我开始尝试设置一个变量来判断ul的内容是否被点击过,但是这种尝试是徒劳的,如果点击过之后执行的语句和未点击过执行的语句是一模一样的,多加一个判断也不能让ul的点击事件优先执行,这里我甚至想为每个事件设置一个优先级,先调用什么,再调用什么,我对JS不太熟悉,显然这种方法不太适合我。
  • 最后我决定用onmouseover和onmouseout事件来解决这个问题,同时也用到了一些DOM冒泡的好处。

代码:

<style>
    * {
    
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    
    div {
    
        position: relative;
        width: 500px;
        height: 35px;
        margin: auto;
    }
    
    input {
    
        width: 500px;
        height: 35px;
        outline: none;
        cursor: default;
        background-image: url("./selectBtn.png");
        background-repeat: no-repeat;
        background-position: 459px -1px;
        border: 1px solid #ddd;
    }
    
    input:focus {
    
        border: 1px solid lightblue;
    }
    
    ul {
    
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值