JQuery plug-in-jRating scoring plug-in source code analysis and usage

Source: Internet
Author: User
Tags vars

This plug-in is widely used in a variety of pages that require scoring. Today, as a learning tool, we will analyze the source code and learn how to use it by the way.
I. Agent usage Overview. Copy codeThe Code is as follows: <div>
<Div> first example </div>
<Div id = "16_1" class = "myRating"> </div>
</Div>

Copy codeThe Code is as follows: <link href = "Script/jRating/jRating.jquery.css" rel = "stylesheet" type = "text/css"/>
<Scripts src = "script/jquery-1.7.min.js" type = "text/javascript"> </Script>
<Script src = "Script/jRating. jquery. js" type = "text/javascript"> </script>
<Script type = "text/javascript">
$ (Function (){
$ (". MyRating"). jRating ({
Length: 10
});
});
</Script>

Execution result:

As you can see, in the above example, there are 10 stars, which are used by the length parameter. The default total score is 20, which means that all 10 stars are selected. Here, we pay attention to the id16_1 of <div>, where 16 is used to initialize the default ratio selected by the scoring plug-in, which is 16/20*10. So we have eight stars in yellow.

When we move the mouse over the plug-in, the stars will increase or decrease as the mouse moves (Red will overwrite yellow or white), indicating that the score ranges from 0 to 20, but when you click the mouse, after the score is over, the plug-in cannot be edited any more. At the same time, the plug-in can POST data to the specified path through Ajax, and use background data to make the Score data persistent.

Before analyzing the source code, let's take a look at the optional parameters when using the plug-in:

2. Plug-in source code analysis

According to the recommended method developed by jQuery plug-ins, to avoid conflicts between the "$" symbol and other JavaScript plug-ins, the following technology is used at the beginning of the source code:Copy codeThe Code is as follows: (function ($ ){
$. Fn. jRating = function (op ){
// Here is the plug-in code
}
}) (JQurery)

Next, all the code we analyzed will appear in the green area above. First, set the default parameter.Copy codeThe Code is as follows: var defaults = {
/** String vars **/
BigStarsPath: 'icons'/stars.png ', // sets the relative path of the big star (displayed by default ).
SmallStarsPath: 'icons'/small.png ', // Xiaoxing
PhpPath: 'php/jRating. php', // click the mouse, score the score, and set the POST data address. Next we will use ASP. Net technology for processing.
Type: 'Big ', // you can see that the stars are used by default.
/** Boolean vars **/
Step: false, // if it is set to True, the stars are either completely discolored or not completely changed. Of course, this is also suitable for synchronizing the score.
IsDisabled: false, // if it is set to True, the plug-in cannot be edited. After you click the mouse, the default status is True.
ShowRateInfo: true, // whether to display the selected proportion below the mouse when the mouse is placed on the star, such as 16/20
/** Integer vars **/
Length: 5, // number of stars
DecimalLength: 0, // the decimal place after the selected number, which can be at most three digits. If it is set to 1, it may occur at 16.3/20.
RateMax: 20, // The denominator in the percentage, an integer ranging from 0 to 9999
RateInfosX:-45, // The Coordinate Position of the Information prompt box relative to the mouse position
RateInfosY: 5, // same as above, ordinate position
/** Functions **/
OnSuccess: null, // callback function after successful
OnError: null // error handling function
};

