寻求jQuery代码优化技巧:实现评分组件HTML结构复用
Hey there! Let's get your rating component fully reusable. Based on the HTML structure you provided, here's a polished, generalized jQuery implementation plus key tips to keep it flexible:
Optimized jQuery Code
This code supports multiple rating instances on the same page, uses your existing class names, and keeps behavior decoupled from hardcoded values:
$(document).ready(function() { // Initialize all rating components on the page $('.rating-container').each(function() { const $container = $(this); const $rating = $container.find('.rating'); const $scoreLabel = $container.find('.hover-score-label'); // Pull configurable values from data attributes (with fallbacks) const maxRating = parseInt($container.data('max-rating')) || 5; let currentRating = parseInt($container.data('initial-rating')) || 0; // Set initial active state if a pre-defined rating exists if (currentRating > 0) { $rating.find(`span:lt(${currentRating})`).addClass('active'); } // Handle hover interactions $rating.on('mouseenter mouseleave mousemove', 'span', function(e) { const isHovering = e.type !== 'mouseleave'; const hoveredIndex = $(this).index() + 1; if (isHovering) { // Show and update the score label $scoreLabel.text(hoveredIndex).removeClass('hide'); // Highlight all items up to the hovered one $rating.find('span').removeClass('active').filter(`:lt(${hoveredIndex})`).addClass('active'); } else { // Hide label and revert to the currently selected rating $scoreLabel.addClass('hide'); $rating.find('span').removeClass('active').filter(`:lt(${currentRating})`).addClass('active'); } }); // Handle click to set a permanent rating $rating.on('click', 'span', function() { currentRating = $(this).index() + 1; $rating.find('span').removeClass('active').filter(`:lt(${currentRating})`).addClass('active'); // Trigger a custom event so parent code can react to rating changes $container.trigger('rating.updated', { value: currentRating }); }); }); });
Key Generalization Tips
Use Data Attributes for Configuration: Extend your HTML to add per-instance settings without modifying JS:
<div class="rating-container" data-max-rating="10" data-initial-rating="4"> <!-- Your rating spans here --> </div>This lets you easily create 5-star, 10-star, or any custom scale ratings, plus pre-fill ratings as needed.
Event Delegation: By binding events to the
.ratingcontainer instead of individual spans, the code works even if you dynamically add rating elements later (e.g., via AJAX).Encapsulate as a jQuery Plugin: For clean, reusable code across projects, wrap the logic into a plugin:
$.fn.rating = function(options) { const defaults = { maxRating: 5, initialRating: 0 }; const settings = $.extend({}, defaults, options); return this.each(function() { // Insert the initialization logic here, using `settings` for configuration }); }; // Usage example: $('.rating-container').rating({ maxRating: 7, initialRating: 2 });Preserve Accessibility: Your existing
sr-onlylegend is perfect for screen readers. Enhance it further by updating the legend text on rating selection, or adding ARIA attributes likearia-selectedto active rating spans.Decouple Styles from Behavior: Keep CSS classes generic (like
activeinstead ofrating-5-active) so the same JS works with any visual styling you apply—from star icons to number badges.
内容的提问来源于stack exchange,提问作者bergJ

