JS三教九流系列-jquery实例开发到插件封装2

我们先写实例,然后有必要在分装为插件,最后做更高级的处理!

封装插件基础学习 http://my.oschina.net/u/2352644/blog/487688

前面的7个实例在这里 http://my.oschina.net/u/2352644/blog/490827

效果目录:

8.商品数量加减效果

9.星星评分效果

10.刮刮卡效果

11.圆形大转盘抽奖效果

12.贪食蛇小游戏效果

13.video的html5视频播放器

14.可拖拽的登陆框

15.树形菜单效果

16.全选/反全选处理

17.瀑布流效果(未实现) 

 

8.商品数量加减效果

这个效果,我们在看淘宝提交的时候,就会选择购买数量,很简单常见效果

 废话不多说,已经做了7个效果,我们直接来布局静态结构:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
.num{ margin:100px;}
.num input{ height:30px; border:1px solid #ccc;}
.numinc,.numadd{ width:30px; text-align:center;}
.numshou{ width:100px; text-align:center;}
</style>
</head>
<body>
 <div class="num">
     <input type="button" class="numinc" value="-" />
     <input type="text" class="numshou" value="1"/>
        <input type="button" class="numadd" value="+" />
      
    </div>
</body>
</html>

我们接下来给加减按钮添加事件,做出处理:

最小数量为1.作为临界值

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
$(".numinc").click(function(){
 if($(".numshou").val()<=1){
  $(".numshou").val(1);
 }else{
  $(".numshou").val(parseInt($(".numshou").val())-1);
 };
 
});
$(".numadd").click(function(){
 $(".numshou").val(parseInt($(".numshou").val())+parseInt(1));
});
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
.num{ margin:100px;}
.num input{ height:30px; border:1px solid #ccc;}
.numinc,.numadd{ width:30px; text-align:center;}
.numshou{ width:100px; text-align:center;}
</style>
</head>
<body>
 <div class="num">
     <input type="button" class="numinc" value="-" />
     <input type="text" class="numshou" value="1"/>
        <input type="button" class="numadd" value="+" />
      
    </div>
</body>
</html>

9.星星评分效果

给商品打分,点击到哪个,当前和以前都被选中,我们看代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
$(".ping").children().click(function(){
 var i=$(this).index();
 $(".ping").children().each(function(index, element) {
        if(index<=i){
   $(this).addClass("add");
  }else{
   $(this).removeClass("add");
  };
    });
 
});
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
.ping{ margin:100px; height:30px;}
.ping span{ float:left; height:20px; width:20px; margin:5px; background:#666; cursor:pointer;}
.ping span.add{ background:#C93;}
</style>
</head>
<body>
 <div class="ping">
     <span class="add"></span>
        <span class="add"></span>
        <span></span>
        <span></span>
        <span></span>      
    </div>
</body>
</html>

10.刮刮卡效果

刮刮卡是基础canvas的,

原理就是用带有颜色canvas盖住下面的奖项,我们去让canvas透明,显示出下面内容

用到对canvas的全局属性设置为原内容和后加内容相加变透明属性处理

globalCompositeOperation="destination-out";

直接代码处理:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
var cjcon=["一等奖","二等奖","三等奖","谢谢参与"];//奖项设置
var cjper=[3,10,20,100];//奖项率,次数
/*
 * sjmes
 * @Author 透笔度([email protected])              
 * @param {cjcon}      所有奖项     
 */
var percjcon=[];
for(var i=0;i<cjper.length;i++){
 peic(cjper[i],i);
};
function peic(len,ind){
 for(var i=0;i<len;i++){
  percjcon.push(cjcon[ind]);
 }; 
};
var sjmes = $("#sjmes");
var numrandom=Math.floor(Math.random()*percjcon.length);
sjmes.html(percjcon[numrandom]);
var opacityb=0.5;//透明百分比,参考值,什么程度出现提示
var backcolorb="#ffaaaa";
var numl=200*80;//总像素个数
var nump;//出现backcolorb的个数
var opacitya;//透明百分比实际值
var canvas = $("#canvas")[0];  //获取canvas   
var context = canvas.getContext('2d');  //canvas追加2d画图
var flag = 0;  //标志,判断是按下后移动还是未按下移动 重要
var penwidth=20; //画笔宽度
context.fillStyle="#faa";  //填充的颜色
context.fillRect(0,0,200,80);  //填充颜色 x y坐标 宽 高
canvas.addEventListener('mousemove', onMouseMove, false); //鼠标移动事件 
canvas.addEventListener('mousedown', onMouseDown, false);  //鼠标按下事件 
canvas.addEventListener('mouseup', onMouseUp, false);  //鼠标抬起事件 
var movex=-1;
var movey=-1;
var imgData;//imagedada容器
var rgbabox=[];//存放读取后的rgba数据;
function onMouseMove(evt) {
 if (flag == 1) {  
  movex=evt.layerX;
  movey=evt.layerY;  
     context.fillStyle="#FF0000";
  context.beginPath();
  context.globalCompositeOperation="destination-out";
  context.arc(movex,movey,penwidth,0,Math.PI*2,true); //Math.PI*2是JS计算方法,是圆  
  context.closePath();
  context.fill();
 }  
}  
function onMouseDown(evt) {  
  flag = 1;  //标志按下
}  
function onMouseUp(evt) {  
 flag = 0;
    //读取像素数据
 imgData=context.getImageData(0,0,200,80);//获取当前画布数据
 //imgData.data.length 获取图片数据总长度,没4个为一组存放rgba
 for(var i=0; i<imgData.data.length;i+=4){
  var rval=imgData.data[i];
  var gval=imgData.data[i+1];
  var bval=imgData.data[i+2];
  var aval=imgData.data[i+3];
  var rgbaval=rval+"-"+gval+"-"+bval+"-"+aval;
  rgbabox.push(rgbaval);
 }
 //end
 for(var j=0;j<rgbabox.length;j++){
  //alert(rgbabox[j].split("-")[0])
  rgbabox[j]='#'+rgbToHex(rgbabox[j].split("-")[0],rgbabox[j].split("-")[1],rgbabox[j].split("-")[2]);  
 }
 nump=countSubstr(rgbabox.join(","),backcolorb,true);
 opacitya=(numl-nump)/numl;
 if(opacitya>opacityb){
  alert("恭喜你获得"+percjcon[numrandom])
 }else{}
 
} 
function rgbToHex(r, g, b) { return ((r << 16) | (g << 8) | b).toString(16); }//rgb转为16进制 #xxx形式
function countSubstr(str,substr,isIgnore){//计算字符串出现子字符串的个数
 var count;
 var reg="";
 if(isIgnore==true){
 reg="/"+substr+"/gi"; 
 }else{
 reg="/"+substr+"/g";
 }
 reg=eval(reg);
 if(str.match(reg)==null){
 count=0;
 }else{
 count=str.match(reg).length;
 }
 return count;
}
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
.cjbox{ margin:100px; height:80px; width:200px; background:#FFF; position:relative;}
#canvas{position:absolute; left:0px; top:0px;z-index:99;}
.sjmes{ position:absolute; left:0px; top:0px; height:80px; width:200px; text-align:center; font-size:40px; line-height:80px; z-index:9;}
</style>
</head>
<body>
<div style="position:relative; margin:20px 100px; background:#0CF; height:400px; width:500px; margin:0 auto;">
 <div>刮刮卡简单抽奖</div>
    <div class="cjbox">
     <div class="sjmes" id="sjmes"></div>
        <canvas width=200 height=80 id="canvas"></canvas> 
    </div>
</div> 
</body>
</html>

11.圆形大转盘抽奖效果

我们已经做了九宫格大装盘,其实原理类似,这个是利用css3的2d旋转,转动中间的带指针图片

原理是元素transform-origin:center center;transform:rotate(0deg);的处理

我就不用图了,以免测试麻烦,

代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
 var set;//存放间隔函数id,用于清除动画 
 var i=0;//初始位置,
 var speed=10;//转动速度
 var ok=Math.floor((Math.random()*361));//产生0-360度的整数,标记中奖位置
 var okw=null;
 if(ok>=0 && ok<30){
  okw="1"
 }else if(ok>=30 && ok<60){
  okw="2"
 }
 else if(ok>=60 && ok<90){
  okw="3"
 }
 else if(ok>=90 && ok<120){
  okw="4"
 }
 else if(ok>=120 && ok<150){
  okw="5"
 }
 else if(ok>=150 && ok<180){
  okw="6"
 }
 else if(ok>=180 && ok<210){
  okw="7"
 }
 else if(ok>=210 && ok<240){
  okw="8"
 }
 else if(ok>=270 && ok<300){
  okw="9"
 }
 else if(ok>=300 && ok<330){
  okw="10"
 }
 else if(ok>=330 && ok<=360){
  okw="11"
 }
 else{
  okw="12"
 }
 var count=5*360+ok;//总圈数,一圈是360度
 var nowcount=0;//当前的圈数
 function dong(){
  if(nowcount>count){
   clearInterval(set);
   alert("恭喜你,中了"+okw+"等奖")
  }else{   
   nowcount+=10;
   $(".start").css('transform','rotate('+i+'deg)')
   i+=10;
  };  
  
 }; 
 $(".start").click(function(){
  set=setInterval(dong,speed);
 });
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
#lottery{width:400px;height:400px;margin:20px auto 0; position:relative;}
#lottery div{width:100px;height:100px;text-align:centerfont-size:24px;color:#333; float:left;}
#lottery .cent{ background:#FFF;}
#lottery .lottery-unit-0{ background:#CC6;}
#lottery .lottery-unit-1{ background:#F99;}
#lottery .lottery-unit-2{ background:#CC6;}
#lottery .lottery-unit-3{ background:#F99;}
#lottery .lottery-unit-4{ background:#CC6;}
#lottery .lottery-unit-5{ background:#F99;}
#lottery .lottery-unit-6{ background:#CC6;}
#lottery .lottery-unit-7{ background:#F99;}
#lottery .lottery-unit-8{ background:#CC6;}
#lottery .lottery-unit-9{ background:#F99;}
#lottery .lottery-unit-10{ background:#CC6;}
#lottery .lottery-unit-11{ background:#F99;}
#lottery div.select{background:#F0F;}
#lottery .start{ position:absolute; left:100px; top:100px; height:200px; width:200px;background:#C33; font-size:30px; text-align:center; cursor:pointer; line-height:200px; color:#fff; border-radius:100px;
transform-origin:center center;transform:rotate(0deg);
}
#lottery .start span{ height:20px; width:80px;background:#C33; position:absolute; left:200px; top:90px; z-index:9999}
</style>
</head>
<body>
<div id="lottery">
   
   <div class="lottery-unit lottery-unit-0">8</div>
   <div class="lottery-unit lottery-unit-1">9</div>
   <div class="lottery-unit lottery-unit-2">10</div>
            <div class="lottery-unit lottery-unit-3">11</div>
            
            <div class="lottery-unit lottery-unit-11">7</div>            
            <div class="cent"></div>
            <div class="cent"></div>            
            <div class="lottery-unit lottery-unit-4">12</div>
            
            <div class="lottery-unit lottery-unit-10">6</div>            
            <div class="cent"></div>
            <div class="cent"></div>            
            <div class="lottery-unit lottery-unit-5">1</div>
        
   <div class="lottery-unit lottery-unit-9">5</div>
   <div class="lottery-unit lottery-unit-8">4</div>
   <div class="lottery-unit lottery-unit-7">3</div>
            <div class="lottery-unit lottery-unit-6">2</div>
 
   <div class="start">抽奖
             <span></span>
            </div>
</div>
</body>
</html>

 12.贪食蛇小游戏效果

这个原理我就按步骤分析,最后放总的代码

我们要有一个舞台,存放贪食蛇还有食物,我们先有基本的html结构

<canvas id="canvas" width="450" height="450"></canvas>

接下来我们jq获取canvas和添加2d画布,

//获取canvas基本信息
 var canvas = $("#canvas")[0];
 var ctx = canvas.getContext("2d");
 var w = $("#canvas").width();
 var h = $("#canvas").height();

我们想象一下,一条蛇放在画布上,是有若干个矩形组成,看到多个,我们就知道是存放在数组里,数组里的每一项还要存放蛇的位置信息(x y坐标),同样矩形的的宽度我们要提前设置,还有开始蛇的方向,

//创建贪吃蛇对象
 var snake_array; //由一个数组组成 
 //设置游戏变量
 var cw = 10;//单元格像素宽度
 //其他变量设置
 var d;//方向

我们还需要一个矩形,表示食物,只有一个,我们存入一个变量就好,还有就是每次吃完的分数记录

var food;//食物
 var score;//统计分数

接下来我们开始画出蛇,我们为了简单,蛇就初始为5个,在左上角位置,开始的话就往右走

创建一条横向,5节长度的蛇,坐标的话就是[{4,0},{3,0},{2,0},{1,0},{0,0}],第一项是蛇头,因为蛇头是最需要掌握的,

//创建蛇对象 函数
 function create_snake()
 {
  var length = 5; //设置初始贪吃蛇长度
  snake_array = []; //清空数组
  for(var i = length-1; i>=0; i--)//让蛇头处在向右,第一行第四个格
  {
   //在左上方创建水平的贪吃蛇
   snake_array.push({x: i, y:0});//[{4,0},{3,0},{2,0},{1,0},{0,0}]
  }
 }

我们要创建食物,这个要随机出现,位置在画布内部

//创建食物函数
 function create_food()
 {
  food = {
   x: Math.round(Math.random()*(w-cw)/cw), 
   //450以内随机数,保证在画布内
   y: Math.round(Math.random()*(h-cw)/cw), 
  };
  //在屏幕内随机产生坐标点
 }

蛇和食物有了,我们要绘制出来,在画布上,我们绘制处理,包含在一个函数里

function paint()
 { }

 下面的处理都是函数内部,绘制蛇头,根据方向做出改变,

//在每一帧图画中都必须首先清除上一帧内容。
  //清屏,即以底色填充canvas
  ctx.fillStyle = "#faa";
  ctx.fillRect(0, 0, w, h);
  //贪吃蛇运动逻辑:将贪吃蛇的尾部点放到头部
  //获取贪吃蛇头部的位置信息
  var nx = snake_array[0].x;
  var ny = snake_array[0].y;
  //根据贪吃蛇的运动方向计算最新头部的坐标信息
  if(d == "right") nx++;
  else if(d == "left") nx--;
  else if(d == "up") ny--;
  else if(d == "down") ny++;

是否碰撞到边际和身体,通过蛇头做参考判断

//判断是否超出屏幕界限或者碰到自己的身体,是则游戏结束
  if(nx == -1 || nx == w/cw || ny == -1 || ny == h/cw || check_collision(nx, ny, snake_array))
  {
   //重启游戏
   init();
   return;
  }

身体检测函数

//碰撞检测函数
 function check_collision(x, y, array)
 {
  //检查当前坐标是否已经存在于贪吃蛇数组中
  for(var i = 0; i < array.length; i++)
  {
   if(array[i].x == x && array[i].y == y)
    return true;
  }
  return false;
 }

检测与食物的碰撞和绘制

//如果贪吃蛇碰到食物,则在头部直接新增一个点
  if(nx == food.x && ny == food.y)
  {
   var tail = {x: nx, y: ny};
   score++;
   //生成新的食物
   create_food();
  }
                //如果贪吃蛇没有碰到食物,则在头部直接新增一个点,还需要去除尾部的一个点
  else
  //????????????????????????????????????????
  {
   var tail = snake_array.pop(); //去除尾部点
   tail.x = nx; tail.y = ny;
  }
  snake_array.unshift(tail); //移动数组
//22
  for(var i = 0; i < snake_array.length; i++)
  {
   var c = snake_array[i];
   //绘制单元格,每个单元格为10像素
   paint_cell(c.x, c.y);
  }
//33
  //绘制食物
  paint_cell(food.x, food.y);
  //绘制分数
  var score_text = "Score: " + score;
  ctx.fillText(score_text, 5, h-5);

运动起来

function init()
 {
  d = "right"; //默认方向
  create_snake();//创建蛇对象 函数
  create_food(); //创建食物对象 函数
  //分数清零
  score = 0;
  //让贪吃蛇动起来!设置一个定时器以定时触发重绘函数
  //设置定时时间为60ms,即60fps
  //if(typeof game_loop != "undefined") clearInterval(game_loop);
  game_loop = setInterval(paint, 300);//动画函数调用
 }

方向处理

//添加键盘控制
 $(document).keydown(function(e){
  var key = e.which;
  //注意不能直接逆向
  if(key == "37" && d != "right") d = "left";
  else if(key == "38" && d != "down") d = "up";
  else if(key == "39" && d != "left") d = "right";
  else if(key == "40" && d != "up") d = "down";
  
 })

整体代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
 //获取canvas基本信息
 var canvas = $("#canvas")[0];
 var ctx = canvas.getContext("2d");
 var w = $("#canvas").width();
 var h = $("#canvas").height();
 //设置游戏变量
 var cw = 10;//单元格像素宽度
 //其他变量设置
 var d;//方向
 var food;//食物
 var score;//统计分数
 //创建贪吃蛇对象
 var snake_array; //由一个数组组成
 //主函数
 function init()
 {
  d = "right"; //默认方向
  create_snake();//创建蛇对象 函数
  create_food(); //创建食物对象 函数
  //分数清零
  score = 0;
  //让贪吃蛇动起来!设置一个定时器以定时触发重绘函数
  //设置定时时间为60ms,即60fps
  //if(typeof game_loop != "undefined") clearInterval(game_loop);
  game_loop = setInterval(paint, 300);//动画函数调用
 }
 init();//执行主函数
 //创建蛇对象 函数
 function create_snake()
 {
  var length = 5; //设置初始贪吃蛇长度
  snake_array = []; //清空数组
  for(var i = length-1; i>=0; i--)//让蛇头处在向右,第一行第四个格
  {
   //在左上方创建水平的贪吃蛇
   snake_array.push({x: i, y:0});//[{4,0},{3,0},{2,0},{1,0},{0,0}]
  }
 }
 //var arr=[{x:0,y:0},{x:1,y:1}]
 //创建食物函数
 function create_food()
 {
  food = {
   x: Math.round(Math.random()*(w-cw)/cw), 
   //450以内随机数,保证在画布内
   y: Math.round(Math.random()*(h-cw)/cw), 
  };
  //在屏幕内随机产生坐标点
 }
 //绘制函数
 function paint()
 {
  //在每一帧图画中都必须首先清除上一帧内容。
  //清屏,即以底色填充canvas
  ctx.fillStyle = "#faa";
  ctx.fillRect(0, 0, w, h);
  //贪吃蛇运动逻辑:将贪吃蛇的尾部点放到头部
  //获取贪吃蛇头部的位置信息
  var nx = snake_array[0].x;
  var ny = snake_array[0].y;
  //根据贪吃蛇的运动方向计算最新头部的坐标信息
  if(d == "right") nx++;
  else if(d == "left") nx--;
  else if(d == "up") ny--;
  else if(d == "down") ny++;
  //判断是否超出屏幕界限或者碰到自己的身体,是则游戏结束
  if(nx == -1 || nx == w/cw || ny == -1 || ny == h/cw || check_collision(nx, ny, snake_array))
  {
   //重启游戏
   init();
   return;
  }
  //贪吃蛇吃食物逻辑
  //如果贪吃蛇碰到食物,则在头部直接新增一个点
  if(nx == food.x && ny == food.y)
  {
   var tail = {x: nx, y: ny};
   score++;
   //生成新的食物
   create_food();
  }
                //如果贪吃蛇没有碰到食物,则在头部直接新增一个点,还需要去除尾部的一个点
  else
  //????????????????????????????????????????
  {
   var tail = snake_array.pop(); //去除尾部点
   tail.x = nx; tail.y = ny;
  }
  snake_array.unshift(tail); //移动数组
//22
  for(var i = 0; i < snake_array.length; i++)
  {
   var c = snake_array[i];
   //绘制单元格,每个单元格为10像素
   paint_cell(c.x, c.y);
  }
//33
  //绘制食物
  paint_cell(food.x, food.y);
  //绘制分数
  var score_text = "Score: " + score;
  ctx.fillText(score_text, 5, h-5);
 }
 //单元格绘制函数
 function paint_cell(x, y)
 {
  ctx.fillStyle = "blue";
  ctx.fillRect(x*cw, y*cw, cw, cw);
  ctx.strokeStyle = "white";
  ctx.strokeRect(x*cw, y*cw, cw, cw);
 }
        //碰撞检测函数
 function check_collision(x, y, array)
 {
  //检查当前坐标是否已经存在于贪吃蛇数组中
  for(var i = 0; i < array.length; i++)
  {
   if(array[i].x == x && array[i].y == y)
    return true;
  }
  return false;
 }
 //添加键盘控制
 $(document).keydown(function(e){
  var key = e.which;
  //注意不能直接逆向
  if(key == "37" && d != "right") d = "left";
  else if(key == "38" && d != "down") d = "up";
  else if(key == "39" && d != "left") d = "right";
  else if(key == "40" && d != "up") d = "down";
  
 }) 
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
</style>
</head>
<body>
<!-- canvas对象 -->
<canvas id="canvas" width="450" height="450"></canvas>
</body>
</html>

总结:

贪食蛇的难点

  1. 蛇的存储(节数和坐标,头部信息存入数组顶部)

  2. 根据方向,移动后坐标的变化处理:我们以蛇头为参考,通过方向去改变蛇头坐标,然后下面的蛇身子的坐标依次等于上一个节点的坐标,我们可以知道,运动时,蛇头以后的部分,会移动到蛇身子上一节的位置,(最核心原理

  3. 每次移动头部都会进行插入的操作,插入变化后的坐标,移除的与否与是否吃到食物有关

  4. 根据数组蛇信息,间隔的去清除绘制

13.video的html5视频播放器

调用video的api,构造自定义外观的播放器

测试时,需要一个mp4的视频文件,那些播放,静音需要图片,大家想象去看

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<title></title>
<style>
*{ margin:0; padding:0;}
body{ font-size:12px; font-family:"微软雅黑"}
.html5demo{ width:300px; height:212px; position:relative; background:#000; margin:200px;}
.videotoolsback{ position:absolute; bottom:0px; left:0px; height:30px;width:300px; background:#0C9 repeat-x left top; opacity:0.9; z-index:5px;}
.videotools{ position:absolute; bottom:0px; left:0px; height:30px;width:300px;z-index:999px;}
.play{ float:left; height:14px; width:14px; margin:8px 8px; background:#F33 no-repeat left center; cursor:pointer;}
span.pause{background:#6C9 no-repeat left center;}
.current{ float:left; margin:8px 0; height:14px; line-height:14px; width:50px; text-align:right; color:#fff; font-size:12px;}
.time-s{float:left; margin:5px 0; width:8px; height:20px; background:#C93 no-repeat center top;}
.duration{float:left; margin:8px 0; height:14px; line-height:14px; width:50px;color:#fff; font-size:12px;}
.progressBar{position: relative;width:30px;height: 6px;background: #6495ed; float:left; margin:12px 0; border-radius:3px;}
.timeBar{position: absolute;top: -5px;left:0;height:16px; width:16px; background:url(default/handle.png) no-repeat left top;margin-left:-8px; cursor:pointer;}
.protimeBar{position: absolute; background:#a2cd5a;border-radius:3px; width:0;height: 6px; left:0px; top:0px;}
.muted{ float:right; height:14px; width:19px; margin:8px 8px; background:#CC3 no-repeat left top; cursor:pointer;}
span.truemuted{ background:#936 no-repeat left top;}
.volumeBar{float:right; position: relative;width:50px;height:6px;background: #6495ed;  margin:12px 8px;border-radius:3px;}
.volume{ position: absolute;top: -5px;left: 50%;height:16px; width:16px; background:#C9C no-repeat left top; margin-left:-8px;cursor:pointer;}
.fullscreen{ float:right; height:14px; width:14px; margin:8px 14px 8px 0px; background:#F99 no-repeat left top; cursor:pointer;}
span.unfullscreen{ background:#FC6 no-repeat left top;}
div.full-html5demo{ margin:0; position:fixed; left:0; top:0; z-index:2;}
div.full-videotoolsw{ width:100%;}
.context-toggle{ position:absolute; top:100px; left:0px; width:100%; text-align:center; height:50px; line-height:50px; color:#FFF; display:none; z-index:9999; font-size:16px;}
</style>
</head>
<body>
   <div class="html5demo">
        <video class="video" width="300" height="212" id="video" preload>      
  </video>  
        <!--<audio class="video" width="300" height="212" id="video" preload>
        <source src="" ></source>  
        </audio>-->
        <div class="videotoolsback"></div>     
     <div class="videotools">
         <span class="play" del="1" title="播放暂停"></span>
            <span class="current"></span>
            <span class="time-s"></span>
            <span class="duration"></span>
            <div class="progressBar" title="进程">
      <div class="protimeBar"></div>
               <div class="timeBar"></div>
            </div>
            <span class="fullscreen" del="1" title="全屏"></span>
            <div class="volumeBar" title="音量">
              <div class="volume"></div>
            </div>
            <span class="muted" del="1" title="静音"></span> 
            <!--<div class="control">
                <span class="ff">快进</span>
                <span class="rw">倒带</span>
                <span class="sl">快退</span>
            </div>--> 
     </div>
        <div class="context-toggle">按 ESC 退出全屏</div>
    </div> 
    
    <div style=" height:800px;"></div>                                  
</body>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script>
$(function(){ 
 videoPlay("movie.mp4");
 
 function videoPlay(url){
  var video=document.getElementById("video");
  video.src=url;
  var paly=$(".play");
  //code
  //video.autoplay=true; 
  //播放暂停
  paly.click(function(){
   if(paly.attr("del")==1){
    video.play();
    paly.addClass("pause");
    paly.attr("del",0);
   }else{   
    video.pause();
    paly.removeClass("pause");
    paly.attr("del",1);  
   }
  });
  //载入后显示视频文件总时间
  video.onloadedmetadata=function(){
    var temp_sub=video.duration.toString().substring(0,parseInt(video.duration.toString().indexOf("."))+3).replace(".", ":");
   // alert(getCurrentTime(1000*video.duration));
    $('.duration').text(getCurrentTime(1000*video.duration));
  };
  //视频播放时,进度条显示
  $('.current').text(getCurrentTime(1000*video.currentTime));
  video.ontimeupdate=function(){
   var temp_sub=video.currentTime.toString().substring(0,parseInt(video.currentTime.toString().indexOf("."))+3).replace(".", ":");   
   $('.current').text(getCurrentTime(1000*video.currentTime));
   var currentPos = video.currentTime;     
      var maxduration = video.duration;     
      var percentage = 100 * currentPos / maxduration; 
      $(".timeBar").css('left',percentage+'%');
   $(".protimeBar").css('width',percentage+'%');
     
  };
  //进度条点击
  var timeDrag = false;  
  $('.progressBar').mousedown(function(e) {
     timeDrag = true;
     updatebar(e.pageX);
  });
  //页面抬起
  $(document).mouseup(function(e) {
     if(timeDrag) {
     timeDrag = false;
     updatebar(e.pageX);    
     };
     if(volumeDrag) {
     volumeDrag = false;
     updatevolume(e.pageX);    
     };
  });
  //页面移动
  $(document).mousemove(function(e) {
     if(timeDrag) {
     updatebar(e.pageX);    
     };
     if(volumeDrag) {
     updatevolume(e.pageX);    
     };
  });  
  //点击进度条跳转方法
  var updatebar = function(x) {
     var progress = $('.progressBar');
     var maxduration = video.duration;
     var position = x - progress.offset().left;
     var percentage = 100 * position / progress.width();  
     //点击超出判断
     if(percentage > 100) {
     percentage = 100;
     }
     if(percentage < 0) {
     percentage = 0;
     }
     //进度条跳转到点击位置
     $('.timeBar').css('left', percentage+'%'); 
           $(".protimeBar").css('width',percentage+'%');        
     video.currentTime = maxduration * percentage / 100;
  };
  
  //缓冲属性,缓存数据的最后一个值.
  var startBuffer = function() {
     var maxduration = video.duration;
     var currentBuffer = video.buffered.end(0);
     var percentage = 100 * currentBuffer / maxduration;
     $('.bufferBar').css('width', percentage+'%');
   
     if(currentBuffer < maxduration) {
     setTimeout(startBuffer, 500);
     }
  };
  setTimeout(startBuffer, 500);
  //是否静音
  $('.muted').click(function(){
   video.muted = !video.muted;
   if($(this).attr("del")==1){
      $(this).addClass("truemuted");
      $(this).attr("del",0);
   }else{
    $(this).removeClass("truemuted");
    $(this).attr("del",1);
   };
  });
  //声音控制
  video.volume=0.5;
  var volumeDrag = false;
  $(".volumeBar").mousedown(function(e){ 
     volumeDrag = true;
     updatevolume(e.pageX);
  });  
  //点击声音跳转方法
  var updatevolume = function(x) {
     var volumeBar= $('.volumeBar');
     var position = x - volumeBar.offset().left;
     var percentage = 100 * position / volumeBar.width();    
     //点击超出判断
     if(percentage > 100) {
     percentage = 100;
     }
     if(percentage < 0) {
     percentage = 0;
     }
     //进度条跳转到点击位置
     $('.volume').css('left', percentage+'%');
     video.volume = percentage / 100; 
  };   
  //快进/快退 倒带控制
  //$('.ff').on('click', function() {
 //    video.playbackrate = 3;
 // });
 //  
 // $('.rw').on('click', function() {
 //    video.playbackrate = -3;
 // });
 //  
 // $('.sl').on('click', function() {
 //    video.playbackrate = 0.5;
 // });
  //全屏播放
  var winWidth=$(window).width();
  var winHeight=$(window).height();
  var prossw=winWidth-300;
  var vidWidth=$(".html5demo").width();
  var vidHeight=$(".html5demo").height();
  var vidprossw=$(".progressBar").width();
  $(window).resize(function(){
   winWidth=$(window).width();
   winHeight=$(window).height();
   prossw=winWidth-300;
   if($('.fullscreen').attr("del")==0){   
    $(".html5demo,.video").width(winWidth);
    $(".html5demo,.video").height(winHeight);
    $(".progressBar").width(prossw);    
   }else{    
   };
  });
  $('.fullscreen').click(function(){   
   if($(this).attr("del")==1){
    $(".html5demo").addClass("full-html5demo");
    $(".videotoolsback,.videotools").addClass("full-videotoolsw");
    $(this).addClass("unfullscreen");    
    $(".html5demo,.video").width(winWidth);
    $(".html5demo,.video").height(winHeight);
    $(this).attr("del",0);
    $(".progressBar").width(prossw);
    $(".context-toggle").show();
    setTimeout(function(){$(".context-toggle").hide()},2000);
    
   }else{//unfull    
    $(".html5demo").removeClass("full-html5demo");
    $(".videotoolsback,.videotools").removeClass("full-videotoolsw");
    $(this).removeClass("unfullscreen");    
    $(".html5demo,.video").width(vidWidth);
    $(".html5demo,.video").height(vidHeight);
    $(this).attr("del",1);
    $(".progressBar").width(vidprossw);
    $(".context-toggle").hide();
   };
      
   //fullScreenCancel(video);
  });
  //keyunfull 
   /** Coding Here */
  $(window).keydown(function(e){
   if (e.which === 27) {     
    if($('.fullscreen').attr("del")==0){
    $(".html5demo").removeClass("full-html5demo");
    $(".videotoolsback,.videotools").removeClass("full-videotoolsw");
    $('.fullscreen').removeClass("unfullscreen");    
    $(".html5demo,.video").width(vidWidth);
    $(".html5demo,.video").height(vidHeight);
    $('.fullscreen').attr("del",1);
    $(".progressBar").width(vidprossw);
    }
    $(".context-toggle").hide();
   }
  });
  //全屏播放方法
  //function fullScreenCancel(video){  
//    if(video.requestFullScreen) {  
//   video.requestFullScreen();  
//    } else if(video .webkitRequestFullScreen ) {  
//   video.webkitRequestFullScreen();  
//    } else if(video .mozRequestFullScreen) {  
//   video.mozRequestFullScreen();  
//    }  
//  };  
 };
 
 //从毫秒数得到一个时间格式 
    function  getCurrentTime(ms) { 
  var  s = parseInt(ms / 1000); 
  var  m = parseInt(s / 60); 
  s -= m * 60; 
  var  h; 
  h = parseInt(m / 60); 
  m -= h * 60; 
  return  make2Str(m) + ":" + make2Str(s); 
 };
 //使数字时钟保持两位 
    function  make2Str(i) { 
  if (i < 10)  return  "0" + i; 
  else  return  "" + i; 
 }; 
});
</script>
</html>

14.可拖拽的登陆框

其实拖拽的实现,就是鼠标组合事件的处理

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
 var drag=$("#drag"); 
 var isd=0; 
 var elex=0;
 var eley=0;
 drag.mousedown(function(event){ 
  isd=1;  
  elex=event.pageX-drag.position().left;
  eley=event.pageY-drag.position().top; 
   event.stopPropagation();    // do something
 });
 $(document).mousemove(function(event){ 
  if(isd==1){
   var evx=event.pageX;
   var evy=event.pageY;
   var cx=evx-elex;
   var cy=evy-eley;
   drag.css('left',cx);
   drag.css('top',cy);
    
  }else{}   
   event.stopPropagation();    // do something
 
 });
 $(document).mouseup(function(event){  
 if(isd==1){isd=0;}
  isd=0;
   event.stopPropagation();    // do something
 });
    
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
</style>
</head>
<body>
<div id="drag" style="width:200px; height:200px; top:200px; left:400px; background:#990; position:absolute; padding:100px;">
 登录<input type="text" /><br/>
    密码<input type="text" /><br/>
    <input type="button" value="ok" />
</div>
</body>
</html>

很简单的处理,不过有个问题,就是可以超出屏幕,我们需要做边界处理,移动事件修改如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
 var drag=$("#drag"); 
 var isd=0; 
 var elex=0;
 var eley=0;
 drag.mousedown(function(event){ 
  isd=1;  
  elex=event.pageX-drag.position().left;
  eley=event.pageY-drag.position().top; 
   event.stopPropagation();    // do something
 });
 $(document).mousemove(function(event){ 
  if(isd==1){
   
    var evx=event.pageX;
    var evy=event.pageY;
    var cx=evx-elex;
    var cy=evy-eley;
    if(cx<=0){cx=0;}
    if(cx>$(window).width()-400){cx=$(window).width()-400;}
    if(cy<=0){cy=0;}
    drag.css('left',cx);
    drag.css('top',cy);
   
    
  }else{}   
   event.stopPropagation();    // do something
 
 });
 $(document).mouseup(function(event){  
 if(isd==1){isd=0;}
  isd=0;
   event.stopPropagation();    // do something
 });
    
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
</style>
</head>
<body>
<div id="drag" style="width:200px; height:200px; top:200px; left:400px; background:#990; position:absolute; padding:100px;">
 登录<input type="text" /><br/>
    密码<input type="text" /><br/>
    <input type="button" value="ok" />
</div>
</body>
</html>

15.树形菜单效果

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
$(".boxt li").has("ul").addClass("see")
 $(".boxt .con1").hide();
 $(".boxt .con2").hide();
 $(".boxt .con3").hide();
 $(".boxt .d1").first().find("ul").show();
 $(".boxt .d1").first().removeClass("see");
 $(".boxt .d1").first().find("li").removeClass("see");
 //ge2
 $(".boxt .d1").has("ul").click(function(){  
  $(this).children("ul").toggle()
  $(this).toggleClass("see")
   
  })
 $(".boxt .d2").has("ul").click(function(event){
  $(this).children("ul").toggle()
  $(this).toggleClass("see") 
  event.stopPropagation()   
  
  })
  $(".boxt .d3").has("ul").click(function(event){
  $(this).children("ul").toggle()
  $(this).toggleClass("see") 
  event.stopPropagation()   
  
  })
  //ge3 mao
  $(".boxt .d2").click(function(event){   
   event.stopPropagation() 
   })
  $(".boxt .d3").click(function(event){   
   event.stopPropagation() 
   })
   
   $(".boxt .d4").click(function(event){   
   event.stopPropagation() 
   })
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
.boxt{width:300px; background:#0CF; margin-top:30px;}
.boxt li{ padding-left:30px; background:#C00; margin:2px 0;}
.boxt div{ height:20px; background:#CF3; line-height:20px;}
.boxt li.see{ background:#03F;}
</style>
</head>
<body>
<ul class="wrapper boxt">
 <li class="d1">
     <div class="d11">我是一级1</div>
        <ul class="con1">
                    <li class="d2">
                        <div class="d22">我是二级1</div>
                        <ul class="con2">
                                    <li class="d3">
                                        <div class="d33">我是三级1</div>
                                        <ul class="con3">
                                         <li class="d4">
                                             <div class="d44">我是四级1</div>
                                            </li>
                                        </ul>
                                    </li>
                                    <li class="d3">
                                        <div class="d33">我是三级2</div>
                                         <ul class="con3">
                                         <li class="d4">
                                             <div class="d44">我是四级1</div>
                                            </li>
                                            <li class="d4">
                                             <div class="d44">我是四级2</div>
                                            </li>
                                        </ul>
                                    </li>                                                      
                                </ul>  
                    </li>
                    <li class="d2">
                        <div class="d22">我是二级2</div>
                        <ul class="con2">
                                    <li class="d3">
                                        <div class="d33">我是三级1</div>
                                    </li>
                                    <li class="d3">
                                        <div class="d33">我是三级2</div>
                                    </li>                                                      
                                </ul>
                    </li>
                    <li class="d2">
                        <div class="d22">我是二级3</div>
                    </li>                   
           </ul>
    </li>
    <li class="d1">
     <div class="d11">我是一级2</div>
        <ul class="con1">
                    <li class="d2">
                        <div class="d22">我是二级1</div>
                    </li>
                    <li class="d2">
                        <div>我是二级2</div>
                    </li>
                    <li class="d2">
                        <div class="d22">我是二级3</div>
                    </li>                   
         </ul>
    </li>
    <li class="d1">
     <div class="d11">我是一级3</div>
    </li>
</ul>
</body>
</html>

 16.全选/反全选处理

简单实现

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
var all=$("#all");
     var boxlists=$("#box").find("input:checkbox");
     all.change(function(){
        //alert(all.checked)
        if(all.is(":checked")){
           boxlists.prop('checked',true);
        }else{
           boxlists.prop('checked',false);
        };
         
     });
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/

</style>
</head>
<body>
<br>
    <div style=" height:50px;"><input type="checkbox" id="all">   全选</div>
    
    <div style="width:200px; border:1px solid #000;" id="box">
    <input type="checkbox">  1<br><br>
    <input type="checkbox">  2<br><br>
    <input type="checkbox">  3<br><br>
    <input type="checkbox">  4<br><br>
    <input type="checkbox">  5<br><br>
    <input type="checkbox">  6<br><br>
    <input type="checkbox">  7<br><br>
    </div>
</body>
</html>

 我们实现另一种全选思路。也是树形菜单带有复选框用到的思路

全选后,上面的例子,在去取消被选中的子复选框,发现,全选还是处在选中中,现在,我们的子复选框有一个取消选中,父复选框就取消选中,代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jq插件简单开发</title>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
//start 
var all=$("#all");
     var boxlists=$("#box").find("input:checkbox");
     all.change(function(){
        //alert(all.checked)
        if(all.is(":checked")){
           boxlists.prop('checked',true);
        }else{
           boxlists.prop('checked',false);
        };
         
     });
  boxlists.change(function(){
   var len=$("#box").find("input:checkbox").length;
   var newlen=$("#box").find("input:checkbox:checked").length;
   if(newlen!=len){
     all.prop('checked',false);
  }else{
    all.prop('checked',true);
  }
 });
//end
});
</script>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/

</style>
</head>
<body>
<br>
    <div style=" height:50px;"><input type="checkbox" id="all">   全选</div>
    
    <div style="width:200px; border:1px solid #000;" id="box">
    <input type="checkbox">  1<br><br>
    <input type="checkbox">  2<br><br>
    <input type="checkbox">  3<br><br>
    <input type="checkbox">  4<br><br>
    <input type="checkbox">  5<br><br>
    <input type="checkbox">  6<br><br>
    <input type="checkbox">  7<br><br>
    </div>
</body>
</html>

原理:点击子复选框选择出当前选中的总长度与子复选框个数做长度比较

17.瀑布流效果(未实现)

我说出原理,然后大家自己去写就好了,这个的难度如果把上面的学会了,也是分分钟的了

  1. 等宽不等高

  2. 定位去排列

  3. 我们先拍第一行,加入我们做5列的效果,top都是0,left是width(等宽)*index(第1 2 3 4 5个)就是距离左侧的值

  4. 我们创建一个数组,长度是5,等于一行的数量,把第一行的每个高度对应存入,高度1-5是不同的

  5. 在数组的五个高度数值中,找出对小的,并且取出他在数组的位置

  6. 第2行开始插入,求除了最小高度位置,把第6个元素等位在下面,并且加上新高度,不断求出最小高度值的数组位置,根据位置,去设置top值(高度),和left值(位置)

  7. 一次显示5行,我们滚动加载,滚动事件判断,到达底部,继续加载6-10行

jq的就这些原理,我下面写个css3的,真是一行样式就实现了

.box{ width:1000px; margin:50px auto; border:1px solid #000;-moz-columns:300px;
 -webkit-columns:300px;
 columns:300px;}
</style>

根据总宽度1000px,通过多栏的300px去分配

你可能感兴趣的:(js,jq)