Through the green section above, we can see the default values of all parameters. At the same time, we can determine the appropriate configuration as needed in the plug-in usage, isn't the use of plug-ins a combination of these parameters?
Next, let's look at a function scope:Copy codeThe Code is as follows: if (this. length> 0)
Return this. each (function () {// the code that appears next will be here !!!}

This code is very simple. We need to execute the jRating () function on the selected set. The above code first checks whether the set length is greater than 0. If it is 1 or more, then, the each () function is executed on the set to process each element (div) of the set separately.
The core code of this plug-in is actually in the above each () function. First, let's look at several functions. These functions are defined in the each () function and called by other statements.Copy codeThe Code is as follows: function findRealLeft (obj ){
If (! Obj) return 0;
Return obj. offsetLeft + findRealLeft (obj. offsetParent );
};

First, focus on the findRealLeft () function. This function receives the object parameter named obj and returns the distance between the element object and the left border of the browser. Note: offsetParent refers to the relative (absolute) ancestor element of the element. If no ancestor element is located, it points to the body element. OffsetLeft returns the position relative to offsetParent.Copy codeThe Code is as follows: function getNote (relativeX ){
Var noteBrut = parseFloat (relativeX * 100/widthRatingContainer) * opts. rateMax/100); // whether two 100 values can be removed, indicating the proportion selected, such as 16 or 16.1
Switch (opts. decimalLength) {// determine the decimal places required for the proportion to be deprecated Based on the parameter, for example, 16.1 16.12 16.123
Case 1:
Var note = Math. round (noteBrut * 10)/10;
Break;
Case 2:
Var note = Math. round (noteBrut * 100)/100;
Break;
Case 3:
Var note = Math. round (noteBrut * 1000)/1000;
Break;
Default:
Var note = Math. round (noteBrut * 1)/1;
}
Return note;
};

Next, let's focus on the getNote function. First, let's look at the following relativeX:Copy codeThe Code is as follows: var realOffsetLeft = findRealLeft (this );
Var relativeX = e. pageX-realOffsetLeft;

The above two lines of code define the relativeX variable before calling the getNote function. We can analyze the functions of relativeX. This is a div of the jRating () function. First, obtain the left margin relative to the browser, because the above two lines of code appear in the mouse movement handler mouseenter (we will see later), the e. pageX indicates the horizontal distance between the mouse and the browser. Therefore, relativeX indicates the horizontal distance between the mouse and the Left Border of <div>.
We pay attention to the getNote function again. We can see from widthRatingContainer = starWidth * opts. length that widthRatingContainer is the sum of the Left and Right stars. Therefore, var noteBrut = parseFloat (relativeX * 100/widthRatingContainer) * opts. rateMax/100); you can remove two 100 pairs of denominator and numerator (relativeX/widthRatingContainer) * opts. rateMax), The noteBrut variable finally stores the ratio selected by the mouse. If rateMax is set to 20, the noteBrut range can be determined by the mouse (0-20 ).
The switch function uses the decimalLength parameter (used to set the decimal point of the display ratio) to determine the number of digits displayed. After reading this, we can find that the getNote function returns the ratio selected by the mouse through relativX. What is the ratio? See the section framed with a brush:

Next, let's focus on a function.:Copy codeThe Code is as follows: function getStarWidth (){
Switch (opts. type ){
Case 'small ':
StarWidth = 12; // The width of the small.png star image
StarHeight = 10; // height
BgPath = opts. smallStarsPath; // relative image address
Break;
Default:
StarWidth = 23; // The width of the big star. You can see that this is the default value.
StarHeight = 20; // height
BgPath = opts. bigStarsPath; // relative address of the star image
}
};

This is a simple function used to initialize variables. According to the type attribute, three variables, starWidth, starHeight, and bgPath, are initialized. The green annotation information can describe everything, no more details!
After reading the functions defined in each (), we are still wandering in the each () function. In the order of top to bottom, we first cut several lines of code as follows:Copy codeThe Code is as follows: var opts = $. extend (ults, op), // use the extend () function to merge the default parameters with the input parameters, and store them in the opts variable.
NewWidth = 0, // defines the variable, which is used to store relativeX, but will be adjusted according to the step attribute
StarWidth = 0, // defines the variable, the width of the star
StarHeight = 0, // height
BgPath = ''; // star image address
If ($ (this). hasClass ('jdisabled ') | opts. isDisabled) // determines whether the jDisabled variable can be used to operate the div.
Var jDisabled = true;
Else
Var jDisabled = false;
GetStarWidth (); // This function is not described in detail and has been analyzed above
$ (This). height (starHeight); // determine the height of the div Based on the height of the stars.

Next, let's look at it.:Copy codeThe Code is as follows: var average = parseFloat ($ (this ). attr ('id '). split ('_') [0]), // use the <div> id (for example, 16_2) to obtain the number before the underline and use this number as the default proportion.
IdBox = parseInt ($ (this). attr ('id'). split ('_') [1]), // The part after the underline, used as the id of the scoring plug-in.
WidthRatingContainer = starWidth * opts. length, // The sum of the width of the star image, which is used as the width of the peripheral container.
WidthColor = average/opts. rateMax * widthRatingContainer, // The width occupied by the color block

