【总结】javascript复习1

JavaScript复习1

  • JS-打印语句、注释
  • JS-数据类型
  • JS-数组
  • JS-DOM节点
  • JS-修改元素
  • JS-事件
  • JS-值类型与引用类型的区别
  • JS-运算符
  • JS-模拟前端路由
  • JS-函数
  • JS-内置对象arguments
  • JS-闭包
  • JS-原型机制
  • JS-JSONP(实现跨域)

打印语句、注释

示例

 <!-- 网页的注释 -->
 <script>
    /*
    多行注释
    */
    window.onload=function(){
     
     
    //控制台
    console.log("测试控制台");
    document.write("<h1>出现在网页上</h1>");
    alert("弹窗");
    }
</script>

数据类型

六种数据类型:String number boolean null undefined Object
引用数据类型:Array Function

示例

//弱类型语言
    /*
    六种数据类型:String  number  boolean  null  undefined  Object
    */
    var a=90;
    var b=3.1234;
    var c;//undefined 没定义  未赋值
    var d=true;
    var e='hello JS';
    var f=null;
    var g=new Date();
    var sz1=[1,2,3,4];
    var sz2=new Array();

    function hello(){
    
    
        console.log("nihao");
    }
    console.log(typeof a);  //number
    console.log(typeof b);  //number
    console.log(typeof c);  //undefined
    console.log(typeof d);  //boolean
    console.log(typeof e);  //String
    console.log(typeof f);  //object
    console.log(typeof g);  //object
    console.log(typeof sz1);  //object
    console.log(typeof sz2);  //object
    console.log(typeof hello);  //function
    console.log("--------");
    console.log(isNaN("abcd")+"|"+isNaN(123));    //不是一个数字,判断是真是假---->false是数字 true不是

数组

数组遍历

方案一:For循环
 //var 全局  let 局部
    var a=[1,2,3,4,5,6];
    console.log(a.length);
    for(let i=0;i<a.length;i++){
    
    
        console.log("数组----->"+a[i])
    }
方案二:For Each 遍历
	var sz=['temo','js','demo','xiao'];
    //for in i是下标
    for(let i in sz){
    
       //for-in中i为sz数组的下标
        console.log(i,sz[i]); //i=0、1、2、3
    }
    //for of i是值
    //es6
    for(let item of sz){
    
       //fo-of中item为sz数组的值
        console.log(item); //item=value
    }
    //for in 对象.....
    let gt={
    
    
        name:"狗头",
        age:18,
        addr:"湖南长沙",
        sr:new Date()
    };
    for(let j in gt){
    
    	//j为key
        console.log(j,gt[j]);
    }

数组常用方法

数组常用的方法
push()尾部放,pop()尾部移除,unshift()头部放,shift()头部移除
splice(下标,个数)增加和删除
sort()排序 concat()合并
join() 合成字符串 split(",")分割
eval() 函数计算或执行参数。

示例

//数组常用的方法
    //push()尾部放,pop()尾部移除,unshift()头部放,shift()头部移除
    //splice(下标,个数)增加和删除
    var sz=["temo","js","dema"];
    console.log(sz);
    console.log(sz.toString());//toString()数组转字符串
    //push
    var n=sz.push("小朋友")   //尾尾增加下标项   返回值为数组长度
    console.log(sz,"长度",n);
    //unshift
    n=sz.unshift("大朋友")  //头部添加下标项    返回值为数组长度
    console.log(sz,"长度",n);
    //pop
    var obj=sz.pop();   //移除尾部的下标项  返回值为移除的下标值
    console.log(obj);
    //shift
    obj=sz.shift();   //移除头部的下标项  返回值为移除的下标值
    console.log(obj);
    console.log(sz);
    //splice
    obj=sz.splice(1,1,"杨幂","迪丽热巴"); //删除-->返回值为被删除的元素 添加--->添加在删除下标的位置
    console.log(obj,sz);
	//join
    console.log(sz.join("-")); //默认逗号(",")连接
    //字符串split(",")
    var t="张三,李四,王五,赵六";
    var str=t.split(",");   //字符串拆成数组
    console.log(str);
	//eval(String)
	var x = 10;
  var y = 20;
  var a = eval("x * y") + "<br>";	//x*y的值<br>
  var b = eval("2 + 2") + "<br>";	//4<br>
  var c = eval("x + 17") + "<br>";	//x+17的值<br>

DOM节点

getElementById 根据id获取
getElementsByTagName 根据标签名获取(一个或多个)
getElementsByClassName 根据类名获取(一个或多个)
getElementsByName 根据name属性获取对象
querySelectorAll 通用

	<h1 id="txt">DOM 练习</h1>
    <h1>BOM对象</h1>
    <h1 class="xiao">Mr_xiao</h1>
    <input type="radio" name="sex" value=""><input type="radio" name="sex" value="">
<script>
    //页面加载完成时执行
    window.onload = function () {
    
    
        //getElementById    根据id获取
        var obj = document.getElementById("txt");
        obj.innerHTML = "修改了文本";
        console.log(obj);
        //getElementsByTagName  根据标签名获取(一个或多个)
        var tags = document.getElementsByTagName("h1");
        for (let i in tags) {
    
    
            tags[i].innerHTML = "循环更改文本" + i;
        }
        console.log(tags);
        //getElementsByClassName  根据类名获取(一个或多个)
        var cls=document.getElementsByClassName("xiao");
        console.log(cls)
        //getElementsByName 根据name属性获取对象
        var name=document.getElementsByName("sex");
        console.log(name);

        //querySelectorAll 通用
        obj=document.querySelectorAll("#txt");
        tags=document.querySelectorAll("h1");
        cls=document.querySelectorAll(".xiao");
        name=document.querySelectorAll("[name=sex]");
        console.log("name="+name);   
        for(let i in obj){
    
    
            obj[i].innerHTML="通用改变"
        }
        for (let i in tags) {
    
    
            tags[i].innerHTML = "通用改变循环更改文本" + i;
        }
        for (let i in cls) {
    
    
            cls[i].innerHTML = "通用改变循环更改文本class" + i;
        }
    }
