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
构造器调用模式
构造函数在创建对象的时候, 做了些什么
- 使用 new 引导构造函数, 创建了一个实例对象
- 在创建对象的同时, 将this指向这个刚刚创建的对象
- 在构造函数中, 不需要 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()+" "+data.msg[i].schoolName)
}
}
})
}
</script>
完结 ojbk…通过改变下拉框的省显示对应的大学-----------------------------------------------------