前端 javascript 练习题

前端

javascript

练习题

函数

1.编写任意个数字的求和、差、积、商的函数

思路分析:首先求任意个数,因此需要一个能够获取函数传递参数个数及值的形参:arguments,方法不一,思路仅供参考

function f1(){
    var sum=arguments[0],   //将第一个数符初值分别给这几个变量
            cha=arguments[0],
            ji=arguments[0],
            shang=arguments[0];
    for(var i=1;i<arguments.length;i++){   //用arguments获取用户传入的参数
    sum=sum+arguments[i];
        cha=cha-arguments[i];
        ji=ji*arguments[i];
        shang=shang/arguments[i];
    }
    console.log("he"+sum+"cha"+cha+"ji"+ji+"shang"+shang);
}
f1(1,2,3,4);
2.编写一个函数,计算任意两个数字之间所能组成的奇数个数,数字必须是个位数比如: 计算0-3之间能组成的奇数个是01、21、03、13、23、31

思路分析:两个数字任意组合,先判断是否是奇数,然后再排除个位和十位相同的数即可
方法:

function f3(x,y){
     var count=0;
     for(var i=x;i<=y;i++){  //x和y之间的数任意组合
         for(var j=x;j<=y;j++){ 
           var str=Number(i+""+j);  //将x和y拼接组成2位的数再转化为2位的数字
             if(str%2!=0&&i!=j){
                 console.log(i+""+j);
                 count++;
             }
         }
     }
     console.log(count);
 }
 f3(0,3);
求斐波那契数列

1、1、2、3、5、8、13、21、34、55……F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)

方法:

function f6(n){ //求斐波那契数列
    var a1=1;
    var a2=1;
    for(var i=3;i<=n;i++){
        var an=a1+a2;  //每一项等于前两项的和
        a1=a2;   //每次循环改变a1和a2使其指向下一次的前两项
        a2=an;
    }
    return an;
}
console.log(f6(5));

2、//递归求斐波那契数列

function getFib(x){
   if(x==1||x=2){
       return 1;
    }
    return getFib(x-1)+getFib(x-2);
}
console.log(getFib(12));
数组

1.数组的选择排序,冒泡排序
冒泡排序: 思路在代码中进行了注释,可以根据注释参照思路

var arr3=[1,5,2,6,3,3];