</script>

修改元素

可以修改标签体,也可以修改属性值,还可以修改CSS样式

改标签体

HTML

	<h1>改标签体</h1>
    <h5 id="context">修改我的内容</h5>

JS

 	var context=document.getElementById("context");
    context.innerHTML="<i>新内容</i>";

改属性

HTML

	<h1>改属性</h1>
    <img src="./images/love.gif" shu="5" />

JS

	var img=document.querySelectorAll("img");
    //设置属性值setAttribute()
    img[0].src="./images/love.png";
    img[0].setAttribute("shu",6);

改CSS

HTML

<h1 id="style">改CSS</h1>

JS

	//css =obj.style.xxxxx
    var cs=document.querySelector("#style");
    cs.style.color="red";
    //background-color
    cs.style.backgroundColor="blue";
    cs.style.border='2px dashed yellow';

添加class

CSS

	.bk{
    
    
            color: pink;
            background-color: green;
            border: 2px double red;
      }

JS

var cs=document.querySelector("#style");
//添加class
cs.className="bk";//class=bk;即用到上方样式

事件

鼠标事件 onclick onmouseover onmouseout onmousemove
键盘事件 onkeydown onkeyup onkeypress

绑定事件

方案一(代码上绑定耦合)

优点:方便快捷
缺点:代码耦合,不利于后期代码维护

<button onclick="dian()">点我</button>
<script>
    //不推荐的写法
    function dian(){
     
     
        alert("hello JS")
    }
</script>

方案二(js绑定)

缺点:同一个事件不可绑定多个
优点:避免了代码耦合

<button id="btn2">点我2</button>
<script>
    //JS绑定
    var btn=document.querySelector("#btn2")
    btn.onclick=function(){
     
     
        alert("JS绑定")
    }
    btn.onmouseout=function(){
     
     
        alert("鼠标移出")
    }
</script>

方案三(事件监听)

优点:同一个事件可以绑定多个

<button id="btn3">点我3</button>
<script>
 //事件监听
    var  btn3=document.querySelector("#btn3");
     function dj1(){
     
     
        alert("事件监听click事件")
    }
    function dj2(){
     
     
        alert("事件监听click事件2")
    }
    btn3.addEventListener("click",dj1)
    btn3.addEventListener("click",dj2)
</script>

删除事件

删除普通事件

将触发事件的结果改为null即可

<button id="delbtn2">删除按钮2事件</button>
<script>
 var delbtn2=document.querySelector("#delbtn2");
    delbtn2.onclick=function(){
     
     
        btn.onclick=null;
        btn.onmouseout=null;
    }
</script>
删除事件监听

