开发者

Help needed in 5 star rating - Jquery

开发者 https://www.devze.com 2023-01-28 15:58 出处:网络
I\'m trying to build a star-rating system. The code that I have now does the following : Highlight stars when mouse hovers over it, but revert back to previous state when mouse is removed.

I'm trying to build a star-rating system. The code that I have now does the following :

Highlight stars when mouse hovers over it, but revert back to previous state when mouse is removed.

I want to add the following functionality to it : When I click on a star ,the number of stars I clicked should remain highlighted even after removing the mouse from the stars.

Can anyone please help me on this ?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd"
    >
<html lang="en">
<head>
    <title>AJAX 5 Star Rating</title>

    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script>

    // This is the first thing we add ------------------------------------------
    $(document).ready(function() {

        $('.rate_widget').each(function(i) {
            var widget = this;
            var out_data = {
                widget_id : $(widget).attr('id'),
                fetch: 1
            };
            $.post(
                'ratings.php',
                out_data,
                function(INFO) {
                    $(widget).data( 'fsr', INFO );
                    set_votes(widget);
                },
                'json'
            );
        });


        $('.ratings_stars').hover(
            // Handles the mouseover
            function() {
                $(this).prevAll().andSelf().addClass('ratings_over');
                $(this).nextAll().removeClass('ratings_vote'); 
            },
            // Handles the mouseout
            function() {
                $(this).prevAll().andSelf().removeClass('ratings_over');
                // can't use 'this' because it wont contain the updated data
                set_votes($(this).parent());
            }
        );


        // This actually records the vote
        $('.ratings_stars').bind('click', function() {
            var star = this;
            var widget = $(this).parent();

            var clicked_data = {
                clicked_on : $(star).attr('class'),
                widget_id : $(star).parent().attr('id')
            };
            $.post(
                'ratings.php',
                clicked_data,
                function(INFO) {
                    widget.data( 'fsr', INFO );
                    set_votes(widget);
                },
                'json'
            ); 
        });



    });

    function set_votes(widget) {

        var avg = $(widget).data('fsr').whole_avg;
        var votes = $(widget).data('fsr').number_votes;
        var exact = $(widget).data('fsr').dec_avg;

        window.console && console.log('and now in set_votes, it thinks the fsr is ' + $(widget).data('fsr').number_votes);

        $(widget).find('.star_' + avg).prevAll().andSelf().addClass('ratings_vote');
        $(widget).find('.star_' + avg).nextAll().removeClass('ratings_vote'); 
        $(widget).find('.total_votes').text( votes + ' votes recorded (' + exact + ' rating)' );
    }
    // END FIRST THING








    </script>

    <style>
        .rate_widget {
            border:     1px solid #CCC;
            overflow:   visible;
            padding:    10px;
            position:   relative;
            width:      180px;
            height:     32px;
        }
        .ratings_stars {
            background: url('star_empty.png') no-repeat;
            float:      left;
            height:     28px;
            padding:    2px;
            width:      32px;
        }
        .ratings_vote {
            background: url('star_full.png') no-repeat;
        }
        .ratings_over {
            background: url('star_highlight.png') no-repeat;
        }
        .total_votes {
            background: #eaeaea;
            top: 58px;
            left: 0;
            padding: 5px;
            position:   absolute;  
        } 
        .event_choice {
            font: 10px verdana, sans-serif;
            margin: 0 开发者_运维知识库auto 40px auto;
            width: 180px;
        }
        h1 {
            text-align: center;
            width: 400px;
            margin: 20px auto;
        }
    </style>
</head>
<body>
<h1> Rate the event! </h1>
<div class='event_choice'>
    Rate: Raiders of the Lost Ark
    <div id="r1" class="rate_widget">
        <div class="star_1 ratings_stars"></div>
        <div class="star_2 ratings_stars"></div>
        <div class="star_3 ratings_stars"></div>
        <div class="star_4 ratings_stars"></div>
        <div class="star_5 ratings_stars"></div>
        <div class="total_votes">vote data</div>
    </div>
</div>

<div class='event_choice'>
    Rate: The Hunt for Red October
    <div id="r2" class="rate_widget">
        <div class="star_1 ratings_stars"></div>
        <div class="star_2 ratings_stars"></div>
        <div class="star_3 ratings_stars"></div>
        <div class="star_4 ratings_stars"></div>
        <div class="star_5 ratings_stars"></div>
        <div class="total_votes">vote data</div>
    </div>
</div>
</body>
</html>


I found a great CSS only way of doing the hover effects. The keeping the stars highlighted will still require some javascript, but much less.

The general idea is that you have a background image (the star) for the ul with a set length (in your case, 5 time the width of the image, for 5 stars) and repeat the image across the x-axis (background: url(star.gif) repeat-x;). Each <a> is set to different widths (20%, 40%, 60%, 80%, 100%, for the 5 stars) and is put on a different z-index.

Here's an update of the author's idea that's a little closer to your use case:

HTML:

<div class='rate_widget'>
    <ul>
        <li><a href='#' class='one-star'>1</a></li>
        <li><a href='#' class='two-stars'>2</a></li>
        <li><a href='#' class='three-stars'>3</a></li>
        <li><a href='#' class='four-stars'>4</a></li>
        <li><a href='#' class='five-stars'>5</a></li>
    </ul>
</div>

CSS:

.rate_widget ul{
    background: url(star_empty.png) repeat-x;
}

.rate_widget a:hover{
    background: url(star_highlight.png) repeat-x;
}

.rate_widget a:active,
.rate_widget a:focus,
.rate_widget a.checked{
    background: url(star_full.png) repeat-x;
}

.rate_widget ul{
    position:relative;
    width:125px; /*5 times the width of your star*/
    height:25px; /*height of your star*/
    overflow:hidden;
    list-style:none;
    margin:0;
    padding:0;
    background-position: left top;
}

.rate_widget li{
    display: inline;
}

.rate_widget a{
    position:absolute;
    top:0;
    left:0;
    text-indent:-1000em;
    height:25px; /*height of your star*/
    line-height:25px; /*height of your star*/
    outline:none;
    overflow:hidden;
    border: none;
}

.rate_widget a.one-star{
    width:20%;
    z-index:6;
}

.rate_widget a.two-stars{
    width:40%;
    z-index:5;
}

.rate_widget a.three-stars{
    width:60%;
    z-index:4;
}

.rate_widget a.four-stars{
    width:80%;
    z-index:3;
}

.rate_widget a.five-stars{
    width:100%;
    z-index:2;
}

.rate_widget a.checked{
    z-index:1;
}

Javascript:

$('.rate_widget a').click(function(){
    // make sure the chosen star stays selected
    var star = $(this);
    star.closest('ul').find('.checked').removeClass('checked');
    star.addClass('checked');

    //whatever else you want to do when something gets clicked
});

And here's a fiddle to see it in action: http://www.jsfiddle.net/BHaTu/

0

精彩评论

暂无评论...
验证码 换一张
取 消