function f4(arr){   //冒泡排序(以从小到大为例)
    for(var i=0;i<arr.length-1;i++){ //控制比较的轮数
        for(var j=0;j<arr.length-1-i;j++){ //内层每轮比较的次数
            if(arr[j]>arr[j+1]){  
                var temp=arr[j];  //交换这两个值的位置
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
    return arr;
}
console.log(f4(arr3));

选择排序:

function f4(arr){ //选择排序
    //用这个数分别和别的数相比较,改变的是索引的位置,每轮结束后才交换为位置
    for(var i=0;i<arr.length-1;i++){  //控制外层比较的轮数
        var minIndex=i;  //先假定一个最小值,定义变量minIndex指向该值的索引
        for(var j=i+1;j<arr.length;j++){
            if(arr[minIndex]>arr[j]){
                minIndex=j;  //改变最小索引的指向
            }
        }
        var temp=arr[i];   //每轮比较结束,将最初假定的最小值和实际最小值交换
        arr[i]=arr[minIndex];
        arr[minIndex]=temp;
    }
    return arr;  //将排序后的数组返回
}
console.log(f4(arr3));

2.判断数组中是否存在某个元素,返回布尔类型
思路分析:判断是否存在某个值,也可以使用indexOf等数组的方法
方法:列举一种普通的

var arr1=[1,4,3,6];

function f2(arr,x){
      for(var i=0;i<arr.length;i++){
          if(arr[i]==x){
              return true;
          }
      }
      return false;
  }

console.log(f2(arr1,4));

3.编写函数将数组元素去重
方法1:推荐使用 (数组和对象结合的方式去重)

var arr1=[1,3,6,6,6,4];

function f3(arr){  //利用数组和对象结合的方式去重
    var newArr=[];
    var obj={};
    for(var i=0;i<arr.length;i++){
        //把数组中的元素当成对象的属性
        if(obj[arr[i]]==undefined){  //如果第一次出现会得到undefined
            newArr.push(arr[i]);  //将第一次出现的值加入到新数组中
            obj[arr[i]]=1;  //给obj对象的属性赋值,使其重复的值得到的结果不为undefined
        }
    }
    return newArr;
}
console.log(f3(arr1));

方法2:(索引值比较,需要注意的是,截取以后数组长度也发生了变化,因此数组长度需要 -1)

function noRepeat(arr){
    for(var i=0;i<arr.length;i++){ //控制外层循环
        for(var j=i+1;j<arr.length;j++){ //控制内层
            if(arr[i]==arr[j]){
                arr.splice(j,1); //从数组中删除元素,此时数组发生改变
                j--;  //此时原数组的索引都向前减了1,因此j--z再去比较一次
            }
        }
    }
    return arr;
}
console.log(noRepeat(arr1));

4.输入一个数,并按原来的规律将它插入数组中
思路分析:可以先进行判断是从大到小,还是从小到大,然后将数据进入插入

var arr2=[1,3,4,5];

function f4(arr,x){
    if(arr[0]>arr[arr.length-1]){
        arr.push(x);  //将传入的参数加入到数组中
        arr.sort(function(a,b){ //调用sort对数组中的元素排序
            return b-a;  //从大到小
        })
    }else {
        arr.push(x);
        arr.sort(function (a,b){
            return a-b;  //从小到大
        })
    }
    return arr;
}
console.log(f4(arr1,0));

5.定义一个含有30个整型元素的数组,按顺序分别赋予从2开始的偶数;然后按顺序每五个数求出一个平均值,放在另一个数组中并输出
方法:

function f1(){
    var arr1=[];  //用来存放最开始的这些数字
    var arr2=[];  //用来存放平均值
    var sum=0;
        for(var i=0;i<30;i++){
            arr1[i]=(i+1)*2;
            sum+=arr1[i];
            if((i+1)%5==0){
                arr2.push(sum/5);
                sum=0;  //每求一次平均值,sum要进行清零
            }
        }
    console.log(arr2);
}
    f1();

6.随机点名程序
思路分析:使用math.random()产生0~1之间的随机数,然后根据索引得到具体值
方法:将人名放入数组中,生成数组的随机索引值,从而得到对应的人名

btn.onclick=function (){
        var arr=["张三","李四","王二","张明","李天","王大","崔勇"];
        var num1 =Math.floor(Math.random()*arr.length);
        var na=arr[num1];
        console.log(na);
}
String

1.密码强度 假设只有大、小写字母及数字
思路分析:可以使用正则表达式(相对简单),也可以根据ASCII码

方法:

var str1 = "123agfdAB";
function f5(str) {
    var flag1 = false, //因为要判断多个分支是否都含有,所以定义多个flag去判断
            flag2 = false,
            flag3 = false;
    for (var i = 0; i < str.length; i++) {
        var code = str.charCodeAt(i);
        if (48 <= code && code <= 57) {   //数字的ASCII码
            flag1 = true;
        }
        if (65 <= code && code <= 90) {  //大写字母的ASCII码
            flag2 = true;
        }
        if (97 <= code && code <= 122) {  //小写字母的ASCII码
            flag3 = true;
        }
    }
    if (flag1 && flag2 && flag3) {  //根据flag的值去判断包含几个分支
        console.log("强");
    } else if (flag1 && flag2 || flag1 && flag3 || flag2 && flag3) {
        console.log("中");
    } else {
        console.log("低");
    }
}
f5(str1);

2.数字字母混合验证码

方法1: 利用字符串中的值随机组合生成

var  str="123456789ABCDEFGHIG";
 function yan(str){
     var str1="";
         for(var i=0;i<4;i++){
             var s =Math.floor(Math.random()*str.length);
             var str1=str1+str[s];
         }
     console.log(str1);
 }
 yan(str);

方法2:利用ASCII码

function yan(){
    var str="";
    while(str.length<4){  //当str的长度不满足重复执行-------生成4位的字符串
        var sCode =Math.floor(Math.random()*(90-48+1)+48);//得到的是数字到大写字母的ASCII 值
        //判断ASCII码的值在数字和字母之间
        if(48<=sCode&&sCode<=57||65<=sCode&&sCode<=90){
            var str=str+String.fromCharCode(sCode);  //将随机值进行拼接
        }
    }
    console.log(str);
}
yan();

3.已知字符串“a,a,b,c,c,d”,统计每个字符出现的次数,结果显示 a 2、b 1、c 2、d1,去掉重复的字符,使结果显示 abcd
方法: 利用数组和对象结合的方式,把数组元素作为对象的属性

var str = "a,a,b,c,c,d";
function f1(str) {
    var arr = str.split(",");  //split返回的是分割后的数组
    var obj = {};  //用来存放数组中的元素
    for (var i = 0; i < arr.length; i++) {
        if (obj[arr[i]] == undefined) {
            obj[arr[i]] = 1;  //用1这个值去表示第一次出现
        } else {
            obj[arr[i]] = obj[arr[i]] + 1;  //出现的次数
        }
    }
    var s = "";  //让obj的属性进行拼接
    for (var i in obj) {
        s += i;
        document.write(i + obj[i] + "&nbsp;");
    }
    document.write(s);   //输出属性拼接后的值
}
f1(str);

留言过滤 :将字符串中指定的字符或字符串替换

var str=“1455-95098888”;

方法1: 替换单个字符,可以利用字符串的索引对应的值进行比较 (charAt同)

function f6(str){
    for(var i=0;i<str.length;i++){
        if(str[i]=="5"){
            str=str.replace("5","*");  //返回替换后的字符串,所以需要定义变量去接收返回的新的字符串
        }
    }
    return str;
}
console.log(f6(str));

方法2: 替换一串,可以用indexOf ,没有这个字符串,返回的结果为-1

function f7(str){
    for(var i=0;i<str.length;i++){
        if(str.indexOf("55")!=-1){
            str=str.replace("55","*");  //返回替换后的字符串,所以需要定义变量去接收返回的新的字符串
        }
    }
    return str;
}
console.log(f7(str));

方法3: 替换一串,可以用substr,截取字符串进行比较,相同再替换

function f8(str){
    for(var i=0;i<str.length;i++){
        if(str.substr(i,3)=="888"){
            str=str.replace("888","*");  //返回替换后的字符串,所以需要定义变量去接收返回的新的字符串
        }
    }
    return str;
}
console.log(f8(str));
Math 对象

1.编写一个函数,获得一个十六进制的随机颜色的字符串(例如:#20CD4F)
方法:

function f2(){
    var str="0123456789abcdef";
    var color="#";
    for(var i=0;i<6;i++){
        var num=Math.floor(Math.random()*str.length);
        color=color+str[num];
    }
    console.log(color);
}
f2();
date对象

数码时钟
思路分析:将时分秒的图片,按照一定规则命名,方便后续根据时间设置图片路径

方法:

<div id="pic">
    <img src="img/0.png" alt="" />
    <img src="img/0.png" alt="" />
    <span>时</span>
    <img src="img/0.png" alt="" />
    <img src="img/0.png" alt="" />
    <span>分</span>
    <img src="img/0.png" alt="" />
    <img src="img/0.png" alt="" />
    <span>秒</span>
</div>

<script>
    function f1(){
        var str="";
        //通过标签获取所有的图片存放在变量imgid中
        var imgid=document.getElementsByTagName("img");
        var oDate = new Date(); //创建时间对象
        var h=oDate.getHours();  //分别去获取当前的时分秒
        var fen=oDate.getMinutes();
        var miao= oDate.getSeconds();
        var h1=h>=10?h:"0"+h;  //保证都是由2位组成
        var fen1=fen>=10?fen:"0"+fen;
        var miao1=miao>=10?miao:"0"+miao;
        str=str+h1+fen1+miao1;  //组合成一个新的字符串
        for(var i=0;i<str.length;i++){  //遍历字符串
            //类比src="img/0.png";
            imgid[i].src='img/'+str[i]+'.png'; //设置每个图片的src路径
        }
    }
    setInterval(f1,1000);  //定时器  后一个参数以毫秒为单位
函数的封装

封装方法:将函数作为对象的参数

eg1:.判断某年份是否为闰年,将日期格式化输出 “2015|08|24”,获得某个月份的天数,判断两个日期相差的天数,获得N天以后的日期

var dateUtil = {
   isLeapYear:function(year){
      if(year%4==0&&year%100!=0 || year%400==0){
         return true;
      }
      return false;
   },
   formatDate:function(date,str){
      var year = date.getFullYear();
      var month = date.getMonth()+1;
      var day = date.getDate();
      if(month < 10){
         month = "0"+month;
      }
      if(day < 10){
         day = "0" + day;
      }
      var ss = year+str+month+str+day
      return ss;
   },
   getDays:function(date){
      var year = date.getFullYear();
      var month = date.getMonth()+1;
      switch(month){
         case 2:
            if(dateUtil.isLeapYear(year)){
               return 29;
            }
            return 28;
            break;
         case 4:
         case 6:
         case 9:
         case 11:
            return 30;
            break;
         default:
            return 31;
      }
   },
   getDiffDays:function(date1,date2){
      //两个日期相减会得到一个相差的毫秒数
      //相差的天时分秒
      var ss = Math.abs((date2-date1)/1000);
      var day = Math.floor(ss/24/3600);
      var hour = Math.floor(ss/3600%24);
      var minute = Math.floor(ss/60%60);
      var second = Math.floor(ss%60);
      return day+"天"+hour+"时"+minute+"分"+second+"秒";
   },
   getNDays:function(n){
      var oDate = new Date();
      oDate.setDate(oDate.getDate()+n);
      return oDate;
   }
};
DOM和BOM

创建表格,添加删除操作
介绍:这是用基本的方式,更便捷的方法是,使用es6提供的模板字符串,代码和效率能提高很多
简单的样式:

a <input type="text"/>
b <input type="text"/>
c <input type="text"/>
<input type="button" value="添加"/>
<table></table>

js实现代码:

var oinput=document.getElementsByTagName("input");
var otable=document.getElementsByTagName("table")[0];
oinput[oinput.length-1].onclick=function(){
    var otr=document.createElement("tr");
    //创建单元格,并且将文本的值加到单元格里
    for(var i=0;i<oinput.length-1;i++){
        var otd=document.createElement("td");
        otd.innerHTML=oinput[i].value;
        otr.appendChild(otd);
    }
    //添加删除按钮,并加入到单元格中
    var otd = document.createElement("td");
        var oSpan = document.createElement("span");
        oSpan.innerHTML = "删除";
        otd.appendChild(oSpan);
        otr.appendChild(otd);
        oSpan.onclick = function(){
            //oTable.removeChild(oTr);
            otable.removeChild(this.parentNode.parentNode);
        }
    otable.appendChild(otr);
}

进度条
html排版样式:

<div class="progressBar">
    <p style=""></p>
</div>
<div class="progressBar">
    <p></p>
</div>
<div class="progressBar">
    <p></p>
</div>

js执行代码:

var opp=document.getElementsByTagName("p");
function progress(obj,num){
    var count=0;
    var timer=setInterval(function(){
        count++;
        obj.style.width=count+"%";
        if(count==num){
            clearInterval(timer);
        }
    },20)
}
progress(opp[0],50);
progress(opp[1],60);
progress(opp[2],80);

简易年历
eg1:将数组中的值输出

改变样式可以直接改样式,也可以修改类名

var okuang=document.getElementById("kuang");
var oli=document.getElementsByTagName("li");
var arr=[11,22,33,44,55];
var index=0;   //定义一个变量用来保存索引值
for(var i=0;i<oli.length;i++){  //遍历给每个li添加事件
    oli[i].onclick=function(){
        for(var j=0;j<oli.length;j++){  //排他功能
            oli[j].style.backgroundColor="#666";
            oli[j].style.color="#fff";
        }
        okuang.innerHTML=arr[index];  //此时不能用arr[i],因为在点击之前for已经执行完了,此时i为oli的元素个数值
        this.style.backgroundColor="red";
        this.style.color="#000";
        index++;
    }
}

解析:
for循环是在页面加载的时候,执行完毕了

//  for(var k=0;k<5;k++){
//  }
//  console.log(k);
  //事件是在触发的时候,执行的

tab切换案例
点击按钮换图片:

var oli=document.getElementsByTagName("li"); //获取li标签
var oimg=document.getElementsByTagName("img")[0];  //获取图片标签
var index=0;  //存储索引值,因为在点击按钮前for已经执行完了
    for(var i=0;i<oli.length;i++){  
        oli[i].onclick=function (){
            oimg.src='images/'+index+'.png';
            index++;
        }
    }

案例
排他功能
一串input

var oinput=document.getElementsByTagName("input");
for(var i=0;i<oinput.length;i++){
    oinput[i].onclick=function(){
        //先让所有的变成原来的样子
        for(var j=0;j<oinput.length;j++){
            oinput[j].value="晴天";
            oinput[j].style.background="#ccc";
        }
        //再设置当前的样式
        this.value="阴天";
        this.style.background="red";
    }
}

通过类名修改样式

var oinput=document.getElementById("btn");
var odiv=document.getElementById("dv");
oinput.onclick=function(){
    //判断是否应用了类样式
    if(odiv.className!="cls"){
        odiv.className="cls";  //当有多个类名时需要注意  留着不需要修改的
    }else{
        odiv.className="dd";
    }
};

tab切换
主要就是排他功能的应用,下面对应的块,选隐藏,找出点击span时对应的li再让它显示

<div class="box" id="box">
    <div class="hd">
        <span class="current">体育</span>
        <span>娱乐</span>
        <span>新闻</span>
        <span>综合</span>
    </div>
    <div class="bd">
        <ul>
            <li class="current">我是体育模块</li>
            <li>我是娱乐模块</li>
            <li>我是新闻模块</li>
            <li>我是综合模块</li>
        </ul>
    </div>
</div>
<script>
var obox=document.getElementById("box");
    var hd=obox.getElementsByTagName("div")[0];
    var bd=obox.getElementsByTagName("div")[1];
    var oli=bd.getElementsByTagName("li");
    var ospan=hd.getElementsByTagName("span");
    for(var i=0;i<ospan.length;i++){
        ospan[i].setAttribute("index",i); //点击之前就把索引保存在span标签中
        ospan[i].onclick=function(){
            //将所有的span样式移除
            for(var j=0;j<ospan.length;j++){
                ospan[j].className="";
                //ospan[j].removeAttribute("class");
            }
           // 设置当前的span类样式
        this.className="current";

           //先将所有地li隐藏
           for(var k=0;k<oli.length;k++){
                oli[k].removeAttribute("class");
           }
            //获取当前被点击的索引值
            var index=this.getAttribute("index");
            //当前点击span对应的li显示
            oli[index].className="current";
        }
    }

动态创建列表

<input type="button" value="动态创建列表" id="btn"/>
<div id="dv"></div>

js代码:

var kungfu=["降龙十八掌", "黯然销魂掌", "葵花宝典", "九阴真经",
    "吸星大法", "如来神掌", "化骨绵掌", "玉女心经", "极乐神功", "辟邪剑谱"];
var dv=document.getElementById("dv");
var oinput=document.getElementsByTagName("input")[0];
//点击按钮创建列表
oinput.onclick=function(){
    var oul=document.createElement("ul");
    for(var i=0;i<kungfu.length;i++){ //有多少个数组元素就创建多少个li
        var oli=document.createElement("li");
        dv.appendChild(oul);
        oul.appendChild(oli);
        oli.innerHTML=kungfu[i];  //给创键的li设置文本和事件
        oli.onmouseover=mouseoverHandle;
        oli.onmouseout=mouseoutHandle;
    }
}
    function mouseoverHandle(){
        this.style.backgroundColor="red";
    }
function mouseoutHandle(){
    this.style.backgroundColor="";
}
//如果是循环的方式添加事件,推荐用命名函数
//如果不是循环的方式添加事件,推荐使用匿名函数

动态创建表格

//点击按钮创建表格
    var arr=[
        {name:"百度",href:"nn1"},
        {name:"谷歌",href:"nn2"},
        {name:"优酷",href:"nn3"},
        {name:"土豆",href:"nn4"},
        {name:"快播",href:"nn5"},
        {name:"爱奇艺",href:"nn6"}
    ];
var btn=document.getElementById("btn");
    var odv=document.getElementById("dv");
    btn.onclick=function(){
        var otable=document.createElement("table");
        otable.cellPadding="0";
        otable.cellSpacing="0";
        otable.border="1"
        //根据数组长度创建表格
        for(var i=0;i<arr.length;i++){
            var otr=document.createElement("tr");
                var otd=document.createElement("td");
                otd.innerHTML=arr[i].name;
                var otd2=document.createElement("td");
                otd2.innerHTML=arr[i].href;
            odv.appendChild(otable);
            otable.appendChild(otr);
            otr.appendChild(otd);
            otr.appendChild(otd2);
        }
    }

只创建一个元素
为了防止不同的人都给同一个元素添加了相同事件,执行次数过多

方式1: 思路(没有才去创建)

<input type="button" value="显示效果" id="btn"/>
<div id="dv"></div>

js代码:

var btn=document.getElementById("btn");
var odiv=document.getElementById("dv");
btn.onclick=function(){
    if(!document.getElementById("an")){
        var oinput=document.createElement("input");
        oinput.type="button";
        oinput.id="an";
        oinput.value="按钮";
        odiv.appendChild(oinput);
    }
}

方式2:思路(有则删除,删除后再去创建)

js代码:

btn.onclick=function(){
  if(document.getElementById("an")){
  odiv.removeChild(document.getElementById("an"));
  }
  var oinput=document.createElement("input");
  oinput.type="button";
  oinput.value="按钮";
  oinput.id="an";
  odiv.appendChild(oinput);
  }

总结一句话就是:无则创建,有则删除

模拟百度搜索框 ------重要
思路:每次键盘抬起都去获取用户输入的内容,并与数组中的数据进行比较,如果有相同的,则获取提取出来加入到下拉框展示出来

简单的布局如下:

<div id="box">
  <input type="text" id="txt" value="">
  <input type="button" value="搜索" id="btn">
</div>

js代码:

var keyWords = ["小杨才是最纯洁的", "小杨才是最帅的", "小段是最猥琐的", "小超是最龌龊的", "传智播客是一个培训机构", "传说在传智有个很帅很纯洁的小杨", "苹果好吃", "苹果此次召回还是没有中国"];
var txt=document.getElementById("txt");
    var btn=document.getElementById("btn");

    //每一次的键盘抬起都判断页面中有没有这个div
    txt.onkeyup= function () {
        if(document.getElementById("dv")) {
            var dv=document.getElementById("dv");
            document.getElementById("box").removeChild(dv);
        }
            //把文本框输入的内容和数组中的每个数据对比
            var text=this.value;
            var arr=[];  //用来存储用户输入的内容
            for(var i=0;i<keyWords.length;i++){
                if(keyWords[i].indexOf(text)==0){
                    arr.push(keyWords[i]);
                }
            }
            //判断文本框是否为空,空则不用创建div
            if(this.value.length==0||arr.length==0){
                if(document.getElementById("dv")){
                    document.getElementById("dv").removeChild("dv");
                }
                return;
            }
            //创建div,把div加入id为box的盒子中
            var dv=document.createElement("div");
            document.getElementById("box").appendChild(dv);
            dv.id="dv";
            dv.style.width="350px";
            dv.style.border="1px solid #ccc";
            //循环遍历临时数组,创建对应的p标签
            for(var i=0;i<arr.length;i++){
                //创建p标签
                var op=document.createElement("p");
                dv.appendChild(op);
                op.innerHTML=arr[i];
                op.onmouseover=function(){
                    this.style.background="red";
                };
                op.onmouseout=function(){
                    this.style.background="";
                };
            }
        };

为同一个元素绑定多个事件
对象.addEventListener(“事件类型”,事件处理函数,false);

对象.attachEvent(“有on的事件类型”,事件处理函数); 只有ie支持

封装缓动动画函数
js代码:

//动画函数---任意一个元素移动到指定的目标位置
function f1(ele,target){
    clearInterval(ele.timer);  //确保元素只有一个定时器
//动画函数---任意一个元素移动到指定的目标位置
    ele.timer=setInterval(function(){  //定时器的id值存储到对象的一个属性中
        var cur=ele.offsetLeft; //获取当前元素坐标
        var step=(target-cur)/10;
        step=step>0?Math.ceil(step):Math.floor(step);
        cur+=step;
        //判断当前移动后的位置是否到达目标位置
        if(cur==target){
            clearInterval(ele.timer);  //清理指定元素的定时器
        }
        ele.style.left=cur+"px";
    },20);
}

封装动画函数,改变任意多个属性和回调函数
js代码:

 function animate(element, json, fn) {
    clearInterval(element.timeId);//清理定时器
    element.timeId = setInterval(function () {
      var flag = true;//默认,假设,全部到达目标
      //遍历json对象中的每个属性还有属性对应的目标值
      for (var attr in json) {
        if (attr == "opacity") { //判断这个属性attr中是不是opacity
          //获取元素的当前的透明度,当前的透明度放大100倍
          var current = getStyle(element, attr) * 100;
          var target = json[attr] * 100;//目标的透明度放大100倍
          var step = (target - current) / 10;
          step = step > 0 ? Math.ceil(step):Math.floor(step);//step<0时不用加-号
          current += step;//移动后的值
          element.style[attr] = current / 100;
        } else if (attr == "zIndex") { //判断这个属性attr中是不是zIndex
          //层级改变就是直接改变这个属性的值
          element.style[attr] = json[attr];
        } else {
          //普通的属性
          //获取元素这个属性的当前的值
          var current = parseInt(getStyle(element, attr));
          var target = json[attr];  //当前的属性对应的目标值
          var step = (target - current) / 10; //移动的步数
          step = step > 0 ? Math.ceil(step) : Math.floor(step);
          current += step;//移动后的值
          element.style[attr] = current + "px";
        }
        if (current != target) {   //是否到达目标
          flag = false;
        }
      }
      if (flag) {
        //清理定时器
        clearInterval(element.timeId);
        //所有的属性到达目标才能使用这个函数,前提是用户传入了这个函数
        if (fn) {
          fn();
        }
      }
    }, 20);
  }

完整的轮播图 --------重要
思路:图片和小按钮分别放在不同的盒子里,然后去设置左右焦点的事件,和小按钮的事件,为小按钮添加事件之前先把索引保存到li的自定义属性中。

左右焦点有临界值,需要去判断第一个和最后一个

小按钮需要设置样式,及第一个和的最后一个转换时小按钮对应的样式

简单的布局代码:

<div class="all" id='box'>
    <div class="screen"><!--相框-->
        <ul>
            <li><img src="img/1.jpg" width="500" height="200"/></li>
            <li><img src="img/2.jpg" width="500" height="200"/></li>
            <li><img src="img/3.jpg" width="500" height="200"/></li>
            <li><img src="img/4.jpg" width="500" height="200"/></li>
            <li><img src="img/5.jpg" width="500" height="200"/></li>
        </ul>
        <ol>  //用来存放小按钮
        </ol>
    </div>
    <div id="arr"><span id="left">&lt;</span><span id="right">&gt;</span></div>
</div>

js代码:

<script>
    var box = document.getElementById("box");
    var kuang = box.children[0];
    var kwidth = kuang.offsetWidth;
    var oul = kuang.children[0];
    var ol = kuang.children[1];
    var oli = oul.children;
    var arr = box.children[1]; //焦点
    var lf = document.getElementById("left");
    var rg = document.getElementById("right");
    box.onmouseover = function () {
        arr.style.display = "block";
        clearInterval(timer);
    }
    box.onmouseout = function () {
        arr.style.display = "none";
        timer=setInterval(clickHandle,2000);
    };
    
    //根据li的个数去创建小按钮
    var pic=0;
    for(var i=0;i<oli.length;i++){
        var list=document.createElement("li");
        ol.appendChild(list);
        list.setAttribute("index",i);
        list.innerHTML=(i+1);
        list.onmouseover=function(){
            for(var j=0;j<ol.children.length;j++){
                ol.children[j].className="";
            }
            this.className="current";
            pic=this.getAttribute("index");
            f1(oul,-pic*kwidth);
        };
        list.onmouseout=function(){
            this.className="";
        }
    }
    
   //设置ol中第一个li有背景颜色
    ol.children[0].className="current";
//克隆克隆一个ul中第一个li,加入到ul中的最后
    oul.appendChild(oul.children[0].cloneNode(true));
    //自动播放
    var timer=setInterval(clickHandle,2000);
   
   //右边的按钮
    rg.onclick=clickHandle;
    function clickHandle(){
        if(pic==oli.length-1){ //pic中存的是索引值
            pic=0;
            oul.style.left=0;
        }
        pic++;
    f1(oul,-pic*kwidth);
    if(pic==oli.length-1){
        ol.children[ol.children.length-1].className="";
        ol.children[0].className="current";
    }else {
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = ""
        }
        ol.children[pic].className= "current";
    }
    }
   
   //左边的按钮
    lf.onclick=function(){
    if(pic==0){
        pic=4;
        oul.style.left=-pic*kwidth+"px";
    }
    pic--;
        f1(oul,pic*kwidth);
        for(var j=0;j<oli.length;j++){
            oli[j].className="";
        }
        this.className="current";
}
    //运动函数
    function f1(ele, target) {
        clearInterval(ele.timer);
        var current = ele.offsetLeft;
        ele.timer = setInterval(function () {
            var step = 10;
            step = current < target ? step : -step;
            current += step;
            if (Math.abs(target - current) < Math.abs(step)) {
                clearInterval(ele.timer);
                ele.style.left = target + "px";
            } else {
                ele.style.left = current + "px";
            }
        }, 20);
    }

筋头云案例:
基本布局代码:

<div class="nav">   //相对定位
  <span id="cloud"></span>  //绝对定位
  <ul id="navBar">  
    <li>北京校区</li>
    <li>上海校区</li>
    <li>广州校区</li>
    <li>深圳校区</li>
    <li>武汉校区</li>
    <li>关于我们</li>
    <li>联系我们</li>
    <li>招贤纳士</li>
  </ul>
</div>

js代码:

//匀速动画
function animate(element, target) {
  clearInterval(element.timeId);  //清理定时器
  element.timeId = setInterval(function () {
    var current = element.offsetLeft;  //获取元素的当前位置
    var step = (target - current) / 10; //移动的步数
    step = step > 0 ? Math.ceil(step) : Math.floor(step);
    current += step;
    element.style.left = current + "px";
    if (current == target) {
      //清理定时器
      clearInterval(element.timeId);
    }
   }, 20);
}

var cloud = my$("cloud");  //获取云彩
var list = my$("navBar").children;  //获取所有的li标签
for (var i = 0; i < list.length; i++) {//给所有的li注册鼠标进入,鼠标离开,点击事件
  list[i].onmouseover = mouseoverHandle; //鼠标进入事件
  list[i].onclick = clickHandle;  //点击事件
  list[i].onmouseout = mouseoutHandle;  //鼠标离开事件
}
function mouseoverHandle() {//进入
  animate(cloud, this.offsetLeft);
}
var lastPosition = 0;
function clickHandle() {//点击
  lastPosition = this.offsetLeft;//点击的时候,记录此次点击的位置
}
function mouseoutHandle() {//离开
  animate(cloud, lastPosition);
}

手风琴案例
简单的布局:

<div id="box">
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

js实现代码:

<script src="common.js"></script>
<script>

  //获取任意一个元素的任意一个属性的当前的值---当前属性的位置值
  function getStyle(element, attr) {
    return window.getComputedStyle ? window.getComputedStyle(element, null)[attr] : element.currentStyle[attr] || 0;
  }
  function animate(element, json, fn) {
    clearInterval(element.timeId);//清理定时器
    //定时器,返回的是定时器的id
    element.timeId = setInterval(function () {
      var flag = true;//默认,假设,全部到达目标
      //遍历json对象中的每个属性还有属性对应的目标值
      for (var attr in json) {
        //判断这个属性attr中是不是opacity
        if (attr == "opacity") {
          //获取元素的当前的透明度,当前的透明度放大100倍
          var current = getStyle(element, attr) * 100;
          //目标的透明度放大100倍
          var target = json[attr] * 100;
          var step = (target - current) / 10;
          step = step > 0 ? Math.ceil(step) : Math.floor(step);
          current += step;//移动后的值
          element.style[attr] = current / 100;
        } else if (attr == "zIndex") { //判断这个属性attr中是不是zIndex
          //层级改变就是直接改变这个属性的值
          element.style[attr] = json[attr];
        } else {
          //普通的属性
          //获取元素这个属性的当前的值
          var current = parseInt(getStyle(element, attr));
          //当前的属性对应的目标值
          var target = json[attr];
          //移动的步数
          var step = (target - current) / 10;
          step = step > 0 ? Math.ceil(step) : Math.floor(step);
          current += step;//移动后的值
          element.style[attr] = current + "px";
        }
        //是否到达目标
        if (current != target) {
          flag = false;
        }
      }
      if (flag) {
        //清理定时器
        clearInterval(element.timeId);
        //所有的属性到达目标才能使用这个函数,前提是用户传入了这个函数
        if (fn) {
          fn();
        }
      }
      //测试代码
      console.log("目标:" + target + ",当前:" + current + ",每次的移动步数:" + step);
    }, 20);
  }

  //先获取所有的li标签
  var list = my$("box").getElementsByTagName("li");
  for (var i = 0; i < list.length; i++) {
    list[i].style.backgroundImage = "url(images/" + (i + 1) + ".jpg)";
    //鼠标进入
    list[i].onmouseover = mouseoverHandle;
    //鼠标离开
    list[i].onmouseout = mouseoutHandle;
  }
  //进入
  function mouseoverHandle() {
    for (var j = 0; j < list.length; j++) {
      animate(list[j], {"width": 100});//动画效果
    }
    animate(this, {"width": 800});
  }
  //离开
  function mouseoutHandle() {
    for (var j = 0; j < list.length; j++) {
      animate(list[j], {"width": 240});//动画效果
    }
  }


</script>

图片跟着鼠标飞:

 //图片跟着鼠标飞,可以在任何的浏览器中实现
  //window.event和事件参数对象e的兼容
  //clientX和clientY单独的使用的兼容代码
  //scrollLeft和scrollTop的兼容代码
  //pageX,pageY和clientX+scrollLeft 和clientY+scrollTop

  //把代码封装在一个函数

  //把代码放在一个对象中
  var evt={
    //window.event和事件参数对象e的兼容
    getEvent:function (evt) {
      return window.event||evt;
    },
    //可视区域的横坐标的兼容代码
    getClientX:function (evt) {
      return this.getEvent(evt).clientX;
    },
    //可视区域的纵坐标的兼容代码
    getClientY:function (evt) {
      return this.getEvent(evt).clientY;
    },
    //页面向左卷曲出去的横坐标
    getScrollLeft:function () {
      return window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft||0;
    },
    //页面向上卷曲出去的纵坐标
    getScrollTop:function () {
      return window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop||0;
    },
    //相对于页面的横坐标(pageX或者是clientX+scrollLeft)
    getPageX:function (evt) {
      return this.getEvent(evt).pageX? this.getEvent(evt).pageX:this.getClientX(evt)+this.getScrollLeft();
    },
    //相对于页面的纵坐标(pageY或者是clientY+scrollTop)
    getPageY:function (evt) {
      return this.getEvent(evt).pageY?this.getEvent(evt).pageY:this.getClientY(evt)+this.getScrollTop();
    }



  };
  //最终的代码

  document.onmousemove=function (e) {
    my$("im").style.left=evt.getPageX(e)+"px";
    my$("im").style.top=evt.getPageY(e)+"px";
  };

滚动条案例
api第七天案例

钢琴版导航条:
css样式:

 * {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    
    .nav {
      width: 900px;
      height: 60px;
      background-color: black;
      margin: 0 auto;
    }
    
    .nav li {
      width: 100px;
      height: 60px;
      /*border: 1px solid yellow;*/
      float: left;
      position: relative;
      overflow: hidden;
    }
    
    .nav a {
      position: absolute;
      width: 100%;
      height: 100%;
      font-size: 24px;
      color: blue;
      text-align: center;
      line-height: 60px;
      text-decoration: none;
      z-index: 2;
    }
    
    .nav span {
      position: absolute;
      width: 100%;
      height: 100%;
      background-color: yellow;
      top: 60px;
    }

jq实现代码: 需要引入jq文件

$(function () {
      //给li注册鼠标进入事件,让li下面的span top:0  播放音乐
      $(".nav li").mouseenter(function () {
        $(this).children("span").stop().animate({top: 0});
        //播放音乐
        var idx = $(this).index();
        $(".nav audio").get(idx).load();
        $(".nav audio").get(idx).play();
      }).mouseleave(function () {
        $(this).children("span").stop().animate({top: 60});
      });
      
      //节流阀  :按下的时候,触发,如果没弹起,不让触发下一次
      //1. 定义一个flag
      var flag = true;
      
      
      //按下1-9这几个数字键,能触发对应的mouseenter事件
      $(document).on("keydown", function (e) {
        if(flag) {
          flag = false;
          //获取到按下的键
          var code = e.keyCode;
          if(code >= 49 && code <= 57){
            //触发对应的li的mouseenter事件
            $(".nav li").eq(code - 49).mouseenter();
          }
        }
       
      });
  
      $(document).on("keyup", function (e) {
        flag = true;
        
        //获取到按下的键
        var code = e.keyCode;
        if(code >= 49 && code <= 57){
          //触发对应的li的mouseenter事件
          $(".nav li").eq(code - 49).mouseleave();
        }
      });
      
      //弹起的时候,触发mouseleave事件
      
    });
事件

键盘控制div移动
如果需要在页面中移动,要将元素脱离文档流(否则会影响页面布局)

<div style="position: absolute;background-color:pink;width: 60px;height: 60px;"></div>

js实现代码:

var odiv=document.getElementsByTagName("div")[0];
document.onkeydown=function(e){
    var evt=e||event; 
    var x=odiv.offsetLeft;  //获取div的坐标值
    var y=odiv.offsetTop;
    var code=evt.keyCode;  //获取键盘码
    switch (code){   //当按下方向键,执行对应的功能
        case 38:
            odiv.style.left=x+"px";
            odiv.style.top=y-10+"px";
            break;
        case 40:
            odiv.style.left=x+"px";
            odiv.style.top=y+10+"px";
            break;
        case 37:
            odiv.style.left=x-10+"px";
            odiv.style.top=y+"px";
            break;
        case 39:
            odiv.style.left=x+10+"px";
            odiv.style.top=y+"px";
            break;
    }
}

鼠标跟随特效:
js实现代码:

for(var i=0;i<10;i++){  //创建10个div,并加入到页面中
    var dv=document.createElement("div");
    document.body.appendChild(dv);
}
var odiv=document.getElementsByTagName("div");
document.onmousemove=function(e){
    var evt=e||event;
    var x=evt.clientX;  //获取鼠标的坐标
    var y=evt.clientY;
    odiv[0].style.left=x+"px";  //让第一个跟随鼠标移动
    odiv[0].style.top=y+"px";
    //让后一个跟随前一个移动
    for(var i=odiv.length-1;i>0;i--){
        odiv[i].style.left=odiv[i-1].style.left;
        odiv[i].style.top=odiv[i-1].style.top;
    }
}
事件委托机制 ----------重要

eg:点击按钮往ul中添加li,使添加的li也有相同的事件

var obtn=document.getElementById("btn");
    var olist=document.getElementById("list");  //获取ul
    var oli=olist.children;  //获取ul的子节点li
   olist.onclick=function(e){
       var evt=e||event;
       var tar=evt.target||evt.srcElement;  //获取事件源
       if(tar.nodeName.toLowerCase()=="li"){  判断事件源是不是是该执行目标
           console.log(tar.innerHTML); //此时不能用this,因为this指向的是ul
       }
   }
    obtn.onclick=function(){
        for(var i=0;i<4;i++){
            var lli=document.createElement("li");
            lli.innerHTML="aaaa";
            olist.appendChild(lli);
        }
    }

拖拽效果

var odiv=document.getElementsByTagName("div")[0];
odiv.onmousedown=function(e){  //按下鼠标的事件
    var evt=e||event;
    var lf=evt.offsetX;
    var tp=evt.offsetY;
  document.onmousemove=function(e){  //鼠标移动事件
       var evt=e||event;
        var x=evt.clientX-lf;  //让鼠标一直在按下的那个位置
       var y=evt.clientY-tp;
      //设置元素只能在可视区域内移动
      if(x<=0){
          x=0;
      }
      if(x>=document.documentElement.clientWidth-odiv.offsetWidth){
        x=document.documentElement.clientWidth-odiv.offsetWidth
      }
      if(y<=0){
          y=0;
      }
        if(y>=document.documentElement.clientHeight-odiv.offsetHeight){
            y=document.documentElement.clientHeight-odiv.offsetHeight;
        }
      odiv.style.left=x+"px";  //让元素跟着鼠标移动
      odiv.style.top=y+"px";
    }
    document.onmouseup=function(){  //鼠标抬起事件
        document.onmousemove=null;
    }
}

九宫格
js代码:

var obox=document.getElementById("box");
    //创建结构
    for(var i=0;i<3;i++){  //控制外层的行数
        for(var j=0;j<3;j++){  //控制内层
            var odiv=document.createElement("div");
            obox.appendChild(odiv);
           /* var r=Math.floor(Math.random()*256);
            var g=Math.floor(Math.random()*256);
            var b=Math.floor(Math.random()*256);*/
            odiv.style.backgroundColor="rgb("+Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256)+")";  //字符串拼接
            odiv.style.left=j*(odiv.offsetWidth+10)+"px";
            odiv.style.top=i*(odiv.offsetHeight+10)+"px";

        }
    }
    var strarr=["a","b","c","d","e","f","g","h","i","m"];
    var child=obox.children;
    //给每个小块加上文字
    for(var i=0;i<child.length;i++){
        child[i].innerHTML=strarr[i];
    }
    
//拖拽
    for(var i=0;i<child.length;i++){
        child[i].onmousedown=function(e){
            var evt=e||event;
            var lf=evt.offsetX;
            var tp=evt.offsetY;
            var current=this;  //将this保存current中 ,因为上下指向的this不同
            //因为拖动的时候原位置,还需要有东西,所以才克隆
            var clone=current.cloneNode(); //克隆一个当前的元素,并添加到盒子里
                clone.style.border="1px dashed #000";
//            obox.appendChild(clone);  //因为添加之后克隆的索引在最后,
// 后面需要进行距离比较,所以需要将克隆节点和当前节点进行替换
            obox.replaceChild(clone,current);  //用克隆的节点替换当前节点
            obox.appendChild(current);  //把当前节点加到盒子里
            current.style.zIndex=1;
            document.onmousemove=function(e){
                var evt=e||event;
                var x= e.clientX-lf-obox.offsetLeft;
                var y= e.clientY-tp-obox.offsetTop;
                //当前对象的坐标:随着鼠标移动
                current.style.left=x+"px";
                current.style.top=y+"px";
                return false;  //取消默认行为
            }
            document.onmouseup=function(){
                //将当前的这个和剩下所有的进行比较,找出距离最近的
                //将当前放到距离最近的位置,最近的那个放到克隆的位置
                var arr=[];
                var newarr=[];
                //以为此时当前节点的索引在最后,不需要和自身比较,所以去掉最后一个索引
                for(var i=0;i<child.length-1;i++){
                    var wid=current.offsetLeft-child[i].offsetLeft;
                    var hei=current.offsetTop-child[i].offsetTop;
                    var juli=Math.sqrt(Math.pow(wid,2)+Math.pow(hei,2));
                    arr.push(juli);
                    newarr.push(juli);
                }
                arr.sort(function(a,b){
                    return a-b;
                })
                var min=arr[0];
                var minindex=newarr.indexOf(min);

                //交换位置:当前的坐标为最小距离对应的位置,最小值的放在克隆所在的位置
                current.style.left=child[minindex].style.left;
                current.style.top=child[minindex].style.top;

                child[minindex].style.left=clone.style.left;
                child[minindex].style.top=clone.style.top;

                obox.removeChild(clone); //交换位置之后将克隆的节点删除
                document.onmousemove=null;
                document.onmouseup=null;
            }
        }
    }

轨迹
js代码:

var odiv = document.getElementsByTagName("div")[0];
var arr=[];  //用来保存鼠标移动时的坐标位置
document.onmousedown = function (e) {
    var evt1 = e || event;
    var x=evt1.clientX;
    var y=evt1.clientY;
    arr.push({pagex:x,pagey:y});
    document.onmousemove=function(e){
        var evt = e || event;
        var x = evt.clientX;
        var y = evt.clientY;
        arr.push({pagex:x,pagey:y}); //采用对象数组存储,因为坐标成对好进行操作
        return false;  //取消浏览器的默认行为
        //console.log(arr);
    }
    document.onmouseup=function(){
        var timer=setInterval(function(){
            odiv.style.left=arr[0].pagex+"px";
            odiv.style.top=arr[0].pagey+"px";
            arr.splice(0,1); //让元素坐标始终从0开始,splice会改变原数组长度
            if(arr.length==0){ //当数组长度为0,说明保存的坐标执行完了
                clearInterval(timer);
            }
        },20);
        document.onmousemove=null;
    }
}
cookie

一周内免登录
样式代码:

<form action="">
    姓名:<input type="text" id="usename"/><br />
    密码:<input type="text" i="mima"/><br />
    一周内免登陆<input type="checkbox" />
    <input type="button" id="btn" value="登录"/><br />
</form>

js功能代码:

 var input=document.getElementsByTagName("input");
  if(getCookie("usename")){  //判端cookie是否有数据
     input[0].value=getCookie("usename");
      input[1].value=getCookie("password");
      input[2].checked=true;
  }
  input[3].onclick=function(){
      if(input[2].checked){
          setCookie("usename",input[0].value,1);
          setCookie("password",input[1].value,1);
      }else{
          removeCookie("usename");
          removeCookie("password");
      }
  }

  //将函数作为对象的方法进行封装
    function setCookie(name,value,n){
         var date=new Date();
         date.setDate(date.getDate()+n);
        //name+"="+value+";"+"expires"+"="+odate;
      document.cookie=name+"="+value+";"+"expires"+"="+date;
     }
    function getCookie(name){
         var str=document.cookie;
         var arr=str.split(";");
         for(var i=0;i<arr.length;i++){
             var newArr=arr[i].split("=");
             if(newArr[0]==name){
                  return newArr[1];
             }
         }
     }
    function removeCookie(name){
        setCookie(name, 11, -2);
    }
购物车

产品页面js代码:

<script type="text/javascript">
//商品数据  后台传过来
var data = [{
   "id":10001,
   "title":"蒙牛",
   "price":60,
   "imgUrl":"img/photo1.jpg"
},{
   "id":10002,
   "title":"婚纱照",
   "price":19999,
   "imgUrl":"img/photo2.jpg"
},{
   "id":10003,
   "title":"加湿器",
   "price":100,
   "imgUrl":"img/photo3.jpg"
}];

//生成结构
var oUl = document.getElementById("productList");
var str = "";
for(var i = 0; i < data.length; i++){
   str += "<li><img src='"+data[i].imgUrl+"'><p>"+data[i].title+"</p><p>"+data[i].price+"</p><input class='addBtn' type='button' data-id='"+data[i].id+"' value='加入购物车'></li>";
}
oUl.innerHTML = str;

//加入购物车
var cartNum = document.getElementById("cartNum");
var oNum = cartNum.children[0];
var count = 0;


var addBtns = document.getElementsByClassName("addBtn");
//定义一个对象,去保存id和数量 判断cookie里有没有存过数据,有就用,没有就赋值为{}
if(getCookie("cart")){
   var obj = JSON.parse(getCookie("cart"));//将json字符串转换成对象的
}else{
   var obj = {};
}
//取所有购物车商品数量
for(var i in obj){
   count += obj[i];
}
oNum.innerHTML = count;

for(var i = 0; i < addBtns.length; i++){
   addBtns[i].onclick = function(){
      //存数据时 存id:num cart {"10001":1,"10002":3}
      //考虑如果取到加入购物车的商品id
      var prodId = this.getAttribute("data-id");
      if(obj[prodId]==undefined){
         obj[prodId] = 1;
      }else{
         obj[prodId]++;
      }
      
      //把这个对象存到cookie
      
      //console.log(obj);
      
      var objToStr = JSON.stringify(obj);//将js对象(数组,对象)转换成JSON格式的字符串
      
      setCookie("cart",objToStr,7);
      
      //显示购物篮中的数量
      oNum.innerHTML = ++count;

   }
}
</script>

cart页面的js代码:

<script type="text/javascript">
   /*var data = [{
      "id":10001,
      "title":"蒙牛",
      "price":60,
      "imgUrl":"img/photo1.jpg"
   },{
      "id":10002,
      "title":"婚纱照",
      "price":19999,
      "imgUrl":"img/photo2.jpg"
   },{
      "id":10003,
      "title":"加湿器",
      "price":100,
      "imgUrl":"img/photo3.jpg"
   }];*/
   var data = {"10001":{
      "id":10001,
      "title":"蒙牛",
      "price":60,
      "imgUrl":"img/photo1.jpg"
   },"10002":{
      "id":10002,
      "title":"婚纱照",
      "price":19999,
      "imgUrl":"img/photo2.jpg"
   },"10003":{
      "id":10003,
      "title":"加湿器",
      "price":100,
      "imgUrl":"img/photo3.jpg"
   }};
   var oList = document.getElementById("cartList");
   var obj = {};
   if(getCookie("cart")){
      obj = JSON.parse(getCookie("cart"));
   }
   var str = "";
   for(var i in obj){
      /*for(var j = 0; j < data.length; j++){
         if(i==data[j].id){
            str += "<li><img src='"+data[j].imgUrl+"'><span>"+data[j].title+"</span><span>"+data[j].price+"</span><span>"+obj[i]+"</span></li>"
         }
      }*/
   str += "<li><img src='"+data[i].imgUrl+"'><span>"+data[i].title+"</span><span>"+data[i].price+"</span><span>"+obj[i]+"</span></li>"
      
   }
   oList.innerHTML = str;
</script>
正则表达式

表单验证

简单的布局:

<div class="container" id="dv">
  <label for="qq">Q Q</label><input type="text" id="qq"><span></span><br/>
  <label>手机</label><input type="text" id="phone"><span></span><br/>
  <label>邮箱</label><input type="text" id="e-mail"><span></span><br/>
  <label>座机</label><input type="text" id="telephone"><span></span><br/>
  <label>姓名</label><input type="text" id="fullName"><span></span><br/>
</div>

js代码:

  checkInput(my$("qq"),/^\d{5,11}$/);  //qq的
  checkInput(my$("phone"),/^\d{11}$/);    //手机
  checkInput(my$("e-mail"),/^[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}$/);     //邮箱
  checkInput(my$("telephone"),/^\d{3,4}[-]\d{7,8}$/);   //座机号码
  checkInput(my$("fullName"),/^[\u4e00-\u9fa5]{2,6}$/);    //中文名字
//通过正则表达式验证当前的文本框是否匹配并显示结果
  function checkInput(input,reg) {
    //文本框注册失去焦点的事件
    input.onblur=function () {
      if(reg.test(this.value)){
        this.nextElementSibling.innerText="正确了";
        this.nextElementSibling.style.color="green";
      }else{
        this.nextElementSibling.innerText="让你得瑟,错了吧";
        this.nextElementSibling.style.color="red";
      }
    };
  }
运动

圆周运动
简单的布局: 一个小球围绕大球转动

<div id="box">   相对定位
    <div id="circal"></div>  子对定位  //注意小球的margin值
</div>    

js实现代码: //思路:让球的坐标随角度变化而变化

var box=document.getElementById("box");
 var circal=document.getElementById("circal");
 var count=0;
 var r=box.offsetWidth/2;
 var timer=setInterval(function(){
      count++;
     var x=r+r*Math.cos(count*Math.PI/180);
     //x=r+r*cosa;  math中用的是弧度值 记住了
     var y=r-r*Math.sin(count*Math.PI/180);
     circal.style.left=x+"px";
     circal.style.top=y+"px";
 },20);

平抛运动
简单的布局:

<div id="ball"></div>

js代码: //利用平抛的原理,让球的位置发生改变

var ball=document.getElementById("ball");
var count=0;
var timer=setInterval(function(){
    //x=vt;y=0.5*10*t*t;
     count++;
    var t=count*0.02;
    var x=30*t;
    var y=0.5*10*t*t;
    ball.style.left=x+"px";
    ball.style.top=y+"px";
    if(x>600||y>600){
        clearInterval(timer);
    }
},20);

抛物线运动
简单的布局

<div id="ball"></div>
<div id="cart"></div>

js实现代码: 思路:先求出抛物线函数,然后再确定球的位置坐标

var ball=document.getElementById("ball");
var cart=document.getElementById("cart");
var count=0;
    var timer=setInterval(function(){
        count+=2;
        var x1=ball.offsetLeft;
        var y1=ball.offsetTop;
         var x2=cart.offsetLeft;
        var y2=cart.offsetTop;
        //假设抛物线过原点 y=ax*x+b*x+c;  a给定的值,c=0;
        var a=0.0005;
        var b=((y2-y1)-a*(x2-x1)*(x2-x1))/(x2-x1); //相当于抛物线函数求出来了
        var x=count;
        var y=a*x*x+b*x;
        ball.style.left=x1+x+"px";
        ball.style.top=y1+y+"px";
        if(ball.offsetLeft>=x2){
            clearInterval(timer);
        }
    },20);

效果案例

startMove.js
function startMove(obj, json, fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function() {
        var flag = true; //假设所有属性都达到目标值
        for(var attr in json) {
            var iTarget = json[attr];
            if(attr == "opacity"){
                var iCur = parseInt(getStyle(obj, attr)*100);
            }else{
                var iCur = parseInt(getStyle(obj, attr));
            }
            
            var iSpeed = (iTarget - iCur) / 7;
            iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
            
            if(attr == "opacity"){
                obj.style.opacity = (iCur + iSpeed)/100;
                obj.style.filter = "alpha(opacity="+(iCur + iSpeed)+")";    
            }else{
                obj.style[attr] = iCur + iSpeed + "px";
            }
            
            
            //只要有一个达到目标值,定时器就会被清除,会导致部分属性没有达到目标值
            //所有属性都达到目标值时,清除定时器
            if(iCur != iTarget) { //假设是否成立由此判断
                flag = false;
            }
        }

        if(flag) { //如果假设成立,清除定时器
            clearInterval(obj.timer);
            if(fn) {
                fn();
            }
        }

    }, 20)
}

//获取属性值
function getStyle(obj, attr) {
    if(obj.currentStyle) {
        return obj.currentStyle[attr];
    }
    return getComputedStyle(obj, null)[attr];
轮播图

css样式

<style type="text/css">
            body,ul,li{
                padding: 0;
                margin: 0;
            }
            li{
                list-style: none;
            }
            img{
                display: block;
                border: none;
            }
            #scrollBanner{
                width: 900px;
                height: 300px;
                overflow: hidden;
                position: relative;
                }
            #scrollList {
                position: absolute;
                height: 300px;
            }
            #scrollList li{
                float: left;
                width: 900px;
                height: 300px;
            }
            #scrollList img{
                width: 900px;
                height: 300px;
            }
            #btns div{
                position: absolute;
                top: 50%;
                width: 50px;
                height: 50px;
                margin-top: -25px;
                background: #000;
                opacity: .3;
                line-height: 50px;
                text-align: center;
                font-size: 50px;
                color: white;
                cursor: pointer;
            }
            #btns div:first-child{
                left:50px;
            }
            #btns div:last-child{
                right:50px;
            }
            #nums{
                position: absolute;
                bottom: 20px;
                right: 20px;
            }
            #nums li{
                float: left;
                width: 20px;
                height: 20px;
                text-align: center;
                line-height: 20px;
                background: white;
                color: red;
                cursor: pointer;
                margin:0 10px;
                border-radius: 50%;
            }
            #nums li.hover,#nums li:hover{
                background: red;
                color: white;
            }
        </style>