removeEventListener(“事件名称”,"方法名“)

<button id="delbtn">删除事件</button>
<script>
//事件删除
    var delbtn=document.querySelector("#delbtn");
    delbtn.addEventListener("click",function(){
     
     
        btn3.removeEventListener("click",dj1);//移除监听事件("事件名称","方法名")
    })
</script>

事件冒泡

简介://当点击子类事件,父类的事件都会触发(事件冒泡)

event.srcElement(火狐不支持) || event.currentTarget(IE不支持) 获取事件源触发代码
兼容问题解决方法:var obj=event.srcElement || event.currentTarget;

取消事件冒泡:event.stopPropagation(); //取消事件冒泡
示例
冒泡原理
通过给ul绑定一个事件获取到所点击的子类对象

	<ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <script>
	var ul=document.querySelectorAll("ul");
    ul[0].onclick=function(){
     
     
        var obj=event.srcElement||event.currentTarget
        console.log(obj)	//得到的是所点击的li对象
    }
	</script>

取消标签的默认行为event.preventDefault();//取消默认行为
例如:
这样就不会跳转到百度了

<a href="https://baidu.com">去百度</a>
<script>
	var a=document.querySelectorAll("a");
    a[0].onclick=function(){
     
     
        alert("a标签");
        event.preventDefault();//取消默认行为
    }
</script>

值类型与引用类型的区别

值类型:原始数据类型…
引用类型:可当作对象,可以设置属性获取属性值

代码表示:

	var str="acbde";
    var o=new String("xyz");

    function newStr(){
    
    
        return "新的字符串";
    }
    function func(t){
    
    
        t.toString=newStr;
    }

    func(str)   //值不会改变
    func(o)     //值会改变
    alert(str)	//abcde
    alert(o)	//新的字符串
    str.price=800;
    console.log(str.price);//undefined
    o.price=800;
    console.log(o.price);   //800

运算符

与或非 && ||

||有值就取不为空的第一个
&&而是取最后一个 如果有其中一个为空则为空

//JS中运算符与或非
    var str1="test";  //值
    var obj={
    
    } ; //空对象
    var x=obj||str1;//x值不是true而是有值就取不为空的第一个
    alert(x)
    var y=obj&&str1;//x值不是false而是取最后一个   如果有其中一个为空则为空
    alert(y)

等于 == ===

==:判断内容值是否相等
===:判断地址是否相等

var a="abc";
    var b=new String("abc");
    var c=b;
    console.log(a==b)   //判断内容是否相等	true
    console.log(c===b); //判断地址是否相等	true

运算符优先级

void是一个运算符,所以我们可以计算void1+2的值,void运算符的优先级比+高
,也是一种运算符

代码示例:

//运算符优先级
    alert(void 1+2);//NaN
    var i=100;
    alert((i+=20,i *=2,'value: '+i));   //240   从左往右

with用法

with可以指定缺省对象

代码示例:

 //with
    var obj1=new Object();
    obj1.name="temo";
    obj1.age=18;
    obj1.hi=function(){
    
    
        alert("我名字");
    }
    with(obj1){
    
    
        name="德玛";
        age=16;
 		hi();       
    }
    console.log(obj1);

逗号的二义性

//逗号的二义性
    var num1=(1,2,3);
    alert(num1) //3
    num1=1,2,3
    alert(num1) //1
    num1=[1,2,(3,4,5),6]
    alert(num1)//1,2,5,6

模拟前端路由

window.onhashchange()事件,得到超链接的跳转事件
location.hash得到跳转路径

代码示例:

	<style>
        #box{
     
     
            width: 100%;
            height: 10cm;
            background-color: greenyellow;
        }
        a{
     
     
            font-size: 50px;
            margin-right: 80px;
            text-decoration: none;/*去下划线*/
        }
    </style>
	<a href="#/wx">微信</a><a href="#/txl">通讯</a><a href="#/fx">发现</a><a href="#/wo"></a>
    <hr/>
    <div id="box">
        
    </div>
    <script>
    //变量名要与路径#/后边的相同,用于简化代码
    let wx='<h1>微信内容</h1>';
    let txl='<h1>通讯录内容</h1>';
    let fx='<h1>发现内容</h1>';
    let wo='<h1>我的内容</h1>';
    // onhashchange()   new事件
    window.onhashchange=function(){
     
     
        console.log(location.hash);
    //  let path=location.hash.slice(1);    //删除#
        let path=location.hash.slice(2);    //删除#/
        let box=document.querySelector("#box");
        box.innerHTML=eval(path);   //eval()这里用于将string转为变量名
        /*
        switch(path){
            case '/wx':
            box.innerHTML=wx;
            break;
            case '/txl':
            box.innerHTML=txl;
            break;
            case '/fx':
            box.innerHTML=fx;
            break;
            case '/wo':
            box.innerHTML=wo;
            break;
        }*/
        /*
        if(path=='/wx'){
            box.innerHTML=wx;
        }else if(path=='/txl'){
            box.innerHTML=txl;
        }else if(path=='/fx'){
            box.innerHTML=fx;
        }else if(path=='/wo'){
            box.innerHTML=wo;
        }*/
    }
	</script>

点击每个超链接控制台会打印出对应的跳转路径并且div显示对应的内容

函数

简介

JavaScript 函数. JS 数据类型. JS 对象.
JavaScript 函数是被设计为执行特定任务的代码块。.
JavaScript 函数会在某代码调用它时被执行。.

函数类型

全局函数、函数表达式、构造函数

全局函数(无论在哪调用都可以)
//调用
fun();
//全局函数(无论在哪调用都可以)
    function fun(){
    
    
        console.log(this);//window
        console.log("hello JSADV");
    }
函数表达式(定义函数存储到变量中,不可以在定义前调用)
var fun2=function(){
    
    
        alert("hello js2")
    }
    fun2();
构造函数(通过new Function构造函数)
var fun1=new Function(alert("new function"));

调用方式

方法调用

json对象

//方法调用()
    var temo={
    
    
        name:"提莫",
        sayhi:function(){
    
    
            console.log(this)   //当前对象
            alert("名字是:"+this.name); //提莫
        }
    }

调用:temo.sayhi();弹框 名字:提莫

函数对象(可以new多个对象)–推荐
function Hero(na){
    
    
        this.name=na;
        this.sayhi=function(){
    
    
            alert("i am"+this.name)
        }
    }

new2个对象var gt=new Hero("阿努比斯");var ani=new Hero("安妮");
调用方法:gt.sayhi();ani.sayhi();打印出i am 对应的名字

调用模式

函数调用模式

简单的函数调用, 函数名前面没有任何引导内容

	function show(a,b,c){
    
    
        console.log(a,b,c);
    }
    //不给参数
    show()  //undefined undefined undefined
    show(1,2,3,4,5)//只取前三个 1,2,3
  • 参数=另一个函数 √
	//参数=另一个函数   √
    function func(name){
    
    
        console.log("我的名字:"+name);
    }
    function hello(fun,msg){
    
    
        fun(msg);
    }
    hello(func,"牛马"); //我的名字:牛马
  • 函数的返回值能变吗? √
 	function hi(t){
    
    
        if(t){
    
    
            return "hello world";
        }else{
    
    
            return {
    
    name:'temo',age:18};
        }
    }
    var ret=hi(true);
    console.log(ret)
  • 函数可以返回一个函数吗? √
	function returnfun(){
    
    
        return function(a,b){
    
    
            console.log(a+b);
        }
    }
    var add=returnfun();
    add(4,5);   //9
构造器调用模式
构造函数在创建对象的时候, 做了些什么
  1. 使用 new 引导构造函数, 创建了一个实例对象
  2. 在创建对象的同时, 将this指向这个刚刚创建的对象
  3. 在构造函数中, 不需要 return , 会默认的 return this