Next, we will see the three newly created <div> and insert them into the main div.Copy codeThe Code is as follows: quotient =
$ ('<Div> ',
{
'Class': 'jratingcolor ',
Css :{
Width: widthColor
}
}). AppendTo ($ (this )),
Average =
$ ('<Div> ',
{
'Class': 'jratingaverage ',
Css :{
Width: 0,
Top:-starHeight
}
}). AppendTo ($ (this )),
Jstar =
$ ('<Div> ',
{
'Class': 'jstar ',
Css :{
Width: widthRatingContainer,
Height: starHeight,
Top:-(starHeight * 2 ),
Background: 'url ('+ bgPath +') repeat-x'
}
}). AppendTo ($ (this ));

First, let's analyze the first <div>. Its Class Name Is jRatingColor, which indicates the default proportion and yellow. Its length is withColor. Here we mainly look at its style sheet:Copy codeThe Code is as follows:. jRatingColor {
Background-color: # f4c239;/* bgcolor of the stars */
Position: relative; // relative positioning
Top: 0;
Left: 0;
Z-index: 2; // note that the ancestor of the div, that is, the z-index of this in our each function, is 1. We will see it immediately below.
Height: 100%;
}

The second <div> style sheet is as follows:Copy codeThe Code is as follows:. jRatingAverage {
Background-color: # f62929; // red
Position: relative;
Top: 0;
Left: 0;
Z-index: 2;
Height: 100%;
}

But in the above program, when initializing, set the width to 0 (because the mouse has not been selected) and change the top value:-star height, in this way, it overlaps with the div added above in the vertical direction.
Next, let's look at the third <div>, which is mainly used to put small stars.Copy codeThe Code is as follows:/** Div containing the stars **/
. JStar {
Position: relative;
Left: 0;
Z-index: 3;
}

This style sheet is relatively simple. Let's take a look at several attribute values dynamically added in JS:Copy codeCode: width: widthRatingContainer, // set the width
Height: starHeight, // height
Top:-(starHeight * 2), // change the value of the vertical direction, and overlap with the above two <div>
Background: 'url ('+ bgPath +') repeat-x' // set the background to star

The attribute value is set, but someone may ask, what is the color of the small star, and the first two <div> added above are not rectangular color bars with a height? Now let's take a look at the pictures of the stars to see why!

Needless to say, there is an opaque background next to it. The stars in the middle are transparent, and the colors below are naturally displayed !!
The following statement is simple: Set the style of the outermost div container. Pay attention to the z-Index attribute:Copy codeThe Code is as follows: border (this).css ({width: widthRatingContainer, overflow: 'did', zIndex: 1, position: 'relative '});

Next we will go into a relatively complex section. We will focus on the mouse action and its response effect. First, we will focus on a small logic:
If (! JDisabled)
// The following code
We can see that the jDisable variable we set previously is used here. If jDisabled is set to true, it indicates that the plug-in is disabled, and the next mouse operation will not be executed.
Next, let's see how the mouse operation is added to the plug-in:
$ (This). unbind (). bind ({// code for processing mouse events, which will be discussed below.
});
First, take a look at the mouse to enter the event processing code:Copy codeCode: mouseenter: function (e ){
Var realOffsetLeft = findRealLeft (this );
Var relativeX = e. pageX-realOffsetLeft; // calculate relativeX, which indicates the horizontal distance between the mouse and the outer <div> left boundary.
If (opts. showRateInfo)
Var tooltip =
$ ('<P> ',{
'Class': 'jratinginfos ',
Html: getNote (relativeX) + '<span class = "maxRate">/' + opts. rateMax + '</span>', // note that the getNote method is used here. The usage of this method is described earlier.
Css :{
Top: (e. pageY + opts. rateInfosY ),
Left: (e. pageX + opts. rateInfosX)
}
}). AppendTo ('body'). show ();
},

