像rate
評分元件一般都用javascript
寫,大概一年前,我在簡書寫過一篇文章原生Javascript實現星星評分元件,感興趣的可以去看一下,很久之前寫的,我不知道之前的程式碼有多囉嗦,所以這次將是一個全新的嘗試,用css
實現一個rate
評分 ❗ 核心程式碼也就三行?
效果圖
原理
梳理如下:
- 去找個好看的
iconfont
,Iconfont-阿里巴巴向量圖示庫; - 借用5個
radio
單選框,把預設樣式都去掉,顯示預設的星星; - 用
checked
偽類監聽使用者選中✅,由預設的星星變成高亮的星星; - 然後配合
~
兄弟操作符把當前選中的所有兄弟元素都一起高亮?; - 把5個
radio
單選框反向排列 ❗;
程式碼
這是我事先生成好的iconfont
<link rel="stylesheet" href="//at.alicdn.com/t/font_1356455_c5d3d3ohlbq.css">
複製程式碼
一個很簡潔的佈局:
<div class="rate-content">
<input type="radio" name="rate">
<input type="radio" name="rate">
<input type="radio" name="rate">
<input type="radio" name="rate">
<input type="radio" name="rate">
</div>
複製程式碼
先把預設的星星顯示出來:
// 去掉預設樣式
input {
-webkit-appearance: none;
border: none;
outline: none;
cursor: pointer;
}
.rate-content {
$main: #ffa822; // 高亮顏色
$basic: #999; // 預設顏色
// 單個星星
input[name="rate"] {
font-family: "iconfont"; // 之前引入的iconfont字型
font-size: 30px;
padding-right: 10px;
// 預設顯示的星星
&::after {
content: "\e645";
color: $basic;
transition: color .4s ease; // 加點顏色過渡效果
}
}
}
複製程式碼
效果如下:
實現選中單個星星:
input[name="rate"] {
// 高亮的星星
&:checked {
&::after {
content: "\e73c";
color: $main;
}
}
}
複製程式碼
效果如下:
實現連同兄弟元素一起高亮:
input[name="rate"] {
// 高亮的星星
&:checked,
&:checked ~ input[name="rate"] {
...
}
}
複製程式碼
效果如下:
然後把input
反向排列:
.rate-content {
display: flex;
flex-flow: row-reverse;
}
複製程式碼
效果如下:
滑鼠移入預覽選中效果:
羅嗦版:
input[name="rate"] {
// 高亮的星星
&:checked,
&:checked ~ input[name="rate"],
&:hover,
&:hover ~ input[name="rate"] {
...
}
}
複製程式碼
優化版:
input[name="rate"] {
// 高亮的星星
&:checked,
&:hover {
&::after {
content: "\e73c";
color: $main;
}
// 兄弟元素一起高亮
& ~ input[name="rate"] {
&::after {
content: "\e73c";
color: $main;
}
}
}
}
複製程式碼
效果如下:
加入放大動畫
input[name="rate"] {
transition: transform .2s ease; // 加入過渡效果
// 高亮的星星
&:checked,
&:hover {
...
}
// 滑鼠移入使星星放大
&:hover {
transform: scale(1.2);
}
}
複製程式碼
效果如下:
總結
核心程式碼其實就是這兩段,其他都是可選的?
元素反向排列:
display: flex;
flex-flow: row-reverse;
複製程式碼
兄弟元素操作:
input:checked ~ input
複製程式碼
如果不用flex
反向排列,還可以用rotateZ
:
.rate-content {
display: flex;
// flex-flow: row-reverse;
transform: rotateZ(180deg);
}
複製程式碼
效果如下:
z軸旋轉180deg
之後發現星星的頭跟尾巴反過來了,那麼子元素也旋轉180deg
即可:
.rate-content {
input[name="rate"] {
transform: rotateZ(180deg);
// 滑鼠移入使星星放大
&:hover {
transform: scale(1.2) rotateZ(180deg);
}
}
}
複製程式碼
效果如下:
需要注意的細節
input[name="rate"] {
// padding-right: 10px;
margin-right: 10px;
}
複製程式碼
如果用外邊距的話,那麼會出現以下情形:
內邊距的作用是保持元素連貫性以及擴大點選範圍;
最後附上本文程式碼的codepen
地址:css實現rate評分;
關於如何獲取分數
原生javascript
獲取也很簡單,不過你得先給五個input
增加value
或自定義索引值:
<input type="radio" name="rate" value="1">
<input type="radio" name="rate" value="2">
<input type="radio" name="rate" value="3">
<input type="radio" name="rate" value="4">
<input type="radio" name="rate" value="5">
複製程式碼
假設最大分數為5:
const getScore = () => {
let checkedInput = document.querySelector("input[name=rate]:checked"); // 獲取當前選中的input
// 沒選中的時候checkedInput為null,直接返回0
retrun checkedInput? 5 - Number(checkInput.value) + 1: 0;
}
複製程式碼
為什麼要相減,因為元素是倒序排列的,選中第一個實際上選中的是第五個?
關於如何實現半星星
提供一下思路,十個input
,奇數顯示星星左邊、偶數顯示星星右邊,其他邏輯不改;
最後
如果你覺得這篇文章不錯,請別忘記點個贊
跟關注
哦~?