html布局

<div id="scrollBanner">
                <ul id="scrollList">
                    <li><img src="img/1.jpg"></li>
                    <li><img src="img/2.jpg"></li>
                    <li><img src="img/3.jpg"></li>
                    <li><img src="img/1.jpg"></li>
                </ul>
                <div id="btns">
                    <div>&lt;</div>
                    <div>&gt;</div>
                </div>
                <ul id="nums">
                    <li class="hover">1</li>
                    <li>2</li>
                    <li>3</li>
                </ul>
        </div>

js实现代码

<script src="startMove.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var oScrollBanner = document.getElementById("scrollBanner");
            var oScrollList = document.getElementById("scrollList");
            var aList  =oScrollList.children;
            var perWidth = aList[0].offsetWidth;
            oScrollList.style.width = perWidth * aList.length + "px";
            var i = 0;
            
            var timer = setInterval(function(){
                move();
            },3000);
            
            function move(){
                i++;
                if(i==aList.length){
                    oScrollList.style.left = 0;
                    i = 1;
                }
                if(i==-1){
                    oScrollList.style.left = -perWidth * (aList.length-1) + "px";
                    i = aList.length - 2;
                }
                
                //控制角标的变化
                for(var j = 0; j < aNumsList.length; j++){
                    aNumsList[j].className = "";
                }
                if(i==aList.length - 1){
                    aNumsList[0].className = "hover";
                }else{
                    aNumsList[i].className = "hover";
                }
                
                
                startMove(oScrollList,{left:-perWidth*i});
            }
            
            //左右按钮实现图片切换
            var oBtns = document.getElementById("btns");
            var oPrev = oBtns.children[0];
            var oNext = oBtns.children[1];
            
            oNext.onclick = function(){
                move();
            }
            oPrev.onclick = function(){
                i-=2;
                move();
            }
            
            oScrollBanner.onmouseover = function(){
                clearInterval(timer);
            }
            oScrollBanner.onmouseout = function(){
                timer = setInterval(function(){
                    move();
                },3000);
            }
            //角标变化
            var oNums = document.getElementById("nums");
            var aNumsList = oNums.children;
            
            for(let j = 0; j < aNumsList.length; j++){
                aNumsList[j].onmouseover = function(){
                    i = j-1;
                    move();
                }
            }
        </script>