The relativeX variable is not explained much. The comments mentioned here and above are described. Next, determine whether the showRateInfo parameter is true. If it is true, the proportion information is displayed (for example, 16/20 is displayed below the mouse ), the tooltip variable is the information box and is added to the body through the appendTo method. The Code logic is very simple. This function is mainly used to display the prompt box <p>. Here we can focus on the <p> node style, which is absolutely positioned, and changed the top and Left values using the code. Let's take a look at the relevant style sheet:Copy codeThe Code is as follows: p. jRatingInfos {
Position: absolute;
Z-index: 9999;
Background: transparent url ('HTTP: // www.cnblogs.com/icons/bg_jRatingInfos.png') no-repeat;
Color: # FFF;
Display: none;
Width: 91px;
Height: 29px;
Font-size: 16px;
Text-align: center;
Padding-top: 5px;
}
P. jRatingInfos span. maxRate {
Color: # c9c9c9;
Font-size: 14px;
}

Next, let's take a look at the processing function of the mousemove event after the mouse comes in:Copy codeThe Code is as follows: mousemove: function (e ){
Var realOffsetLeft = findRealLeft (this );
Var relativeX = e. pageX-realOffsetLeft;
If (opts. step) newWidth = Math. floor (relativeX/starWidth) * starWidth + starWidth;
Else newWidth = relativeX;
Average. width (newWidth );
If (opts. showRateInfo)
$ ("P. jRatingInfos ")
. Css ({
Left: (e. pageX + opts. rateInfosX)
})
. Html (getNote (newWidth) + '<span class = "maxRate">/' + opts. rateMax + '</span> ');
},

This function is mainly used to determine the ratio of mouse selection. Of course, this ratio is obtained through getNote (newWidth), so determining the appropriate newWidth value becomes the core of this function, if opts. step is true, that is, the proportion can only be an integer Star (cannot be 15.3, etc.), so let's take a look at this logic: Math. floor (relativeX/starWidth), starWidth is the width of the star image, Math. floor (-0.1) =-1, Math. floor (0.1) = 0, Math. floor (2.6) = 2. Knowing this makes it easy to understand the code highlighted above.
OK, Let's go on. Let's take a look at the three simple processing functions.Copy codeThe Code is as follows: mouseover: function (e ){
Vertex (this).css ('cursor ', 'pointer ');
},
Mouseout: function (){
Vertex (this).css ('cursor ', 'default ');
Average. width (0 );
},
Mouseleave: function (){
$ ("P. jRatingInfos"). remove ();
},

The mouseover function ensures the display style after the mouse enters the plug-in. The mouseout function also changes the div (red) width of the class named average to 0, and the mouseleave function disappears the prompt box.
The last function is the end of the entire source code. Of course, it is also the most important and complex-The mouse click function:Copy codeThe Code is as follows: click: function (e ){
// The subsequent code is here.
}

Let's take a look at the first part:Copy codeThe Code is as follows: publish (this).unbind().css ('cursor ', 'default'). addClass ('jdisabled ');

Why only one statement is listed here, because it is very important, but also very simple. Here we must pay attention to the unbind () function, which is very important. When you click the mouse, first, all the other events bound to the peripheral <div> are removed, so that the plug-in's appearance is fixed in the browser when you click the mouse, it does not change with mouse events. Of course, add the jDisabled attribute to <div>.
Let's go back:Copy codeThe Code is as follows: if (opts. showRateInfo) $ ("p. jRatingInfos"). fadeOut ('fast ', function () {$ (this). remove ();});
E. preventDefault ();
Var rate = getNote (newWidth); // follow the rate variable, which will be used later.
Average. width (newWidth );

The first sentence is not hard to understand. The delete prompt box and the second sentence cancel the default operation of Mouse clicking. The next two sentences are very simple and will not be described in detail. You Need To Know That newWidth has been mentioned earlier, the width selected by the mouse.
The last statement sends the selected proportion to the server for persistence:Copy codeThe Code is as follows: $. post (
Opts. phpPath, // address for sending data to the server using Ajax technology
{// Post past data
IdBox: idBox,
Rate: rate,
Action: 'rating'
},
Function (data) {// callback function, which is used to pass parameters and execute them to custom functions of the plug-in.
If (! Data. error)
{
If (opts. onSuccess) opts. onSuccess (element, rate );
}
Else
{
If (opts. onError) opts. onError (element, rate );
}
},
'Json' // determine how to understand the returned data, which uses json.
);

