使悬停从最左边到最右边的星星有什么技巧? 诸如
flex-direction: row-reverse;
和 direction: rtl;
之类的东西不算数,因为它们也颠倒了星星的顺序。因为我们找不到一种方法来反转循环从 5 到 1,所以我们需要另一个解决方案。
.rating-container input[type="radio"] {
display: none;
}
.rating-container label {
display: inline-block;
cursor: pointer;
}
.rating-container svg {
fill: #ccc;
}
.rating-container input[type="radio"]:checked ~ label svg,
.rating-container label:hover ~ label svg,
.rating-container label:hover svg {
fill: #000;
}
<div id="rating-rate" class="rating-container" name="revrating">
<input type="radio" id="rating1" name="revrating" value="1">
<label for="rating1"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating2" name="revrating" value="2">
<label for="rating2"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating3" name="revrating" value="3">
<label for="rating3"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating4" name="revrating" value="4">
<label for="rating4"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating5" name="revrating" value="5">
<label for="rating5"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span></div>
循环生成HTML:
<div id="rating-rate" class="rating-container" name="revrating">
{{#for 1 5}}
{{#if ../product.reviews.selected_rating '===' $index}}
<input type="radio" id="rating{{$index}}" value="{{$index}}" checked />
<label for="rating{{$index}}"><svg class="star-icon" aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
{{else}}
<input type="radio" id="rating{{$index}}" name="revrating" value="{{$index}}" />
<label for="rating{{$index}}"><svg class="star-icon" aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
{{/if}}
{{/for}}
</div>
您尝试过 :has 运算符吗?有点新,但允许这种选择。它允许您选择具有特定特征的每个元素,在您的情况下,所有星星都具有稍后的兄弟姐妹:hover。 这段代码应该可以解决问题
label:has(~:hover)>svg,
label:hover>svg{
fill: #000;
}
$(document).ready(function() {
$('#rating-rate span').on('click', function(){
$('#rating-rate span').removeClass('active');
var stars = $(this).find('input').val();
for (i = 1; i <= stars; i++) {
$('#rating'+i).parent().addClass('active');
}
});
});
.rating-container input[type="radio"] {
display: none;
}
.rating-container label {
display: inline-block;
cursor: pointer;
}
.rating-container svg {
fill: #ccc;
}
span:has(~:hover) > label svg{
fill: #000;
}
span:hover label svg{
fill: #000;
}
#rating-rate span.active label svg {
fill: #000;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="rating-rate" class="rating-container" name="revrating">
<span>
<input type="radio" id="rating1" name="revrating" value="1">
<label for="rating1"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
</span>
<span>
<input type="radio" id="rating2" name="revrating" value="2">
<label for="rating2"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
</span>
<span>
<input type="radio" id="rating3" name="revrating" value="3">
<label for="rating3"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
</span>
<span>
<input type="radio" id="rating4" name="revrating" value="4">
<label for="rating4"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
</span>
<span>
<input type="radio" id="rating5" name="revrating" value="5">
<label for="rating5"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
</span>
<span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span></div>
您可以使用
direction: rtl;
,但您需要反转无线电值,因此第一个是5
,直到1
是最后一个
// For testing only (To see the selected value)
setInterval(() => { console.log(document.querySelector('input[name="revrating"]:checked')?.value)
}, 1000)
.rating-container {
direction: rtl;
width: fit-content;
}
.rating-container input[type="radio"] {
display: none;
}
.rating-container label {
display: inline-block;
cursor: pointer;
}
.rating-container svg {
fill: #ccc;
}
.rating-container input[type="radio"]:checked~label svg,
.rating-container label:hover~label svg,
.rating-container label:hover svg {
fill: #000;
}
<div id="rating-rate" class="rating-container" name="revrating">
<input type="radio" id="rating5" name="revrating" value="5">
<label for="rating5"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating4" name="revrating" value="4">
<label for="rating4"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating3" name="revrating" value="3">
<label for="rating3"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating2" name="revrating" value="2">
<label for="rating2"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating1" name="revrating" value="1">
<label for="rating1"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span></div>
以下是我们如何解决错误悬停和选择方向问题的方法。
(CSS解决方案由Giuliano Gostinfini和Mitali Patel提供,谢谢)
$(document).ready(function() {
$('.rating-container input[type="radio"]').change(function() {
var selectedRating = $(this).val();
$('.rating-container label svg').each(function(index) {
if (index < selectedRating) {
$(this).css('fill', '#000');
} else {
$(this).css('fill', '#ccc');
}
});
});
});
.rating-container input[type="radio"] {
display: none;
}
.rating-container label {
display: inline-block;
cursor: pointer;
}
.rating-container svg {
fill: #ccc;
}
label:has(~:hover) > svg, label:hover > svg {
fill: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="rating-rate" class="rating-container" name="revrating">
<input type="radio" id="rating1" name="revrating" value="1">
<label for="rating1"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating2" name="revrating" value="2">
<label for="rating2"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating3" name="revrating" value="3">
<label for="rating3"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating4" name="revrating" value="4">
<label for="rating4"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input type="radio" id="rating5" name="revrating" value="5">
<label for="rating5"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span><span style="display: none;"></span></div>
将
<input>
、<label>
和<svg>
的容器设为 Flex 容器,然后通过添加以下 CSS 来反转其方向:
.rating-container {
display: flex;
flex-flow: row-reverse nowrap;
justify-content: flex-end;
}
接下来,反转每个
<input>
上的值的顺序:
<input ... value="5">
<input ... value="4">
<input ... value="3">
<input ... value="2">
<input ... value="1">
如果无法更改 HTML,只需在页面加载后以编程方式分配值即可:
// Plain JavaScript
document.querySelectorAll("[type='radio]").forEach((r, i, a) => {
r.value = a.length - i;
});
// OR
// jQuery
$(":radio").each(function(i) {
let size = $(":radio").length;
$(this).val(size - i);
});
在下面的示例中,容器是
<form id="rating">
,为简单起见,名称略有更改,但 HTML 布局没有变化。添加了一些 JavaScript 来演示当用户选择星星时会分配正确的值。
此示例将把检查的值提交到实时测试服务器。
路线
// For demonstration purposes
const main = document.forms.rating;
main.onchange = e => console.log(e.target.value);
Array.from(main.elements.rating).forEach((r, i, a) => r.value = a.length - i);
/* This version will work specifically for OP code */
// document.querySelectorAll("[type='radio']").forEach((r, i, a) => r.value = a.length - i);
/* This is a jQuery version of the previous line */
/*
$(":radio").each(function(i) {
let size = $(":radio").length;
$(this).val(size - i);
});
*/
#rating {
display: flex;
flex-flow: row-reverse nowrap;
justify-content: flex-end;
}
[name="rating"] {
display: none;
}
label {
display: inline-block;
cursor: pointer;
}
svg {
fill: #ccc;
}
[name="rating"]:checked~label svg,
label:hover~label svg,
label:hover svg {
fill: #000;
}
/* All of the proceeding CSS is for demonstration purposes */
button {
margin-left: 24px;
cursor: pointer;
}
iframe {
display: block;
width: 100%;
margin-top: 12px;
}
.as-console-row::after {
width: 0;
font-size: 0;
}
.as-console-row-code {
width: 100%;
word-break: break-word;
}
<!-- Attributes "action", "method", and "target" are for
demonstration purposes -->
<form id="rating" action="https://httpbin.org/post" method="post" target="response">
<!-- button is for demonstration purposes -->
<button>Send</button>
<input id="rating1" name="rating" type="radio" value="1">
<label for="rating1"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input id="rating2" name="rating" type="radio" value="2">
<label for="rating2"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input id="rating3" name="rating" type="radio" value="3">
<label for="rating3"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input id="rating4" name="rating" type="radio" value="4">
<label for="rating4"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
<input id="rating5" name="rating" type="radio" value="5">
<label for="rating5"><svg aria-hidden="true" focusable="false" viewBox="1.697 1.992 11.58 11" role="img" width="24px" height="24px"><path d="M13.277 6.182 9.697 8.782 11.057 12.992 7.487 10.392 3.907 12.992 5.277 8.782 1.697 6.182 6.117 6.182 7.487 1.992 8.857 6.182 13.277 6.182Z"></path></svg></label>
</form>
<!-- iframe is for demostration purposes -->
<iframe name="response"></iframe>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>