星级评价

html代码:

<ul>
    <li></li>  //css样式给li加的背景图
    <li></li>
    <li></li>
    <li></li>       
    <li></li>
</ul>

js代码:

var aLi = document.getElementsByTagName('li');
var flag = false;
var index = 0; //表示点击了哪个星星
for(let i = 0; i < aLi.length; i++){
   aLi[i].onmouseover = function(){
      for(var j = 0; j < aLi.length; j++){
         //用的是背景图,改变定位信息即可
         aLi[j].style.backgroundPosition = "0 0";
      }
      for(var j = 0; j <= i; j++){
         aLi[j].style.backgroundPosition = "0 -28px";
      }
   }
   aLi[i].onmouseout = function(){
      for(var j = 0; j < aLi.length; j++){
         aLi[j].style.backgroundPosition = "0 0";
      }
      if(flag){
         for(var j = 0; j <= index; j++){
            aLi[j].style.backgroundPosition = "0 -28px";
         }
      }
      
   }
   aLi[i].onclick = function(){
      flag = true;
      index = i;
   }
}
放大镜

css代码:

<style type="text/css">

    body,ul,li{
    margin: 0;
    padding: 0;
    }
    body{
    height: 1000px;
    }
    ul,li{
    list-style: none;
    }
    img{
    display: block;
    border: none;
    }
    #zoomBox{
    position: relative;
    margin: 20px;
    width: 400px;
    border: 1px solid #CECECE;
    }
    #midArea img{
    width: 400px;
    height: 400px;
    }
    #midArea{
    cursor: move;
    }
    #zoom{
    display: none;
    position: absolute;
    width: 200px;
    height: 200px;
    background: yellow;
    opacity: .5;
    }
    #bigArea{
    display: none;
    position: absolute;
    left: 400px;
    top: -1px;
    border: 1px solid #CECECE;
    width: 400px;
    height: 400px;
    overflow: hidden;
    }
    #bigArea img{
    position: absolute;
    width: 800px;
    height: 800px;
    }
    #smallArea ul{
    display: flex;
    height: 100px;
    width: 400px;
    border-top: 1px solid #CECECE;
    align-items: center;
    justify-content: space-around;
    }
    #smallArea li{
    border: 2px solid white;
    padding: 6px;
    }
    #smallArea li:hover,#smallArea li.hover{
    border: 2px solid red;
    }
    #smallArea img{
    width: 60px;
    height: 60px;
    }