分析: 由于构造函数只是给 this 添加成员, 而方法也可以完成这个操作,对与 this 来说, 构造函数和方法没有本质区别

关于return的补充, 在构造函数中

普通情况, 可以理解为构造函数已经默认进行了 return this, 添加在后面的都不会执行

  • 如果手动的添加 return ,就相当于 return this.
  • 如果手动的添加 return 基本类型(字符串, 数字, 布尔), 无效, 还是 return this
  • 如果手动的添加 return null 或 return undefined, 无效, 还是 return this

特殊情况, return 对象, 最终返回对象

  • 手动添加 return 对象类型, 那么原来创建的 this 会被丢掉, 返回 return 后面的对象
示例

注:变量名.prototype.属性名-------> 修改原型

 	var Person=function(na){
    
    
        this.name=na;
    }
    //修改原型
    Person.prototype.sayHi=function(){
    
    
        console.log("我的名字是:"+this.name);
    }
    var timi=new Person("timi");
    var mihoyou=new Person("mihoyou");
    timi.sayHi();	//我的名字是:timi
    mihoyou.sayHi();//我的名字是:mihoyou
Apply调用模式

将函数的拥有者变更

示例:

用法:apply(谁,数组参数) 参数必须用数组的格式传入

	//Apply调用模式
    function add(a,b,c){
    
    
        console.log(this.tag);
        console.log(a+b+c);
    }
    var ren={
    
    tag:"变换"}; //对象
    // add(1,2,3);
    //函数的拥有者变更  apply(谁,数组参数)
    add.apply(ren,[1,2,3]);	//变更	6

匿名函数

立即执行

	//匿名函数(立即执行)
    (function(){
    
    
        console.log("匿名函数");
    })();

函数递归

递归就是一个函数在它的函数体内调用它自身。

示例1(累加)
//1+2+3...+n
    //a(5)=a(4)+5=a(3)+4=a(2)+3=a(1)
    function add(n){
    
    
        if(n==1){
    
    
            return 1;
        }else{
    
    
            return add(n-1)+n;
        }
    }
    console.log(add(5));//求1~5的累加   15

示例2(阶乘)
//阶乘  5!=5*4*3*2*1
    function cheng(n){
    
    
        if(n==1){
    
    
            return 1;
        }else{
    
    
            return cheng(n-1)*n;
        }
    }
    console.log(cheng(5))//1~5的阶乘    120

示例3(斐波拉契数列)
 //0,1,1,2,3,5,8,13,.....前两个数之和得出后面这位数(斐波拉契数列)
    //f(5)=f(4)+f(3)
    //根据n求出n位数为几
    function shu(n){
    
    
        if(n==0){
    
    
            return 0;
        }else if(n==1){
    
    
            return 1;
        }else{
    
    
            return shu(n-1)+shu(n-2);
        }
    }
    console.log(shu(5))

内置对象arguments

作用:

  • (1)实现js的重载
  • (2)检测参数个数 arguments对象 大多用来针对同个方法多处调用并且传递参数个数不一样时使用。

示例

可以把arguments当成一个数组,存放所有的参数值 //类似与java中的object…

	//内置对象arguments
    //函数不列出参数
    function showAll(){
    
    
        //arguments是一个数组,存放所有的参数值  //类似与java中的object..
        for(let i=0;i<arguments.length;i++){
    
    
            alert(arguments[i]);
        }
    }
    showAll(1,3,4)//1,3,4

闭包

闭包是指有权访问另一个函数作用域变量的函数,创建闭包的通常方式,是在一个函数内部创建另一个函数

示例1

闭包内部可以使用外部的资源

function hello(name){
    
    
        let city='长沙';
        return{
    
    
            getms:function(){
    
    
                let age=18;
                //内部可以使用外部的资源
                console.log("我叫"+name+city);
                console.log("年龄"+age);
            }
        }
    }
    var ms=hello("temo");
    ms.getms()

示例2

new两个函数闭包互不影响

	function counter(name){
    
     
        var x=1;
        return function(){
    
    
            x++;
            console.log(name+"="+x);
        }
    }
    let ret=counter("Mr_xiao");
    ret();  //2
    ret();  //3
    let dm=counter("小朋友");   //---互不影响
    dm();   //2
    ret();  //4

闭包的难点

闭包内函数未执行导致循环完i为5都被放入到数组中

function test(){
    
    
        var arr=[];//数组
        for(var i=0;i<5;i++){
    
    
            arr[i]=function(){
    
    
                return i;
            }
        }
        return arr;
    }
    var p=test();
    console.log(p[0]()) //5
    console.log(p[1]()) //5
    console.log(p[2]()) //5

闭包函数未执行导致循环完都是3

var btn=document.querySelectorAll("button");
    for(var i=0;i<btn.length;i++){
    
    
        btn[i].onclick=function(){
    
    
            alert(i);   //都是3
        }
    }
解决方案
解决1
//解决 
    var helper=function(x){
    
     
        return function(){
    
    
            alert(x)
            return x;
        }
    }
    var btn=document.querySelectorAll("button");
    for(var i=0;i<btn.length;i++){
    
    
       btn[i].onclick=helper(i);
    }
解决2

将var改成let

 var btn=document.querySelectorAll("button");
    for(let i=0;i<btn.length;i++){
    
    
        
        btn[i].onclick=function(){
    
    
            alert(i);   //都是3
        }
    }

闭包的封装

提高安全性

未封装前
var Person=function(na){
    
    
    this.name=na;
    }
    var tm=new Person("temo");
    console.log(tm.name);//直接访问--->相当于public(不安全)
