最近完整做了一个项目,从前端到后台,一个人搞定,还是非常有成就感的。整个流程走通了,以往很害怕的一些地方也理顺了,就比较有自信了。
现总结一下一个项目有哪些关键点:
从前端来讲,主要有两部分,一是图片轮播、图片放大显示,可以采用SuperSlide插件和zoom插件来搞定;二是简单的动画效果,纯css搞定;
从后台来讲,主要有三部分,一是文件上传,用jquery的uploadify插件搞定,包括文件引用、插件初始化及处理上传的ashx文件;二是编辑器,用kindeditor搞定,也是包括文件引用、编辑器初始化,如果要插入图片什么的,还要包括两个关键的处理上传的东东upload和file manager的ashx;三是分页,包括存储过程、Controller、js、Dom及css写法,其中存储过程是关键。具体如何使用罗列如下:
前端:
一、图片轮播、图片放大显示(SuperSlide和zoom插件)
使用jquery.SuperSlide.2.1.1.js插件,完整调用包括js引用、样式、dom写法。
<script src="~/Content/JS/jquery.SuperSlide.2.1.1.js"></script>
<div class="banner">
<style type="text/css">
/* bannercss */
.slideBox{ 100%; height:500px; overflow:hidden; position:relative;}
.slideBox .hd{ height:24px; overflow:hidden; position:absolute; right:50%; margin-left:-38px; bottom:35px; z-index:1; }
.slideBox .hd ul{ overflow:hidden; zoom:1; float:left; }
.slideBox .hd ul li{ float:left; margin-right:2px; 24px; height:24px;cursor:pointer;background:url(../Images/icons.png) -191px -22px; }
.slideBox .hd ul li.on{ background:url(../Images/icons.png) -160px -22px; }
.slideBox .bd{ position:relative; height:100%; z-index:0; }
.slideBox .bd li{ zoom:1; vertical-align:middle; }
.slideBox .bd img{ height:500px; display:block; min-1200px;margin:0 auto }
</style>
<div id="slideBox" class="slideBox">
<div class="hd">
<ul>
@if (bannerList != null && bannerList.Count > 0)
{
int b = 1;
foreach (var item in bannerList)
{
<li>b</li>
b++;
}
}
</ul>
</div>
<div class="bd">
<ul>
@if (bannerList != null && bannerList.Count > 0)
{
foreach (var item in bannerList)
{
<li><a href="@item.href" target="_blank"><img src="@item.imgUrl" alt="@item.title" /></a></li>
}
}
else
{
<li><a href="" target="_blank"><img src="~/Content/Images/banner.jpg" /></a></li>
}
</ul>
</div>
</div>
<script type="text/javascript">
jQuery(".slideBox").slide({mainCell:".bd ul",autoPlay:true});
</script>
</div>
同样使用SuperSlide可实现预览图切换、小图滚动
// 楼盘图切换
jQuery(".picFocus").slide({
mainCell: ".bd ul",
titCell: ".hd li",
effect: "left",
autoPlay: true,
interTime: 5000,
delayTime: 400
});
// 楼盘小图左右滚动
jQuery(".picFocus .hd").slide({
mainCell: "ul",
vis: 5,
prevCell: ".sPrev",
nextCell: ".sNext",
effect: "left",
autoPage: true
});
图片放大效果需要使用zoom插件
@*图片放大*@
<script src="~/Content/JS/zoom.min.js"></script>
<div id="zoom" style="display: none;">
<a class="close"></a>
<a href="#previous" class="previous"></a>
<a href="#next" class="next"></a>
<div class="content loading"></div>
</div>
轮播处<ul class="gallery">@*class="gallery"确保点击图片后全屏放大显示*@
/*楼盘图弹出显示大图*/
#zoom {
z-index: 99990;
position: fixed;
top: 0;
left: 0;
display: none;
100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";
}
#zoom .content {
z-index: 99991;
position: absolute;
top: 50%;
left: 50%;
200px;
height: 200px;
background: #ffffff no-repeat 50% 50%;
padding: 0;
margin: -100px 0 0 -100px;
box-shadow: -20px 20px 20px rgba(0, 0, 0, 0.3);
border-radius: 4px;
}
#zoom .content.loading {
background-image: url('../Images/loading-big.gif');
}
#zoom img {
display: block;
max- none;
background: #ececec;
box-shadow: 0 1px 3px rgba(0,0,0,0.25);
border-radius: 4px;
}
#zoom .close {
z-index: 99993;
position: absolute;
top: 0;
right: 0;
49px;
height: 49px;
cursor: pointer;
background: transparent url('../Images/close.png') no-repeat 50% 50%;
opacity: 1;
filter: alpha(opacity=100);
border-radius: 0 0 0 4px;
}
#zoom .previous,
#zoom .next {
z-index: 99992;
position: absolute;
top: 50%;
overflow: hidden;
display: block;
49px;
height: 49px;
margin-top: -25px;
}
#zoom .previous {
left: 0;
background: url('../Images/arrows.png') no-repeat 0 0;
border-radius: 0 4px 4px 0;
}
#zoom .next {
right: 0;
background: url('../Images/arrows.png') no-repeat 100% 0;
border-radius: 4px 0 0 4px;
}
#zoom .close:hover {
background-color: #f83d3d;
}
#zoom .previous:hover,
#zoom .next:hover {
background-color: #466EB6;
}
二、纯css实现动画效果,如鼠标移到图片上显示文字
.yh-process .mouseover{
opacity: 0;
filter: alpha(opacity=0);
-webkit-transition: all ease-in-out .2s;
-moz-transition: all ease-in-out .2s;
-ms-transition: all ease-in-out .2s;
transition: all ease-in-out .2s;
}
.yh-process li:hover .mouseover{
opacity: 1;
filter: alpha(opacity=100);
top: 0;
height: 100%;
cursor: pointer;
}
后台:
一、文件上传(使用jquery.uploadify插件)
引用:
<link href="~/Content/js/uploadify/uploadify.css" rel="stylesheet" type="text/css" />
<script src="~/Content/js/uploadify/uploadify.swf"></script>
<script src="~/Content/js/uploadify/jquery.uploadify.min.js" type="text/javascript"></script>
初始化:
$("#productDetailImg").uploadify({
//开启调试
// 'debug' : false,
//是否自动上传
// 'auto':false,
//'buttonText': '上传',
'buttonImage': '/Content/Images/upload_btn.png',
//flash
'swf': "/Content/JS/uploadify/uploadify.swf",
//文件选择后的容器ID
// 'queueID': 'uploadfileQueue',
'uploader': '/ajax/uploadsoftware.ashx',
'width': '248',
'height': '210',
'multi': false,
'fileTypeDesc': '支持的格式:*.jpg;*.jpge;*.gif;*.png',
'fileTypeExts': '*.jpg;*.jpge;*.gif;*.png',
'fileSizeLimit': '4MB',
'removeTimeout': 1,
//返回一个错误,选择文件的时候触发
'onSelectError': function (file, errorCode, errorMsg) {
switch (errorCode) {
case -100:
alert("上传的文件数量已经超出系统限制的" + $('#productDetailImg').uploadify('settings', 'queueSizeLimit') + "个文件!");
break;
case -110:
alert("文件 [" + file.name + "] 大小超出系统限制的" + $('#productDetailImg').uploadify('settings', 'fileSizeLimit') + "大小!");
break;
case -120:
alert("文件 [" + file.name + "] 大小异常!");
break;
case -130:
alert("文件 [" + file.name + "] 类型不正确!");
break;
}
},
//检测FLASH失败调用
'onFallback': function () {
alert("您未安装FLASH控件,无法上传图片!请安装FLASH控件后再试。");
},
//上传到服务器,服务器返回相应信息到data里
'onUploadSuccess': function (file, data, response) {
var $pre = $("#floorImg .preview");
var iLength = $pre.find("a").length;
var str = '<a href="javascript:void(0);" class="item_margin_left upload_btn" data-value="0"><img src="' + data + '" /><i class="del"></i><input type="text" value="" placeholder="请输入图片描述" /></a>';
if (iLength == 0) {
$pre.html(str);
} else {
$pre.find("a").eq(iLength - 1).after(str);
}
}
});
上传处理:uploadsoftware.ashx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
namespace Web.ajax
{
/// <summary>
/// uploadsoftware 的摘要说明
/// </summary>
public class uploadsoftware : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Charset = "utf-8";
HttpPostedFile file = context.Request.Files["Filedata"];
//string DistributedUploadVirtualPath = System.Web.Configuration.WebConfigurationManager.AppSettings["DistributedUploadVirtualPath"];
//if (string.IsNullOrEmpty(DistributedUploadVirtualPath))
string DistributedUploadVirtualPath = "/UploadFiles/";
string strUploadPath = "";
string pathDate = System.DateTime.Now.ToString("yyyyMMdd");
string filenamedate = System.DateTime.Now.ToString("yyyyMMddhhmmff") + "" + Guid.NewGuid().ToString().Substring(1, 16);
string fileExt = Path.GetExtension(file.FileName.Trim()).ToLower();
string fileName = filenamedate + "" + fileExt;
string strDPath = DistributedUploadVirtualPath + "" + pathDate;
string uploadPath = context.Server.MapPath(strDPath);
if (file != null)
{
if (!System.IO.Directory.Exists(uploadPath))
{
System.IO.Directory.CreateDirectory(uploadPath);
}
file.SaveAs(uploadPath+"/"+fileName);
strUploadPath = strDPath + "/" + fileName;
}
context.Response.Write(strUploadPath);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
二、编辑器(kindeditor)
<script src="~/Content/JS/kindeditor-4.1.2/kindeditor-min.js"></script>
//初始化编辑器
var editor = "";
$().ready(function () {
editor = KindEditor.create('#txtContentGood', {
cssPath: '../../Content/JS/kindeditor-4.1.2/plugins/code/prettify.css',
uploadJson: '../../Content/Action/upload_json.ashx',
fileManagerJson: '../../Content/Action/file_manager_json.ashx',
allowFileManager: false,
allowImageRemote: false,
minWidth: 300,
items: ['source','bold', 'italic', 'underline', 'forecolor', 'hilitecolor', 'removeformat',
'|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', '|',
'image', '|', 'fullscreen']
});
editor.html($("#hideContentGood").val());
});
还有两个关键的处理上传的文件:
uploadJson: '../../Content/Action/upload_json.ashx',
fileManagerJson: '../../Content/Action/file_manager_json.ashx'
三、分页
存储过程写法:
-- ----------------------------
-- Procedure structure for `p_productList`
-- ----------------------------
DROP PROCEDURE IF EXISTS `p_productList`;
DELIMITER ;;
CREATE DEFINER=`cjq_123`@`%` PROCEDURE `p_productList`(PageIndex int,
PageSize int,
strWhere varchar(1000),
out PageCount int)
top:begin
if PageSize<0 then
set PageSize=0;
end IF;
if PageIndex<1 THEN
set PageIndex=1;
end IF;
set @PageCount=0;
set @strSQL=concat('select count(0) into @PageCount from products ',strWhere);
prepare SqlCmd from @strSQL;
execute SqlCmd;
DEALLOCATE PREPARE SqlCmd;
set PageCount=@PageCount;
set @strSQL=concat('select *,(select count(0) from coupon where productID=a.productId and type=0) as hongbaoCount, (select count(0) from coupon where productID=a.productId and type=1) as yyCount from products a ',strWhere,
' order by productId desc limit ',PageIndex*PageSize-PageSize,',',PageSize);
prepare SqlCmd from @strSQL;
execute SqlCmd;
DEALLOCATE PREPARE SqlCmd;
end
;;
DELIMITER ;
Controllers写法:
public ActionResult ProductList(string page, string productName, string status)
{
if (string.IsNullOrEmpty(page) || Convert.ToInt32(page) <= 0)
{
page = "1";
}
if (!string.IsNullOrWhiteSpace(productName))
{
productName = Common.StringHelper.UrlDecode(productName);
}
int pageCount = 0, iCount = 0;
int pageSize = 20;
string strWhere = " where Status>-2 ";
if (!string.IsNullOrEmpty(status))
{
strWhere += " and Status=" + status + " ";
}
if (!string.IsNullOrEmpty(productName))
{
strWhere += " and productName like CONCAT('%','" + productName + "','%') ";
}
var productList = ProductBLL.getList(pageSize, Convert.ToInt32(page), strWhere, out iCount);
if (iCount > 0)
{
if (iCount % pageSize == 0)
{
pageCount = iCount / pageSize;
}
else
{
pageCount = iCount / pageSize + 1;
}
}
ViewData["productList"] = productList;
ViewBag.PageIndex = page;
ViewBag.PageCount = pageCount;
ViewBag.productName = productName == null ? "" : productName;
ViewBag.status = status == null ? "" : status;
return View();
}
页面写法:
@{
ViewBag.Title = "- 住宅";
Layout = "../Shared/_LayoutWeb.cshtml";
int PageIndex = Convert.ToInt32(ViewBag.PageIndex);
int pageCount = Convert.ToInt32(ViewBag.PageCount);
var productList = ViewData["productList"] as IList<V_Model.Products>;
}
@if (productList != null && productList.Count > 0)
{
<div class="bg-grey">
<ul class="pic-list clearfloat">
@foreach (var item in productList)
{
<li onclick="document.location.href = '/Home/Detail?productId=@item.productId'">
<div class="imgbox">
<img alt="@item.productName" src="@item.coverImg">
<div class="text">
<p>@item.productName</p>
</div>
</div>
<div class="imginfo">
<p>
<span class="price-h">@item.price 元/平方米</span>
<span class="number"><em class="red">@item.number</em>人报名</span>
</p>
<p class="yh">@item.coupon</p>
</div>
</li>
}
</ul>
<div id="pagination"></div>
</div>
}
else
{
<div class="noitem">暂无住宅</div>
}
<script type="text/javascript">
setPagination("pagination", @PageIndex, @pageCount, "");
</script>
JS写法
//分页
function setPagination(id, currentPage, pageCount, query) {
if (currentPage <= 0)
currentPage = 1;
if (currentPage > pageCount)
currentPage = pageCount;
var arrHtml = [];
var pageStart = 1;
var pageEnd = 5;
if (currentPage == '' || currentPage < 1)
currentPage = 1;
if (currentPage > pageCount) {
currentPage = pageCount;
}
pageStart = 1 * (currentPage - 1);
pageStart = pageStart <= 1 ? 1 : pageStart;
pageEnd = pageStart + 2;
pageStart -= 2;
pageEnd = pageStart <= 0 ? 5 : pageEnd;
pageStart = pageStart <= 0 ? 1 : pageStart;
pageEnd = pageEnd > pageCount ? pageCount : pageEnd;
var prevPage = parseInt(currentPage) - 1;
var nextPage = parseInt(currentPage) + 1;
arrHtml.push("<div class="pagination">");
if (pageEnd > 1) {
if (pageEnd - pageStart > 4) {
pageStart = pageEnd - 5;
}
if (pageEnd - pageStart < 4) {
pageStart = pageEnd - 4 > 0 ? pageEnd - 4 : 1;
}
if (prevPage > 0) {
arrHtml.push('<a href="?page=' + prevPage + '' + query + '" class="prev"><i class="img_icon"></i></a>');
} else {
arrHtml.push('<a class="prev"><i class="img_icon"></i></a>');
}
for (var i = pageStart; i <= pageEnd; i++) {
if (currentPage == i) {
arrHtml.push('<span class="page-current">' + i + '</span>');
} else {
arrHtml.push('<a href="?page=' + i + '' + query + '">' + i + '</a>');
}
}
if (pageEnd < pageCount) {
arrHtml.push('<span>...</span>');
}
if (currentPage < pageCount) {
arrHtml.push('<a href="?page=' + nextPage + '' + query + '" class="next"><i class="img_icon"></i></a>');
} else {
arrHtml.push('<a class="next"><i class="img_icon"></i></a>');
}
}
arrHtml.push("</div>");
$("#" + id).html(arrHtml.join(""));
}
css写法:
.pagination {
margin: 30px auto 0;
height: 40px;
line-height: 40px;
text-align: center;
}
.pagination span, .pagination strong, .pagination a {
padding: 10px 15px;
border-radius: 5px;
margin-right: 5px;
background-color: #e9e2e0;
color: #e64b40;
font: normal 16px "Microsoft YaHei";
cursor: pointer;
}
.pagination strong, .pagination span.page-current {
background: #e64b40;
color: #ffffff;
}
.pagination a.prev i{
display:inline-block;
10px;
height:16px;
background:url("/Content/Images/prev_icon.png") no-repeat;
}
.pagination a.next i{
display:inline-block;
10px;
height:16px;
background:url("/Content/Images/next_icon.png") no-repeat;
}