</style>

html布局代码

<div id="zoomBox">
            <div id="midArea">
                <img src="img/m01.jpg">
                <div id="zoom"></div>
            </div>
            <div id="bigArea">
                <img src="img/m01.jpg">
            </div>
            <div id="smallArea">
                <ul>
                    <li class="hover"><img src="img/m01.jpg"></li>
                    <li><img src="img/m02.jpg"></li>
                    <li><img src="img/m03.jpg"></li>
                    <li><img src="img/m04.jpg"></li>
                    <li><img src="img/m05.jpg"></li>
                </ul>
            </div>
        </div>

js实现代码

var oMidArea = document.getElementById("midArea");
            var oZoom = document.getElementById("zoom");
            var oBigArea = document.getElementById("bigArea");
            var oZoomBox = document.getElementById("zoomBox");
            var oBigImg = oBigArea.children[0];
            var oSmallArea = document.getElementById("smallArea");
            var aSmallList = oSmallArea.children[0].children;
            var oMidImg = oMidArea.children[0];
            
            oMidArea.onmouseover = function(){
                oZoom.style.display = "block";
                oBigArea.style.display = "block";
            }
            oMidArea.onmouseout = function(){
                oZoom.style.display = "none";
                oBigArea.style.display = "none";
            }
            
            
            oMidArea.onmousemove = function(e){
                
                //控制放大镜的移动
                var evt = e || event;
                var x = evt.pageX - oZoomBox.offsetLeft - oZoom.offsetWidth/2;
                var y = evt.pageY - oZoomBox.offsetTop -  oZoom.offsetHeight/2;
                
                if(x <= 0){
                    x = 0;
                }
                if(x >= oMidArea.offsetWidth - oZoom.offsetWidth){
                    x = oMidArea.offsetWidth - oZoom.offsetWidth;
                }
                if(y <= 0){
                    y = 0;
                }
                if(y >= oMidArea.offsetHeight - oZoom.offsetHeight){
                    y = oMidArea.offsetHeight - oZoom.offsetHeight;
                }
                
                oZoom.style.left = x + "px";
                oZoom.style.top = y + "px";

                //控制大图的移动
                oBigImg.style.left = - oZoom.offsetLeft/oMidArea.offsetWidth * oBigImg.offsetWidth + "px";
                oBigImg.style.top = - oZoom.offsetTop/oMidArea.offsetHeight * oBigImg.offsetHeight + "px";
                
            }
        
            //点击缩略图 切图片
            
            for(let i = 0; i < aSmallList.length; i++){
                aSmallList[i].onclick = function(){
                    for(var j = 0; j < aSmallList.length; j++){
                        aSmallList[j].className = "";
                    }
                    aSmallList[i].className = "hover";
                    
                    oMidImg.src = aSmallList[i].children[0].src;
                    oBigImg.src = aSmallList[i].children[0].src;
                    
                }
            }