封装后
var Person=function(na){
    
    
    var name=na;
    return{
    
    
        getName:function(){
    
    
            return name;
        },
        setName:function(nam){
    
    
            name=nam;
        }
    };    
    }
    var tm=new Person("temo");
    console.log(tm.getName())//get访问--->相当于private私有属性-->闭包封装    temo
    tm.setName("小丑")
    console.log(tm.getName())//小丑

原型机制

用于修改函数属性方法等等…

constructor与prototype

prototype给类用

constructor给对象用

/*
实质上,函数对象的prototype属性就是一个对象,这个对象会自动带有一个constructor属性,该属性就是Stu函数本身,即
Stu.prototype.constructor==Stu
*/

示例
//实例的构造函数属性(constructor)指向构造函数
    function Stu(na,age){
    
    
        this.name=na;
        this.age=age;
        this.hi=function(){
    
    
            console.log("我叫:"+this.name+"年龄:"+this.age);
        }
    }
    var lei=new Stu("Mr_xiao",17);
    var tao=new Stu("涛涛",18);
    console.log(lei.constructor==Stu);   //true 指向类本身
    console.log(tao.constructor==Stu);   //true
    console.log(lei==tao);  //false
    console.log(Stu.prototype);//指向函数的原型对象
    //由原型对象给类增加属性和方法
    Stu.prototype.banname='终极一班';
    Stu.prototype.game=function(){
    
    
        alert(this.name+"打游戏....")
    }
    console.log(lei.banname);
    console.log(tao.banname);
    lei.game()  //调用game方法OK

    console.log(Stu.prototype.constructor==Stu);//true
两者区别
	var o1={
    
    }//json
    console.log(o1.prototype);  //undefined  类原型    prototype给类用
    console.log(o1.constructor);    //object  
    //每个对象都有    constructor给对象用

proto

//–proto–
/*
Js在创建对象(不论使普通对象还使函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的构造函数的原型对象
*/

关系示例
	console.log(Stu.prototype==lei.__proto__);//true    类指向类原型
    console.log(lei.__proto__); //对象指向类原型

总结:

lei.–proto–==Stu.prototype
lei.–proto–=lei.constructor.prototype

JSONP

概念

JSONP 是一种无需考虑跨域问题即可传送 JSON 数据的方法。
JSONP 不使用 XMLHttpRequest 对象。
JSONP 使用 <script> 标签取而代之。

第一版

直接引用

前台:
jsonp.js

alert("测试远程请求跨域");
localFn({
    
    "msg":"后台调用前台的函数方法传参"});

后台

<!-- 第一版直接引用 -->
<script src="http://localhost:8080/email/js/jsonp.js"></script>

第二版

用servlet代替 js springboot中用controller

前台:

//jsonpcontroller测试JSONP
    @GetMapping("/kzq")
    @ResponseBody
    public String jsonp(String callback) throws JsonProcessingException {
    
    
        System.out.println("jsonp 请求中....");
        System.out.println("传来的参数="+callback);
        return callback+"({\"msg\":\"第二版远程请求数据\"})";
    }

后台:

 <!--第二版 用servlet代替 js-->
 <script src="http://localhost:8080/email/kzq?callback=sheng"></script>
<script>
	function sheng(data){
     
     
            console.log("远程省数据:"+data.msg);
        }
</script>

第三版

第三版 js动态创建script

前台与第二版一样
后台:

function sheng(data){
    
    
            console.log("远程省数据:"+data.msg);
        }
//动态发请求
        function jsonp(url,method){
    
    
            let scr=document.createElement("script");
            scr.src=url+method;
            document.querySelector("head").appendChild(scr);
        }
        //调用
        let url="http://localhost:8080/email/kzq?callback=";
        jsonp(url,"sheng");

第四版

获取灵活数据(终极版本)

前台:

//jsonpcontroller测试JSONP
    @GetMapping("/kzq")
    @ResponseBody
    public String jsonp(String callback) throws JsonProcessingException {
    
    
        System.out.println("jsonp 请求中....");
        System.out.println("传来的参数="+callback);
        List list=new ArrayList();
        list.add("csdn博客");
        list.add("菜鸟教程");
        list.add("w3school");
        list.add("gitee");
        list.add("github");
        //list-->json
        ObjectMapper om=new ObjectMapper();
        String json=om.writeValueAsString(list);
        return callback+"({\"msg\":"+json+"})";
    }

后台:

//第四版获取灵活数据
        //动态发请求
        function jsonp(url,method){
    
    
            let scr=document.createElement("script");
            scr.src=url+method;
            document.querySelector("head").appendChild(scr);
        }
        function myfun4(data){
    
    
            console.log("灵活数据:"+data.msg);
        }
       
        jsonp(url,"myfun4");

效果图:
效果图

第五版Jq

前台与第四版相同
后台:

<!-- 第五版Jquery中发jsonp请求 -->
    <script src="../js/jquery.min.js"></script>
    <script>
        function jsonpofjq(data){
     
     
            alert("jq触发回调函数拿到数据:"+data.msg);
        }
    let url1="http://localhost:8080/email/kzq";
    $.ajax({
     
     
        url:url1,
        async:false,    //false为异步,true为同步
        dataType:"jsonp",
        jsonp:"callback",//默认为callback,可不写
        jsonpCallback:"jsonpofjq",//自定义回调函数
        success:function(data){
     
     
            console.log("JQ="+data.msg);
        }
    })
    </script>

综合练习

基础练习

