原生JavaScript+Css模拟Select下拉框,美化
发布日期:2022-02-22 16:04:52 浏览次数:14 分类:技术文章

本文共 5508 字,大约阅读时间需要 18 分钟。

原生JavaScript+Css模拟Select下拉框

前言

各位FEer,你们好! 在我们的前端开发生涯中,有着许许多多的细枝末节,有的需要兼容低版本ie浏览器,有的是因为需要有更好的用户体验。最近呢,我们公司要为产品中心设计一个官方推广网站,其中的Select下拉框就因为设计师的交互靠原生不能很好的实现,以及效果,所以我就对Select进行了模拟的实现,一起来看看吧。

实现细节

涉及到的技术

考虑到兼容型以及最轻量化,我们就没有引用Jquery等,使用原生Javascript和Css来实现select的模拟。

效果展示

这个是初始状态
打开状态
选项滑过状态
打开已经选中的,滑过其他选项
已经选择完毕的闭合状态
arrow-up
arrow-down

代码展示

Html结构

   
    


   北京市
   上海市
   天津市
   重庆市
   河北省
   河南省
   江苏省
   云南省
  

Css结构

/* 公共样式 */
*,
body {
  padding: 0;
  margin: 0;
  list-style: none;
  font-size: 14px;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
.hide {
  display: none;
}
/* 模拟下拉框 */
.select-box {
  position: relative;
  margin: 50px 0 0 100px;
}
.select-box .select-input {
  line-height: 20px;
  border: 1px solid #d6d6d6;
  cursor: pointer;
  width: 170px;
  height: 50px;
  border: 1px solid transparent;
  outline: none;
  border-radius: 30px;
  -webkit-border-radius: 30px;
  -moz-border-radius: 30px;
  text-indent: 30px;
  font-size: 16px;
  font-weight: 400;
  /* color: rgba(187, 187, 187, 1); */
  color: rgba(34, 34, 34, 1);
  line-height: 22px;
  margin: 0;
  background: rgba(247, 247, 247, 1) url('./static/imgs/arrow-down.png') no-repeat scroll 130px center;
  background-size: 20px 20px;
  cursor: pointer;
  box-sizing: border-box;
}
/** input placeholder颜色改变 **/
.select-box .select-input::-webkit-input-placeholder {
  /* WebKit browsers */
  color: rgba(187, 187, 187, 1);
}
.select-box .select-input:-moz-placeholder {
  /* Mozilla Firefox 4 to 18 */
  color: rgba(187, 187, 187, 1);
}
.select-box .select-input::-moz-placeholder {
  /* Mozilla Firefox 19+ */
  color: rgba(187, 187, 187, 1);
}
.select-box .select-input:-ms-input-placeholder {
  /* Internet Explorer 10+ */
  color: rgba(187, 187, 187, 1);
}
.select-box .select-input.isActive {
  background-color: #ffffff;
  border: 1px solid rgba(204, 204, 204, 1);
  background-image: url(./static/imgs/arrow-up.png);
}
.select-box .options-box {
  position: absolute;
  top: 55px;
  left: 0;
  width: 170px;
  overflow-y: scroll;
  overflow-x: hidden;
  width: 170px;
  height: 225px;
  background: rgba(255, 255, 255, 1);
  box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.25);
  border-radius: 5px;
}
.select-box .options-box li {
  width: 170px;
  height: 45px;
  text-indent: 30px;
  cursor: pointer;
  font-size: 16px;
  font-weight: 400;
  color: rgba(34, 34, 34, 1);
  line-height: 45px;
  background: rgba(255, 255, 255, 1);
}
.select-box .options-box li.active {
  background-color: rgba(247, 247, 247, 1);
  color: rgba(2, 176, 159, 1)
}

JavaScript结构

window.onload = function () {
// 判断是否有某个class
function hasClass(ele, cls) {
  return ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
}
// //为指定的dom元素添加样式
function addClass(ele, cls) {
  if (!hasClass(ele, cls)) ele.className += " " + cls;
}
// //删除指定dom元素的样式
function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
ele.className = ele.className.replace(reg, " ");
  }
}
// //如果存在(不存在),就删除(添加)一个样式
// function toggleClass(ele, cls) {
//   if (hasClass(ele, cls)) {
//
 removeClass(ele, cls);
//   } else {
//
 addClass(ele, cls);