定时器案例

循环打印5,6,7,8,9,10,9,8,7,6,5,6,7…循环输出

var a=4;
        var b=1;
        setInterval(function(){
            a=a+b;
            if(a==10){
                b=-1;
            }else if(a==5){
                b=1;
            }
            console.log(a);
        },500);
ajax

ajax的基本封装 ----必须掌握

function ajax(url,fn){
    if(window.XMLHttpRequest){
        var xhr = new XMLHttpRequest();
    }else{
        var xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    xhr.open("get",url,true);
    xhr.send();
    
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                var data = xhr.responseText;
                fn(data);
            }
        }
    }
}

ajax的完整封装
function ajax(obj){
    //obj -> type url data success
    var str = "";
    for(var key in obj.data){
        str += key+"="+obj.data[key]+"&";
    }
    //str = str.substring(0,str.length-1);
    str = str.replace(/&$/,"");
    
    if(window.XMLHttpRequest){
        var xhr = new XMLHttpRequest();
    }else{
        var xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    if(obj.type.toUpperCase()=="GET"){
        if(obj.data){
            var url = obj.url + "?" + str;
        }else{
            var url = obj.url;
        }
        
        xhr.open("get",url,true);
        xhr.send();
    }
    if(obj.type.toUpperCase()=="POST"){
        xhr.open("post",obj.url,true);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(str);
    }
    
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                var data = xhr.responseText;
                obj.success(data);
            }
        }
    }
}
页码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
        *{
        margin: 0;
        padding: 0;
        }
    
        #list{
        width: 500px;
        }
        #list li{
        border-bottom: 1px solid #ccc;
        height: 40px;
        line-height: 40px;
        list-style: none;
        }
        #btm{
        margin-top: 20px;
        }
        #btm li{
        float: left;
        margin: 0 10px;
        border:1px solid #ccc;
        list-style: none;
        background: orange;
        padding: 0 6px;
        }
        #osp span{
        display: inline-block;
        padding: 0 10px;
        margin: 0 5px;
        background: red;
        }
        </style>
    </head>
    <body>
        <ul id="list"></ul>
        <ul id="btm">
            <li>上一页</li>
            <li>首页</li>
            <li id="osp"></li>
            <li>下一页</li>
            <li>尾页</li>
        </ul>
    <script src="ajax.js"></script>
    <script>
    var list=document.getElementById("list");
    var btm=document.getElementById("btm");
    var oli=btm.children;
    var osp=document.getElementById("osp");
    
    ajax("data.json",foo);
    
    function foo(data){
         data=JSON.parse(data);
         var tatalnums=data.length;
         var pernums=5;
        var numsp=Math.ceil(tatalnums/pernums); //得到具体的页数
    
        //创建具体的页码数字
        var str="";
        for(var i=0;i<numsp;i++){
            str+=`<span>${i+1}</span>`;
        }
        osp.innerHTML=str;
        
        //默认显示第一页的内容
        index=0;
        click(index);
        
        //上一页事件
        var index=0;
        oli[0].onclick=function(){
            index--;
            if(index<=0){
                index=0;
            }
            click(index);
        }
        
        function click(index){
            var str1="";
            for(var i=index*pernums;i<Math.min(data.length,(index+1)*pernums);i++){
                str1+=`<li>${data[i]}</li>`;
            }
            list.innerHTML=str1;
        }
        
        //首页
        oli[1].onclick=function(){
            index=0;
            click(index);
        }
        
        //下一页
        oli[oli.length-2].onclick=function(){
            index++;
            if(index>=numsp-1){
            index=numsp-1;
            }
            click(index);
        }
        
        //尾页
        oli[oli.length-1].onclick=function(){
            index=numsp-1;
            click(index);
        }
        
        //具体页
        
        var ospan=osp.children;
        for(var i=0;i<ospan.length;i++){
            ospan[i].index=i;
            ospan[i].onclick=function(){
            index=this.index;
                click(index);
            }
        }
    }
    </script>
    </body>
</html>
data.json数据:

["111","2222","3333","2222","3333","2222","3333","2222","3333","2222","3333","2222","3333","2222","3333","2222","3333","2222","3333","2222","3333","2222","4444","2222","3333","55555","3333","2222","3333","2222","3333","2222","6666"]
1
自动补全
html样式代码

<input type="text" name="txt" id="txt" />
<ul id="list"></ul>

js代码:

var oTxt = document.getElementById("txt");
            var oList = document.getElementById("list");
            oTxt.oninput = function(){
                ajax({
                    type:"post",
                    url:"index.php",
                    data:{"kw":oTxt.value},
                    success:function(data){
                        data = JSON.parse(data);
                        var str = "";
                        for(var i = 0; i < data.length; i++){
                            str += `<li>${data[i]}</li>`;
                        }
                        oList.innerHTML = str;
                    }
                })
            }

index.php文件代码:

<?php
$kw = $_POST["kw"];
$arr = ["a","aa","aba","aaaa","aaaaaaaaa"];
$newArr = [];
foreach($arr as $val){
   
   if($kw == substr($val,0,strlen($kw))){
      array_push($newArr,$val);
   }
   
}

$json = json_encode($newArr);

echo $json;

?>

jsonp -------百度接口
html结构代码

搜索<input type="text" id="txt">
<ul id="list">
   
</ul>

js代码

<script type="text/javascript">
   var oTxt = document.getElementById("txt");
   var oList = document.getElementById("list");
   //给文本框添加输入事件
   oTxt.oninput = function(){
   //jsonp请求,得到的是callback包裹的函数
      var oScript = document.createElement("script");
      oScript.src = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+oTxt.value+"&cb=aa";
      document.body.appendChild(oScript);
      document.body.removeChild(oScript);
   }
  //接收传来的数据并进行处理
   function aa(data){
      data = data.s;
      var str = "";
      data.forEach(function(item){
         str += `<li><a href="https://www.baidu.com/s?wd=${item}">${item}</a></li>`;
      })
      oList.innerHTML = str;
      }
</script>
promise

promise-ajax的封装

function ajax(url){
//创建promise对象
   var promise = new Promise(function(resolve,reject){
   //创建ajax对象
         if(window.XMLHttpRequest){
            var xhr = new XMLHttpRequest();
         }else{
            var xhr = new ActiveXObject("Microsoft.XMLHTTP");
         }
         
         xhr.open("get",url,true);
         xhr.send();
         
         xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
               if(xhr.status == 200){
                  var data = xhr.responseText;
                  resolve(data);
               }else{
                  reject();
               }
            }
         }
   
   })
   return promise;  //返回promise对象
}

红绿灯

html结构代码

<ul id="traffic" class="">
    <li id="green"></li>
    <li id="yellow"></li>
    <li id="red"></li>
</ul>

css样式代码:

ul {
    position: absolute;
    width: 200px;
    height: 200px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    }
    /*画3个圆代表红绿灯*/

    ul>li {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    opacity: 0.2;
    display: inline-block;
    }
    /*执行时改变透明度*/

    ul.red>#red,
    ul.green>#green,
    ul.yellow>#yellow {
    opacity: 1.0;
    }
    /*红绿灯的三个颜色*/

    #red {
    background: red;
    }

    #yellow {
    background: yellow;
    }

    #green {
    background: green;
}

js实现代码:

function timeout(timer) {
     return function() {
          return new Promise(function(resolve, reject) {
                setTimeout(resolve, timer)
                     })
                 }
             }
         var green = timeout(1000);
         var yellow = timeout(1000);
         var red = timeout(1000);
         var traffic = document.getElementById("traffic");
        
         (function restart() {
             'use strict' //严格模式
             traffic.className = 'green';
             green().then(function() {
                     traffic.className = 'yellow';
                     return yellow();
                 })
                 .then(function() {
                     traffic.className = 'red';
                     return red();
                 }).then(function() {
                     restart()
                 })
         })();
闭包案例

编写一个求和函数sum,使输入sum(2)(3)或输入sum(2,3),输出结果相同

可以传入多个参数

function sum(){    
    var num = arguments[0];    
    if(arguments.length==1){       
    return function(sec){           
        return num+sec;       
            }    
        }else{        
        var num = 0;        
        for(var i = 0;i<arguments.length;i++){           
            num = num + arguments[i];        
            }   
            return num;    
        }
    }
递归----深拷贝
function deepCopy(obj){
                if(Array.isArray(obj)){
                    var newobj=[];
                }else{
                    var newobj={};
                }
                
                for(var i in obj){
                    if(typeof obj[i]=="object"){
                     newobj[i]=deepCopy(obj[i]);
                        
                    }else{
                        newobj[i]=obj[i];
                    }
                }
                return newobj;
            }
观察者模式案例

观察者模式(发布-订阅模式):其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知


var observer = {
   regist:function(eventName,callback){
      if(!this.obj){
         this.obj = {};
      }
      if(!this.obj[eventName]){
         this.obj[eventName] = [callback];
      }else{
         this.obj[eventName].push(callback);
      }
   },
   emit:function(eventName){
      for(var i = 0; i < this.obj[eventName].length; i++){
         this.obj[eventName][i]();
      // this.obj[eventName][i](arguments[n]); 有参数的
      }
   },
   remove:function(eventName,callback){
      for(var i = 0; i < this.obj[eventName].length; i++){
         if(this.obj[eventName][i] == callback){
            this.obj[eventName].splice(i,1);
         }
      }
   }
}

//给三个模块注册事件
observer.regist("loginSuccess",function(){
   console.log("用户信息模块接收到了登录成功的消息,做出了响应");
})
observer.regist("loginSuccess",function(){
   console.log("购物车模块接收到了登录成功的消息,做出了响应");
})
observer.regist("loginSuccess",function(){
   console.log("消息模块接收到了登录成功的消息,做出了响应");
})

observer.emit("loginSuccess");  //广播
JQ
全选和反选:

简单的布局:

<input type="checkbox" id="checkAll">全选
<input type="checkbox" id="checkOther">反选
<ul>
   <li><input type="checkbox"></li>
   <li><input type="checkbox"></li>
   <li><input type="checkbox"></li>
   <li><input type="checkbox"></li>
   <li><input type="checkbox"></li>
   <li><input type="checkbox"></li>
</ul>

jq代码: 思路:下面的状态和全选的状态一致,和反选的状态相反的

$(function(){
    //全选
   $("#checkAll").click(function(){
        //让li 下的input的状态和当前的这个保持一致
      $("li input").prop("checked",$(this).prop("checked"));
   });
   //反选
   $("#checkOther").click(function(){
        //遍历下面的每一个,让它的状态和它当前的状态相反
      $("li input").each(function(){
         $(this).prop("checked",!$(this).prop("checked"));
      })
   });
   //下方
   $("li input").click(function(){
        //根据选中状态的长度判断下方是否都选上了
      if($("li input:checked").length == $("li input").length){
         $("#checkAll").prop("checked",true);
      }else{
         $("#checkAll").prop("checked",false);
      }
   })
})
手风琴

html结构

<div id="acc">
   <ul>
       <li class="active">
           <h3 class="active">红玫瑰</h3>
           <div><img src="img/bg1.jpg"></div>
       </li>
       <li>
           <h3>白玫瑰</h3>
           <div><img src="img/bg2.jpg"></div>
       </li>
       <li>
           <h3>白玫瑰</h3>
           <div><img src="img/bg3.jpg"></div>
       </li>
       <li>
           <h3>白玫瑰</h3>
           <div><img src="img/bg4.jpg"></div>
       </li>
       <li class="last">
           <h3>白玫瑰</h3>
           <div><img src="img/bg5.jpg"></div>
       </li>
   </ul>

</div>

JQ代码

<script src="jquery-1.11.0.js"></script>
<script>
    $(function(){
        $("#acc li").on("mouseenter",function(){
            $(this).stop().animate({"width":434}).find("h3").addClass("active")
                    .end().siblings().stop().animate({"width":50}).find("h3").removeClass("active")
        })
    })
</script>
多级下拉菜单

html结构

<ul>
            <li>主题市场
                <ul>
                    <li>运动派
                        <ul>
                            <li>三级菜单a</li>
                            <li>三级菜单b</li>
                            <li>三级菜单c</li>
                            <li>三级菜单d</li>
                        </ul>
                    </li>
                    <li>有车族
                        <ul>
                            <li>三级
                                <ul>
                                    <li>四级</li>
                                    <li>四级</li>
                                    <li>四级</li>
                                </ul>
                            </li>
                            <li>三级</li>
                            <li>三级</li>
                            <li>三级</li>
                        </ul>
                    </li>
                    <li>生活家</li>
                </ul>
            </li>
            <li>特色购物
                <ul>
                    <li>淘宝二手</li>
                    <li>拍卖会</li>
                    <li>爱逛街</li>
                    <li>全球购</li>
                    <li>淘女郎</li>
                </ul>
            </li>
            <li>优惠促销
                <ul>
                    <li>天天特价</li>
                    <li>免费试用</li>
                    <li>清仓</li>
                    <li>1元起拍</li>
                </ul>
            </li>
            <li>工具</li>
        </ul>

JQ代码: 用了多种方式,练习jq的用法

<script type="text/javascript" src="js/jquery-1.11.0.js"></script>
        <script type="text/javascript">
            
            $(function(){
                //给每一个有ul(有子菜单)的li添加一个图标
                //添加点击事件,展开收缩
                //$("li:has(ul)").css("list-style-image","url(img/plus.gif)")
                $("li:has(ul)").addClass("plus")
                //链式调用
                .click(function(e){
                    //e.stopPropagation();
                    //$(this).css("list-style-image","url(img/minus.gif)");
                    //$(this).toggleClass('minus');
                    if($(e.target).children().length){
                    if($(this).children().is(":hidden")){
                        $(this).css("list-style-image","url(img/minus.gif)");
                    }else{
                        $(this).css("list-style-image","url(img/plus.gif)");
                    }
                    $(this).children().slideToggle();
                    }
                    return false;
                })
                
            })
                
        </script>
轮播案例

html

<div id="main">
            <div class="pic">
                <ul>
                    <li style="background: url(img/bg1.jpg);">
                        <img class="img1" src="img/text1.png"/>
                        <img class="img2" src="img/con1.png"/>
                    </li>
                    <li style="background: url(img/bg2.jpg);">
                        <img class="img1" src="img/text2.png"/>
                        <img class="img2" src="img/con2.png"/>
                    </li>
                    <li style="background: url(img/bg3.jpg);">
                        <img class="img1" src="img/text3.png"/>
                        <img class="img2" src="img/con3.png"/>
                    </li>
                    <li style="background: url(img/bg4.jpg);">
                        <img class="img1" src="img/text4.png"/>
                        <img class="img2" src="img/con4.png"/>
                    </li>
                    <li style="background: url(img/bg5.jpg);">
                        <img class="img1" src="img/text5.png"/>
                        <img class="img2" src="img/con5.png"/>
                    </li>

                </ul>
            </div>
            <div class="nav">
                <ul>
                    <li class="select"></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
            </div>
            
        </div>

JQ代码

<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
        <script type="text/javascript">
            $(function(){
                $(".pic li").eq(0).find(".img1").stop().animate({"left":0},1000)
                .next().show().stop().animate({"left":0},1000);
                var i = 0;
                var timer = setInterval(function(){
                    i++;
                    if(i==$(".pic li").length){
                        i = 0;
                    }
                    $(".pic li").eq(i).fadeIn().find(".img1").stop().animate({"left":0},1000)
                    .next().show().stop().animate({"left":0},1000)
                    //.parent().siblings().fadeOut().find(".img1").css("left",-760).next().hide().css("left",-20);
//移除样式也可以用这种方法                  .parent().siblings().fadeOut().children().removeAttr("style");
                    
                    $(".nav li").eq(i).addClass("select").siblings().removeClass("select");
                },2000);
            })
        </script>
楼梯

html结构

<div id="floorNav">
    <ul>
        <li>1F<span>服饰</span></li>
        <li>2F<span>美妆</span></li>
        <li>3F<span>手机</span></li>
        <li>4F<span>家电</span></li>
        <li>5F<span>数码</span></li>
        <li>6F<span>运动</span></li>
        <li>7F<span>居家</span></li>
        <li>8F<span>母婴</span></li>
        <li>9F<span>食品</span></li>
        <li>10F<span>图书</span></li>
        <li>11F<span>服务</span></li>
        <li>TOP</li>
    </ul>