1、创建三个数组,用for循环对数组进行遍历,使用console.log进行打印。
2、创建三个对象,用foreach遍历对对象中的属性进行遍历,并且console.log进行打印。 
3、创建一个单选框,通过js获取到选中的选项并且打印值。 
4、创建一个多选框,通过js获取到选中的选项,要求这些选项使用,进行分割,最后打印出一个总的字符串。 
5、创建一个下拉框,通过js添加一些选项进去,并设置某一个选项为默认选中。 
6、对第1题的三个数组中的值进行字符串的拼接。

实现:
HTML:

	<input type="radio" name="sexs" value="男生">男生
    <input type="radio" name="sexs" value="女生">女生
    <input type="checkbox" name="like" value="打游戏" />打游戏
    <input type="checkbox" name="like" value="打豆豆" />打豆豆
    <input type="checkbox" name="like" value="睡觉" />睡觉
    <select id="xx">
        <option>选项</option>
    </select>

JS:

//页面加载完成时执行
    window.onload = function () {
    
    
        //1
        var num1=[1,23,421,231];
        var num2=[4,3,331,12];
        var num3=[2,23,221,131];
        for(let i=0;i<num1.length;i++){
    
    
            console.log(i,num1[i]);
        }
        for(let i=0;i<num2.length;i++){
    
    
            console.log(i,num2[i]);
        }
        for(let i=0;i<num3.length;i++){
    
    
            console.log(i,num3[i]);
        }
        //2
        var dx1={
    
    
        name:"下雨",
        age:18,
        addr:"湖南长沙",
        sr:new Date()
        };
        var dx2={
    
    
        name:"小舞",
        age:14,
        addr:"江西吉安",
        sr:new Date()
        };
        var dx3={
    
    
        name:"xiao",
        age:17,
        addr:"江西吉安",
        sr:"2004-06-25"
        };
        for(let i in dx1){
    
    
            console.log(i,dx1[i])
        }
        for(let i in dx2){
    
    
            console.log(i,dx2[i])
        }
        for(let i in dx3){
    
    
            console.log(i,dx3[i])
        }
        //3
        var sexs=document.querySelectorAll("[name=sexs]");
        for(let i in sexs){
    
    
            sexs[i].onchange=function(){
    
    
                if(this.checked==true){
    
    
                alert(this.value)
                }
            }
        }
        //4
        var likes=document.querySelectorAll("[name=like]");
        var szlikes=new Array();
        for(let i in likes){
    
    
            likes[i].onchange=function(){
    
    
                if(this.checked==true){
    
    
                    szlikes.push(this.value);
                }else{
    
    
                    szlikes.splice(szlikes.indexOf(this.value),1);
                }
                console.log("szlikes="+szlikes)
                
            }
        }
        //5
        var sel=document.querySelector("#xx");
        for(var a=0;a<=3;a++){
    
    
        var opt=document.createElement("option");
        opt.innerText="选项卡"+a;
        if(opt.innerText=='选项卡0'){
    
    
            // console.log(opt)
            opt.setAttribute("selected",true);  //设置默认值
        }
        sel.appendChild(opt);
        }
        //6
        var strs=num1.concat(num2.concat(num3));
        console.log("字符串拼接:"+strs)
   }

dom节点练习

修改 奇数个LI的背景色改为yellow
偶数个LI的内容改为BBB
每个LI 加个属性 price=1000内随机数

HTML

	<ul id="txt">
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
    </ul>

JS

	var lis=document.querySelectorAll("#txt li");
        for(let i=0;i<lis.length;i++){
    
    
            if((i+1)%2==0){
    
    
                lis[i].innerHTML="BBB";
            }else{
    
    
                lis[i].style.backgroundColor="yellow";
            }
            lis[i].setAttribute("price",Math.random()*1000)
        }

事件绑定练习

效果图:
在这里插入图片描述

事件绑定练习 留言板点击ADD内容在下方显示,点击DEL删除对应留言)

<!-- 事件绑定练习 留言板-->
    <h1>留言板</h1>
    <input type="text" id="txts" required /><button id="add">ADD</button>
    <hr id="spx"/>
<script>
	 	var add=document.querySelector("#add");
    	add.addEventListener("click",function(){
     
     
        var texts=document.querySelector("#txts");
        console.log(texts.value)//文本框的值
        var p=document.createElement("p");
        var span=document.createElement("span");
        span.innerText=texts.value;
        var delbtns=document.createElement("button");
        var body=document.getElementsByTagName("body");
        delbtns.innerText="DEL";
        p.appendChild(span);
        p.appendChild(delbtns);
        p.className="del";
        body[0].appendChild(p)
        delbtns.addEventListener("click",function(){
     
     
            this.parentNode.parentNode.removeChild(this.parentNode)
        })
    })
</script>

事件冒泡练习

效果图:
在这里插入图片描述

10个按钮,点击每个按钮分别在上方右下角追加显示,用的flex弹性布局

<style>
		.box{
     
     
            display: flex;
            width: 500px;
            height: 700px;
            flex-wrap: wrap;
            background-color: red;
        }
        .box button{
     
     
            width: 150px;
            height: 150px;
            margin: 8px;
            background-color: hotpink;
        }
        .show{
     
     
            background-color: rosybrown;
            width: 500px;
            height: 100px;
            display: flex;
            justify-content: flex-end;
            align-items: flex-end;
        }
</style>
<html>
	<body>
	<!-- 练习按钮值显示 -->
    <div class="show"></div>
    <div class="box">
        <button>7</button>
        <button>8</button>
        <button>9</button>
        <button>4</button>
        <button>5</button>
        <button>6</button>
        <button>1</button>
        <button>2</button>
        <button>3</button>
        <button>0</button>
    </div>
    
	</body>