//   }
// }
document.getElementsByClassName('select-input')[0].onclick = function () {
  var optionsBox = document.getElementsByClassName('options-box')[0];
  var selectInput = document.getElementsByClassName('select-input')[0];
  // 这里最好用children,不要用childNode, 否则会有多余的text节点
  var lis = optionsBox.children;
  if (hasClass(optionsBox, 'hide')) { // 如果当前不是正在打开选项状态
removeClass(optionsBox, 'hide')
addClass(selectInput, 'isActive')
for (var i = 0; i < lis.length; i++) {
  if (lis[i].innerHTML == selectInput.value) { // 如果之前已经选择过,将之前的选项激活状态
addClass(lis[i], 'active')
  } else {
removeClass(lis[i], 'active')
  }
}
  } else {
addClass(optionsBox, 'hide');
removeClass(selectInput, 'isActive');
  }
}
document.getElementsByClassName('options-box')[0].onclick = function (e) {
  var optionsBox = document.getElementsByClassName('options-box')[0];
  var selectInput = document.getElementsByClassName('select-input')[0];
  //这一行及下一行是为兼容IE8及以下版本
  e = e || window.event;
  var target = e.target || e.srcElement;
  if (target.tagName.toLowerCase() === "li") {
  
// 将选中的值赋值给展示框文本
selectInput.value = target.innerHTML;
// 关闭选择列表
addClass(optionsBox, 'hide');
// 取消展示框的激活状态
removeClass(selectInput, 'isActive');
  }
}
// 列表中选项滑过效果
document.getElementsByClassName('options-box')[0].onmouseover = function (e) {
// 事件代理
  var optionsBox = document.getElementsByClassName('options-box')[0];
  var selectInput = document.getElementsByClassName('select-input')[0];
  e = e || window.event;
  var target = e.target || e.srcElement;
  if (target.tagName.toLowerCase() === "li") {
if (target.innerHTML != selectInput.value) { //如果滑过的不是已经选中的,给予暂时的滑过效果
  addClass(target, 'active');
}
  }
}
document.getElementsByClassName('options-box')[0].onmouseout = function (e) {
  var optionsBox = document.getElementsByClassName('options-box')[0];
  var selectInput = document.getElementsByClassName('select-input')[0];
  //这一行及下一行是为兼容IE8及以下版本
  e = e || window.event;
  var target = e.target || e.srcElement;
  if (target.tagName.toLowerCase() === "li") {
if (target.innerHTML != selectInput.value) { // 如果滑出的不是已经选中的,将滑过的效果取消
  removeClass(target, 'active');
}
  }
}  }

总结

用原生JavsScript去实现效果的时候,可能有时候会比较麻烦,但是这是根本,其他的框架也好,第三方插件也罢,其实都可以理解为基于它而衍生的语法糖或者简化调用的集合。所谓万变不离其宗,谢谢各位同学,如果这篇文章对您有用的话,麻烦记得点赞收藏哦!😄

转载地址:https://blog.csdn.net/cynthia101/article/details/104048276 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Mac配置GitLab和GitHub账户
下一篇:MongoDB数据库学习

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.191.171.8]2022年10月12日 20时39分39秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

最新文章

PyHive(遇到的坑)以及一些ETl使用函数 2019-12-25 02:37:34
使用Python将MongoDB数据同步到Elasticsearch 2019-12-25 02:37:34
PyMongo2Es常见问题汇总 2019-12-25 02:37:34
利用 cv2 给图片添加文字 2019-12-25 02:37:32
不同优化器对损失下降过程的影响(无解析,仅用于记录) 2019-12-25 02:37:32
UML类图中箭头和线条的含义和用法 2019-12-25 02:37:32
归并排序 2019-12-25 02:37:32
一 Apache NiFi 2019-12-25 02:37:32
二 NIFI环境搭建-单机 2019-12-25 02:37:33
正则表达式 2019-12-25 02:37:30
Python 操作文件 2019-12-25 02:37:31
How to address the overfitting 2019-12-25 02:37:31
机器学习 话题模型 2019-12-25 02:37:31
移动链表最大元素 2019-12-25 02:37:31
打印叶节点到根的路径 2019-12-25 02:37:31
《统计学习方法》提升方法 2019-12-25 02:37:31
[maven学习笔记(九)] 使用 eclipse 的 maven 插件 2019-12-25 02:37:29
demo 2019-12-25 02:37:29
git 命令 2019-12-25 02:37:29
Linux权限管理 2019-12-25 02:37:29