</div>
<div id="header"></div>
<div id="content">
    <ul>
        <li style="background: #8B0000;">服饰</li>
        <li style="background: #123;">美妆</li>
        <li style="background: #667;">手机</li>
        <li style="background: #558;">家电</li>
        <li style="background: #900;">数码</li>
        <li style="background: #456;">运动</li>
        <li style="background: #789;">居家</li>
        <li style="background: #234;">母婴</li>
        <li style="background: #567;">食品</li>
        <li style="background: #887;">图书</li>
        <li style="background: #980;">服务</li>
    </ul>
</div>
<div id="footer"></div>

js代码

<script src="jquery-1.11.0.js"></script>
<script>
    //滚动到某值让小nav显示
    $(function(){
        var flag=true;
        $(window).scroll(function(){
            if(flag){
            //滚动条的显示与隐藏
            var scrolltop=$(this).scrollTop();
            if(scrolltop>300){
                $("#floorNav").fadeIn();
            }else{
                $("#floorNav").fadeOut();
            }

            //随着滚动显示对应的内容
            //判断offset.top-outheight/2和scrolltop的值
                $("#content li").each(function(){
                    if(scrolltop>=$(this).offset().top-$(this).outerWidth()/2){
                        var index=$(this).index();
                        $("#floorNav li").eq(index).addClass("hover").siblings().removeClass("hover");

                    }
                })
            }
        })

        //给每个小nav注册点击事件,不包含最后一个
        $("#floorNav li:not(:last)").click(function(){
           flag=false;
            var index= $(this).index();
            $("#floorNav li").eq(index).addClass("hover").siblings().removeClass("hover");
          $("html,body").stop().animate({"scrollTop":$("#content li").eq(index).offset().top},800,function(){
              flag=true;
          });
        })
        //回到顶部的事件
        $("#floorNav li:last").click(function(){
            $("html,body").stop().animate({"scrollTop":0});
        })
        
    })
</script>
商城后台接口

先建数据库,建好之后,开始接口的操作

1.创建连接数据库的接口 conn.php

<?php
//防止中文乱码
header("content-type:text/html;charset=utf-8");
//连接数据库
$conn=new mysqli("localhost","root","","work2");
//判断是否连接成功
if($conn->connect_error){
    die("连接失败".$conn->connect_error);
}

2.创建注册接口 register.php
//我的用户表是 users

用户名不能重复

请求方式:get,post都支持

参数 :用户名 usename ,密码 password

<?php
header("content-type:text/html;charset=utf-8");
//连接数据库
include_once "connect.php";
//接收数据
$usename=$_REQUEST["usename"];
$pwd=$_REQUEST["password"];

//先判断数据库中是否有相同的数据,如果有则插入失败,无则插入成功
$sq="select usename from users where usename=$usename";
$result=$conn->query($sq);
if ($result->num_rows>0){
    $data=array('msg'=>'注册失败','code'=>'0');
    echo json_encode($data,JSON_UNESCAPED_UNICODE);
}else{
    //让插入的数据从1开始
    $sq="alter table users auto_increment=1";
    $conn->query($sq);
   //插入数据库中的表
    $sql="insert into users (usename,pwd) values
   ('$usename','$pwd')";
//执行,返回数据
    $conn->query($sql);
    $data=array('msg'=>'注册成功','code'=>'1');
    //将数组转成json字符串
    echo json_encode($data,JSON_UNESCAPED_UNICODE);
}

3.创建登录接口 login.php
必须先注册才能登录

请求方式:get,post 都支持

参数:用户名 usename

<?php
header("content-type:text/html;charset=utf-8");
include_once "connect.php";
$usename=$_REQUEST["usename"];
$sql="select usename from users where usename=$usename";
$result=$conn->query($sql);
$sql1="select id from users where usename=$usename";
$result1=$conn->query($sql1);
if($result->num_rows>0){
    while ($row=$result1->fetch_assoc()) {
        $oid = $row["id"];
    }

   $data=array("code"=>"1",
        "msg"=>"ok",
        "data"=>array("token"=>"$oid")
    );
    echo json_encode($data,JSON_UNESCAPED_UNICODE);
}else{
    echo "0";  //登录失败,先注册再登录
}

4.商品列表接口 protects.php
//我的产品表是protects

无需参数

<?php
header("content-type:text/html;charset=utf-8");
include_once "connect.php";
$sql ="select * from protects";
$result=$conn->query($sql);
if($result->num_rows){
    $prot=[];
    $data=[];  //不用多个数组嵌套只能获取到一组数组
    while ($row=$result->fetch_assoc()){
        //将数据库中的数据添加到data数组中
        Array_push($data,[
            "pid"=>$row["pid"],
            "pname"=>$row["pname"],
            "pimg"=>$row["pimg"],
            "pchar"=>$row["pchar"]
        ]);
    }
    //循环完之后,再将data添加到最外层prot数组中
    $prot["msg"]="查询成功";
    $prot["data"]=$data;

  echo json_encode($prot,JSON_UNESCAPED_UNICODE);
}

5.详情页接口 details.php
参数:商品的 pid

请求方式:get,post 都支持

<?php
header("content-type:text/html;charset=utf-8");
include_once "connect.php";
$id=$_REQUEST["id"];
//获取一整条数据,select 字段 where 获取的就是一个字段值
$sql="select * from protects where pid=$id";
$result=$conn->query($sql);
if($result->num_rows){
   $data=[];
   while($row=$result->fetch_assoc()){
       Array_push($data,[
           "pid"=>$row["pid"],
           "pname"=>$row["pname"],
           "pimg"=>$row["pimg"],
           "pchar"=>$row["pchar"]
       ]);
   }
   $data=json_encode($data,JSON_UNESCAPED_UNICODE);
   echo $data;
}

6.添加购物车的接口 add-protect.php
请求方式:get,post都支持

参数:用户 uid ,商品 pid ,添加商品的数量 numbers

<?php

header("content-type:text/html;charset=utf-8");
include_once "connect.php";

//添加商品,用户id,商品id,商品数量

$uid=$_REQUEST["uid"];
$pid=$_REQUEST["pid"];
$numbers=$_REQUEST["numbers"];

$data1=["code"=>"1","msg"=>"加入成功"];
$data1=json_encode($data1,JSON_UNESCAPED_UNICODE);
$data2=["code"=>"0","msg"=>"加入失败".$conn->error];
$data2=json_encode($data2,JSON_UNESCAPED_UNICODE);
//先判断数据库中是否有这条数据
$sql1="select * from uplink where uid=$uid and pid=$pid";
$result=$conn->query($sql1);
//如果有这条数据,只需修改数据值,无,则新插入进去
if($result->num_rows){
    $sql3="select numbers from uplink where uid=$uid and pid=$pid";
    $res=$conn->query($sql3);
    while ($row1=$res->fetch_assoc()){
        $resnum=$row1["numbers"];
    }
    $numbers=$numbers+$resnum;
    $sql2="update uplink set numbers=$numbers where uid=$uid and pid=$pid";
    if ($conn->query($sql2)){
        echo $data1;
    }else{
        echo $data2;
    }
}else{
    $sq="alter table users auto_increment=0";
    $conn->query($sq);
 //字段值用 , 分开,再错锤死你
    $sql="insert into uplink (uid,pid,numbers) values
    ('$uid','$pid','$numbers')";
    if($conn->query($sql)){
        echo $data1;
    }else{
        echo $data2;
    }
}

7.获取购物车列表的接口 cart-list.php
请求方式:get,post 都支持

参数: 用户 uid

<?php
header("content-type:text/html;charset=utf-8");
include_once "connect.php";

//获取购物车列表, 用户id
$uid=$_REQUEST["uid"];
/*$sql1="alter table uplink add constraint fk_pid foreign
key (pid) references protects(pid)";
$conn->query($sql1);*/
/*多表查询时,需给子表添加外键约束,如果表已经创建好,在软件的SQL面板中运行下方的代码
 *  alter table 子表明 add constraint fk_pid foreign
    key (pid) references protects(pid)
     //子表                 //主表
 * */
//两个表联合查询,先从主表中查,再从子表中查
$sql="select * from protects u 
  join uplink p on u.pid=p.pid where uid=$uid 
";

/*  //将表中的字段求和,对该栏赋个别名                 group by 分组
 * $sql="select pid,sum(numbers) as numbers from uplink where uid=$uid group by pid";*/
/*$sql="select pid,numbers from uplink where uid=$uid";*/
$result=$conn->query($sql);
if($result->num_rows){
//    $wrap=[];
    $data=[];
    $pid=[];
    while ($row=$result->fetch_assoc()){
        Array_push($data,[
            "pid"=>$row["pid"],
            "numbers"=>$row["numbers"],
            "pname"=>$row["pname"],
            "pimg"=>$row["pimg"],
            "pchar"=>$row["pchar"]
        ]);

    }
    $wrap["data"]=$data;
    $wrap["msg"]="查询成功";
    $wrap=json_encode($wrap,JSON_UNESCAPED_UNICODE);
    echo $wrap;
}else{
    echo "查询失败.$conn->error";
}

8.修改购物车的接口 modifycart.php
请求方式:get,post 都支持

参数:用户 uid , 商品 pid ,修改的商品数目(>0 增加,<0 减少, =0 删除)

<?php
header("content-type:text/html;charset=utf-8");
include_once "connect.php";

//修改购物车, 用户id,商品id,修改的商品数目(>0 增加,<0 减少, =0 删除)
$uid=$_REQUEST["uid"];
$pid=$_REQUEST["pid"];
$nums=$_REQUEST["nums"];

$sql="select * from uplink where uid=$uid and pid=$pid";
$result=$conn->query($sql);
if($result->num_rows){
    $sql1="select numbers from uplink where uid=$uid and pid=$pid";
    if($nums>0){
        $res1=$conn->query($sql1);
            while ($row1=$res1->fetch_assoc()){
                $resnum1=$row1["numbers"];
            }
        $resnum1=$resnum1+$nums;
        $sql2="update uplink set numbers=$resnum1 where uid=$uid and pid=$pid";
        if($conn->query($sql2)){
            $data=["code"=>"1","msg"=>"修改成功 + "];
            echo json_encode($data,JSON_UNESCAPED_UNICODE);
        }else{
            $data=["code"=>"0","msg"=>"修改失败.$conn->error"];
            echo json_encode($data,JSON_UNESCAPED_UNICODE);
        }

    }else if($nums<0){
        $res1=$conn->query($sql1);
        while ($row1=$res1->fetch_assoc()){
            $resnum1=$row1["numbers"];
        }
        $resnum1=$resnum1+$nums;
        $sql2="update uplink set numbers=$resnum1 where uid=$uid and pid=$pid";
        if($conn->query($sql2)){
            $data=["code"=>"1","msg"=>"修改成功 - "];
            echo json_encode($data,JSON_UNESCAPED_UNICODE);
        }

    }else if($nums==0){
        //等于0 ,直接删除该数据
        $sql3="delete from uplink where uid=$uid and pid=$pid";
        if($conn->query($sql3)){
            $data=["code"=>"1","msg"=>"修改成功,该条数据已删除"];
            echo json_encode($data,JSON_UNESCAPED_UNICODE);
        }

    }

}else{
    echo "购物车还没有该商品哦";
}

复制于qq_43101321的博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,475评论 4 372
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,744评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,101评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,732评论 0 221
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,141评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,049评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,188评论 2 320
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,965评论 0 213
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,716评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,867评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,341评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,663评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,376评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,200评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,990评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,179评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,979评论 2 279