It is really easy to use jQuery for Ajax, and the necessary comments are made in the code. I will not repeat it here. The source code of this plug-in has been analyzed and is rough, but the entire logic may reflect some, I hope this learning note will help you. Next we will enter the practical stage.
Iii. Actual jRating plug-ins
To better approach the real application, we first use SQL server to create a database table, which is an article table with four fields: id, Title, article content, and score:

The default score field is-1, indicating that this article has not been scored. Of course, some people may say that this table is not designed properly, because an article won't only rate it once. Every user should be able to comment. Yes, here we only want to demonstrate the jRating plug-in using Ajax for persistence operations, because it is a demonstration, so everything starts from the beginning.
Create a new Web page to display the title, content, and scoring plug-in of the first article (id: 1). For details, see the front-end code:Copy codeThe Code is as follows: <Head runat = "server">
<Title> </title>
<Link href = "Script/jRating/jRating.jquery.css" rel = "stylesheet" type = "text/css"/>
<Scripts src = "script/jquery-1.7.min.js" type = "text/javascript"> </Script>
<Script src = "Script/jRating. jquery. js" type = "text/javascript"> </script>
<Script type = "text/javascript">
$ (Function (){
$ (". TheRating"). jRating ({
Length: 20,
PhpPath: 'tempajax. aspx/updatecomment' // The address is changed to a static function under An aspx WEB page. We will see it later!
});
});
</Script>
</Head>
<Body>
<Form id = "form1" runat = "server">
<Div>
<Asp: Label ID = "Label1" runat = "server" Text = "title:"> </asp: Label>
<Asp: Label ID = "page0000title" runat = "server" Text = ""> </asp: Label> <br/>
<Asp: Label ID = "pagedomainbody" runat = "server" Text = ""> </asp: Label> <br/>
<Div id = "16_1" class = "theRating"> </div>
</Div>
</Form>
</Body>
</Html>

The backend CS code is as follows:Copy codeThe Code is as follows: protected void Page_Load (object sender, EventArgs e)
{
If (! Page. IsPostBack)
{
TempEntities cbx = new tempEntities (); // obtain the data table using the object framework
Var page1 = cbx. jRatingArticles. Where (m => m. id = 1). SingleOrDefault ();
Pageappstitle.text = page1.title;
Pagedomainbody.text = page1.body;
}
}

To reduce the database connection code, I used the Entity Framework and mapped only one table (jRatingArticle), which we saw above. Obtain the article object with id 1 and assign the corresponding attribute to the Text attribute of the Label control.
The page effect is as follows::

We can see that there is such a statement in the JS Code on the front-end page:
PhpPath: 'tempajax. aspx/updatecomment'
It specifies the address for sending data through Ajax after clicking the plug-in. Here we use the. net page technology to process this asynchronous request. The background cs code of tempAjax. aspx is as follows:Copy codeThe Code is as follows: [WebMethod ()]
Public static void UpdateComment (int idBox, int rate)
{
TempEntities cbx = new tempEntities ();
Var page1 = cbx. jRatingArticles. Where (m => m. id = 1). SingleOrDefault ();
Page1.is _ comment = rate;
Cbx. SaveChanges ();
}

At this point, we also need to modify the original file of the jRating plug-in and replace the $. post function in the mouse-click processing function with the following:Copy codeThe Code is as follows: $. ajax ({
Type: "POST ",
Url: opts. phpPath,
Data: '{"idBox": "' + idBox + '", "rate": "' + rate + '"}',
ContentType: "application/json; charset = UTF-8 ",
DataType: "json"
});

Why should I change the source file? Because I want to change the contentType attribute of the Ajax request and send the request data in json format, the default value is application/x-www-form-urlencoded.
OK, everything is ready. Check the execution result (select a ratio of 16 to 16 red stars ):

View database changes:

Test successful! I hope this learning note will be helpful to you!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.