<script>
	var box=document.querySelectorAll(".box");
    box[0].onclick=function(){
     
     
        let obj=event.srcElement||event.currentTarget;
        // console.log(obj.innerText)
        event.stopPropagation();
        let show=document.querySelectorAll(".show");
        show[0].innerText=show[0].innerText+obj.innerText;
    }		
</script>
</html>

二维数组练习

循环生成3*4表格

	var homework=[
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12]    
    ]
    var tab=document.createElement("table");
    tab.border="1px";
    tab.width="50%";
    for(let i=0;i<homework.length;i++){
    
    
        var tr=tab.insertRow(tab.rows.length);
        for(let j=0;j<homework[i].length;j++){
    
    
            var td=tr.insertCell(tr.cells.length);
            td.innerText=homework[i][j];
        }
    }
    document.body.appendChild(tab);

下拉列表城市二级联动

	<select id="pro" onchange="pro1()">
        <option>请选择省</option>
    </select>
    <select id="city">
    </select>
    <script>
	var citys=
    [
        ['湖南省','长沙市','湘潭市','株洲市','张家界市'],
        ['江西省','吉安市','宜春市','赣州市','井冈山市','南昌市','上饶市'],
        ['上海省','黄浦市','宝山市','卢湾市'],
        ['浙江省','温州市','杭州市']
    ]
    window.onload=function(){
     
     
        let pro=document.querySelector("#pro");
        for(let i=0;i<citys.length;i++){
     
     
        let op=new Option(citys[i][0],citys[i][0]);//(txt,value)
    //  pro.appendChild(op);
        pro.options.add(op);
        }
    }
    //清空city项
    function selclear(){
     
     
        let city=document.querySelector("#city");
    //  city.empty();//jq方法
    //  city.innerHTML="";
        city.options.length=0;
    }
    function pro1(){
     
     
        let pro2=document.querySelector("#pro").value;
        selclear()
        for(let i=0;i<citys.length;i++){
     
     
            for(let j=1;j<citys[i].length;j++){
     
     
                if(pro2==citys[i][0]){
     
     
                    let op=new Option(citys[i][j],citys[i][j]);//(txt,value)
                    let city=document.querySelector("#city");
                    city.options.add(op)
                }
            }
        }
    }
	</script>

函数练习

1、创建一个猫Cat对象,包含一个体重weight属性和吃饭eat的方法,每调用一次eat方法,体重就加1,
调用3次eat方法后,在控制台打印出猫的体重。

 //1、Cat
   function Cat(g){
    
    
       var j=1;
       this.weight=g;
       this.eat=function(){
    
    
           for(let i=1;i>0;){
    
    
           this.weight=this.weight+1;
           if(j==3){
    
    
               console.log(this.weight);
               break;
            }
           j++;
            }
       }
   }
   var cat1=new Cat(6);
   cat1.eat();

2、创建一个Car对象,包含一个花费属性cost和run方法,run方法中包含一个参数公里数kl,
每跑1公里,花费就增加0.8元,调用run方法后,打印出花费。

//2、Car
   function Car(km){
    
    
    this.cost=km*0.8;
    this.run=function(){
    
    
        console.log("花费money="+this.cost)
        return this.cost;
    }
   }
   var car1=new Car(2);
   car1.run();  //花费money数量

3、new 打印机 name 名字 print() 每3秒打印下自己的名字,打10次停

//new 打印机
    //name名字
    //print()   每三秒打印下自己的名字
    function Dyj(name){
    
    
        this.name=name;
        this.print=function(){
    
    
            let i=1;
            let that=this; //保存当前对象this
            var time=setInterval(function(){
    
    
            if(i==10){
    
    
                alert("10次了")
                clearInterval(time);
            }
            console.log(that.name);
            i++;
            }, 3000);
        };
    }
    var dy=new Dyj("惠普打印机");
    dy.print();
    var dy2=new Dyj("傻吊")
    dy2.print();

定义一个函数,他有两个参数,一个是执行次数,一个是需要执行的函数,调用这个函数。

//1
    function hs(){
    
    
        console.log("我是要被执行的函数");
    }
    function fun1(count,fun){
    
    
        for(let i=1;i<=count;i++){
    
    
            fun();
        }
    }
    fun1(3,hs);

定义一个函数,它的返回值是另外一个函数,另外这个函数有一个打印语句,请调用函数运行这个打印语句。

//2
    function fun2(){
    
    
        return function(){
    
    console.log("第二题打印语句");}
    }
    var funcon=fun2();
    funcon()

同时定义和运行一个匿名的函数,计算1到100之间的整数和

 var sum=0;
    (function(){
    
    
        for(let j=1;j<=100;j++){
    
    
            sum=sum+j;
        }
        console.log("1~100整数和为:"+sum);
    })();

创建一个Dog对象,包含一个摇尾巴shake的方法,该方法有一个参数name,当name等于’Tom’时,在控制台打印‘主人回来了’,其他的值不执行任何代码。

//6 Dog
    function Dog(na){
    
    
        this.shake=function(){
    
    
            this.name=na;
            if(this.name=='Tom'){
    
    
                alert("主人回来了")
            }
        }
    }
    var dog=new Dog("Tom");
   dog.shake();

创建一个函数,包含一个参数a,当a是函数时,执行a,否则打印出a的值。

 //7
    function fun3(a){
    
    
        if(typeof a=='function'){
    
    
            a();
        }else{
    
    
            console.log(a);
        }
        
    }
    fun3(123)

在页面创建三个按钮,通过js脚本循环给这三个按钮绑定一个点击事件,当点击第一个按钮弹出数字0,第二个按钮弹出数字1,第三个按钮弹出数字2

 //8
    window.onload=function(){
    
    
    for(let i=0;i<3;i++){
    
    
        let btn=document.createElement("button");
        btn.style.width='60px';
        btn.style.height='60px';
        btn.innerText="按钮"+i;
        document.body.appendChild(btn);
        btn.onclick=function(){
    
    
            let txt=this.innerText.substring(2);
            alert(txt)
        }
    }
    }
函数递归练习

模拟递归C盘所有文件(JSON对象)

//模拟递归C盘所有文件
    var root={
    
    
        name:'C盘',
        children:[{
    
    
            name:'学习',
            children:[{
    
    
                name:'电子书',
                children:[
                    {
    
    
                        name:'文学',
                        children:[
                            {
    
    name:'三体'},{
    
    name:'红与黑'}
                        ]
                    }
                ]
            }
            ]
        },
        {
    
    
            name:'电影',
            children:[
                {
    
    name:'美国电影',children:[{
    
    name:'变形金刚'}]},
                {
    
    name:'中国电影',children:[{
    
    name:'长津湖'},{
    
    name:'斗罗大陆'}]}
            ]
        }]
    }
    //4
    function getAllJson(jsons, name, sign) {
    
    
    if(name == "" || name == undefined) {
    
    
        name = "json"
    }
    for(key in jsons) {
    
    
        var k = name + sign + key;
        if(!(jsons[key] instanceof Object)){
    
    
            console.log(k + " = " + jsons[key]); //如果不是Object则打印键值
        }else{
    
    
            getAllJson(jsons[key], k, sign); //如果是Object则递归
        } 
    }
};
//调用
getAllJson(root, "", ">");

闭包练习

创建一个Car类,包含车牌号码和颜色属性,
通过闭包实现类似于JAVA中的封装属性的功能(即只能通过getter和setter方法访问到车牌号码和颜色)

//2
    var Car=function(num,ys){
    
    
        var number=num;
        var color=ys;
        return{
    
    
                getNumber:function(){
    
    
                    return number;
                },
                setNumber:function(shu){
    
    
                    number=shu;
                },
                getColor:function(){
    
    
                    return  color;
                },
                setColor:function(col){
    
    
                    color=col;
                }
        };
    }
    var car1=new Car("赣D88888","red");
    console.log(car1.getNumber());
    console.log(car1.getColor());
    car1.setNumber("赣D12313");
    car1.setColor("blue");
    console.log(car1.getNumber());
    console.log(car1.getColor());

(面试题)定义一个函数repeat;function repeat(func,nums,times){}
//调用方法 var a=repeat(alert,6,3000) a(“你好”) alert六次"你好" 每次间隔3秒

//3
    function repeat(func,nums,times){
    
    
        return function(t){
    
    
            var count=1;
            var xh=setInterval(function(){
    
    
                if(count==nums){
    
    
                    clearInterval(xh);
                }
                func(t);
                count++;
            },times)
        }
    }
    var a=repeat(alert,6,3000);
    a("你好")

jsonp练习

JSONP 查每个省的大学信息 数据库的数据

两个sql语句
getshengselect distinct province from university
getschoolselect *from university where province=#{province}
前台controller

 @GetMapping("/sheng")
    @ResponseBody
    public String sheng(String callback) throws JsonProcessingException {
    
    
        List sheng=userService.getsheng();
        System.out.println("sheng="+sheng);
        //list-->json
        ObjectMapper om=new ObjectMapper();
        String json=om.writeValueAsString(sheng);
        return callback+"({\"msg\":"+json+"})";
    }
    @GetMapping("/university")
    @ResponseBody
    public String getuniversity(String callback,String msg) throws JsonProcessingException {
    
    
        List school=userService.getschool(msg);
        System.out.println("school="+school);
        //list-->json
        ObjectMapper om=new ObjectMapper();
        String json=om.writeValueAsString(school);
        return callback+"({\"msg\":"+json+"})";
    }

后台请求数据

<body>
    <select id="sheng">
    </select>
    <div id="school"></div>
</body>
<script>
// 作业: JSONP  查每个省的大学信息  (查省,查对应大学)
var shengs=document.querySelector("#sheng");
$.ajax({
     
     
    url:"http://localhost:8080/email/sheng",
    async:false,
    dataType:"jsonp",
    success:function(data){
     
     
        for(var i=0;i<data.msg.length;i++){
     
     
        // console.log("省="+data.msg[i].province);
        var opt=new Option(data.msg[i].province,data.msg[i].province);
        shengs.appendChild(opt);
        }
    }
})
shengs.onchange=function(){
     
     
    $.ajax({
     
     
    url:"http://localhost:8080/email/university?msg="+this.value,
    async:false,
    dataType:"jsonp",
    success:function(data){
     
     
        $("#school").html("");
        for(var i=0;i<data.msg.length;i++){
     
     
        // console.log("省="+data.msg[i].schoolName);
        $("#school").html($("#school").text()+"&nbsp;&nbsp;&nbsp;"+data.msg[i].schoolName)
        }
    }
})
}
</script>

完结 ojbk…通过改变下拉框的省显示对应的大学-----------------------------------------------------

猜你喜欢

转载自blog.csdn.net/m_xiaozhilei/article/details/121944559
今日推荐