四天学会JavaScript(Day1~Day4)
Day1
前言
一年一度的国庆长假终于来了,但是对于一名菜鸟来说,是绝对不能放过这么好的一个学习机会的,所以我打算花七天的时间把JavaScript的大体内容简单的过一遍。前端这一块呢,我几乎是一个小白。过去也只是写写Ajax,或者整几个XX事件,接收接收数据而已。所以这个国庆我是计划用七天的时间把JavaScript语言从头到尾,简单的过一遍。毕竟本人是后端开发的程序员,前端也不需要太过深入,换句话说是暂时不用太过深入。于是,前天下班的时候我就找领导借了本七百多页【JavaScript高级程序设计】的书,那么这四天的博客就是我四天的笔记。我会尽量把书中的精华总结出来。
一般情况下呢,一个后端程序员在他入职之前肯定是经历了一个学习阶段。而学习阶段肯定是学过Servlet,JSP的,不然后面的SSM什么的都没法学。而学JSP的前提也是要首先会一点HTML,CSS,JavaScript或者Jquery。所以说像这种速成的学法比较适合有一定基础的人而不是零基础。零基础如果要专门学前端的话不建议速成。
第一天的学习内容
JavaScript基本语法
垃圾收集机制
引用数据类型
Array类型
顺序栈数据结构
顺序队列数据结构
RegExp
JavaScript简介
JavaScript是诞生于1995年,很多没接触过JavaScript的人可能会认为这个语言一定和Java有关系,然而事实并不是这样。
JavaScript刚诞生的时候,主要目的还是为了处理以前由服务器端语言比如说Perl负责的一些输入验证操作。再此之前,必须把表单数据发送到服务器端才能确定用户是否没有填写某个必填域,学过JavaWeb的人一定是很容易理解这个概念的。如果说表单的每次请求都要发给后端才能验证判断是否遗漏哪些必填项的话,响应的速度肯定是会慢很多的。所以现在JavaScript也逐渐成为市面上常见浏览器的必备功能。
现如今呢,JavaScript已经变成了一个功能非常全面的编程语言,它从一个简单的输入验证器发展到现在确实非常出乎人的意料。你可以说它是一个非常简单的编程语言,也可以说它是一个非常难学的编程语言。说它简单,是因为它可以很快学会使用,但是如果要深入掌握,那就需要很多年的时间了。而我呢,是打算七天学完,所以说,我这七天也仅仅只是学会它的使用而已。如果要再深入研究底层的话应该是需要很长时间。
JavaScript基本语法
JavaScript的语法很多都借鉴了C语言或者类C语言。在JavaScript中是区分大小写的,第一个字符必须是一个字母、下划线(_)或者美元符号($)符号。注视这一块也是C语言风格的注释,可以是//也可以是/**/。
typeof 操作符可以让用户知道变量是什么数据类型。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>网页标题</title>
<script type="text/javascript">
var flag = true;
alert(typeof flag);
//返回结果是 boolean
</script>
</head>
<body>
</body>
</html>
NAN
NAN是英文Not a Number的缩写,从英文意思就知道是非数值。这个数值主要表示本来要返回一个数值的操作数未返回数值的情况。(这样就不会抛错误了)。就举个例子,当 9 / "hello" 的时候,返回的则是NAN。因为9是数值但是"hello"不是数值而是字符串。isNAN()函数就是用来判断一个值到底是不是数值
alert(isNaN(NaN)); //true
alert(isNaN(666)); //false
数值转换
在JavaScript里面有三个函数可以把非数值转换成数值: Number()、parseInt()、parseFloat()。第一个函数Number可以用于任何数据类型、另外两个函数就是专门给字符串用的,在Java语言里面也见过这样的方法。
使用Number转化成数值的时候,字符串必须完全是数字,否则返回NAN。使用parseInt的时候,如果第一个字符是数值那么它会判断第二个字符是不是数值。直到遇见非数值的时候,后面的就不会再判断直接返回前面的内容了。就比如num3只返回了15一个道理。
var num1 = Number("helloworld"); //NAN
var num2 = parseInt("hello"); //NAN
var num3 = parseInt("15asf96"); //15
var num4 = parseInt("4546465"); //4546465
var num5 = Number("asf45448f4sa86"); //NAN
var num6 = Number("15464"); //15464
var num7 = Number("15asfasf"); //NAN
alert(num1 + " " + num2 + " " + num3 + " " + num4 + " " + num5 + " " + num6 + " " + num7);
字符串面量
\n | 换行 |
\t | 制表 tab |
\b | 退格 |
\r | 回车 |
\\ | 斜杠 |
\' | 单引号 |
\"" | 双引号 |
\xnn | 以十六进制代码 nn 表示一个字符 |
\unnn | 以十六进制代码表示一个uniCode字符 |
for-in 语句
有点像for each
for(var propName in window){
document.write(propName);
}
with语句
with语句的作用是把代码的作用域全都设置到一个特定的对象中。下面两段代码的作用是相同的。
var str = "today is great day";
var a = str.substring(2);
var b = str.charAt(3);
alert("a = " + a + " b = " + b);
var str = "today is great day";
with(str){
var a = substring(2);
var b = charAt(3);
alert("a = " + a + " b = " + b);
}
函数
在JavaScript中函数都是统一使用function来声明。如果需要返回直接return就好了。
function my(num1,num2){
return num1 + num2;
}
var result = my(9,9);
alert("result = " + result);
没有重载
在JavaScript中,函数没有重载。假如程序员定义了两个名字相同的函数,调用的时候则会调用下面的那个。
= = 和 = = = 有什么区别?
“= = =”首先计算其操作数的值,然后比较这两个值,比较过程没有任何类型转换。相等运算符“= =”如果两个操作数不是同一类型,那么相等运算符会尝试一些类型转换,然后进行比较
var a = 1;
var b = '1';
alert(a == b); //true
alert(a === b); //false
垃圾收集
JavaScript具有自动垃圾收集机制,也就是说执行环境会负责管理代码执行过程中使用的内存。而在C和C++之类的语言中,开发人员的基本任务就是手工跟踪内存的使用情况,这样很容易造成许多问题。这个垃圾收集器的工作原理也很简单,其实就是找到那些不用的变量,然后释放掉它的内存。不需要像C++一样还要去delete。
当我们在一个函数中定义了一个局部变量,那么这个局部变量会在该函数执行的过程中存在。而这个过程中会为该局部变量在栈(或者堆)的内存上分配相应的空间以便存储他们的值。直到函数要执行结束了,这个时候局部变量就没有存在的必要,然后就会释放他们供内存使用。
标记清除
JavaScript中最常见的垃圾清理方式是标记清除。当变量进入环境的时候会将这个变量标记为进入环境,当变量要离开的时候会被标记成离开环境。垃圾收集器会在运行的时候给存储在内存中的所有变量都加上标记,然后它会去掉环境中的变量以及被环境中的变量引用的变量标记。而在此之后再被加上标记的变量就会被视为准备删除的变量,原因是环境中的变量已经无法访问这些变量了。最后垃圾收集器完成内存清除的工作。销毁那些带标记的值并收回他们所占用的内存空间。
管理内存
虽然JavaScript已经具有了垃圾收集机制,但是在内存管理和垃圾收集面临的问题还是有点与众不同。最常见的问题就是分配给Web浏览器的可用内存数量通常要比分给桌面的要少。这样做的目的主要是为了防止运行JavaScript的网页耗尽全部系统内存而导致系统崩溃。内存限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及在一个线程中能够同时执行的语句数量。所以说我们要确保占用最少的内存给浏览器最好的性能。
如果说一个数据已经不再有用了,则可以把他置为Null来释放这个引用。通常称之为解除引用。
function fun(name){
var obj = new Object();
obj.name = name;
return obj;
}
var local = fun("hello world");
alert(local);
//手工解除引用
local = null;
不过,这种做法并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,方便垃圾收集器下次执行的时候将其回收。
引用数据类型
Object类型
JavaScript中对象其实就是一组数据和功能的集合。对象可以通过执行new操作符跟要创建的对象类型的名称来创建。而创建Object类型的实例并为其添加属性或者方法就可以创建自定义对象。下面三段代码作为操作的案例。
使用构造函数的方法创建
function fun(){
var obj = new Object();
obj.name = "alvin";
obj.age = 12;
obj.score = 98;
alert("姓名: " + obj.name + " 年龄: " + obj.age + " 成绩: " + obj.score);
}
使用对象字面量的方法创建
var person = {
name : "bob",
age : 18,
score : 98
};
alert("姓名: " + person.name + " 年龄: " + person.age + " 成绩: " + person.score);
还可以直接 = {},此类操作和 new Object() 是相同的
var person = {
};
person.name = "alvin";
person.age = 18;
person.score = 78;
alert("姓名: " + person.name + " 年龄: " + person.age + " 成绩: " + person.score);
Array类型
作为一名后端程序员来说,一看名字就知道这是数组,但是JavaScript的数组和Java或者C语言的数组不太一样。JavaScript的数组使用起来更加有点像是Python语言里面的列表。在C语言里面,数组的大小和类型都是固定的。也就是说,一旦定义了数组的大小和类型就不再可以改变。而JavaScript的数组大小可以动态调整,并且存储的类型可以是任何类型。下面一段代码举个例子。
var arr = new Array();
arr[0] = "hello";
arr[1] = 123;
arr[2] = 9.9;
arr[3] = true;
alert(arr);
数组的创建方法还有一种,就是前面说过的字面量表示法
var arr = [1,2,3,4,5,6,7];
alert(arr);
检测数组
在JavaScript里,如果要确定一个对象是不是数组就可以使用 instanceof 操作符得到满意的结果。
var arr = [1,2,3,4,5];
if(arr instanceof Array){
alert("是数组");
}else{
alert("不是数组");
}
但是这么做的话又会有一个问题,那就是它假定只有一个全局执行环境。如果网页中包含多个框架,那实际上就存在两个完全不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。如果说我要从一个框架向另一个框架传入数组。那么传入的数组和第二个框架中原生创建的数组分别具有各自不同的构造函数。于是乎后面就出现了Array.isArray()方法。
var arr = [1,2,3,4,5];
if(Array.isArray(arr)){
alert("是数组");
}else{
alert("不是数组");
}
转换方法
在JavaScript中所有对象都具有toLocaleString()、toString()和valueOf()方法。其中呢,valueOf 返回的还是数组本身,而调用toString就会返回数组的字符串。而每个元素之间都会有一个逗号,学过Java语言的话一定深有体会。
toLocaleString() 和 toString咋一看显示的内容好像差不多啊。但实际上还是有一定区别的。toLocaleString()是为了取得每一项的值,调用的是每一项的toLocaleString()方法,而不是toString()方法。
栈和队列
栈和队列都是属于数据结构一类,本人过去曾写过这类的博客。
在JavaScript中也提供了一种让数组的行为类似于其他数据结构的方法。就比如说,数组可以表现得像栈。栈是一种可以限制插入和删除的数据结构,其本质更像是一种受限制的线性表。栈既可以用数组表示也可以用链表表示,而在这里自然是数组表示的顺序栈。
push()方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并且返回修改数组的长度。而pop()方法则是从数组末尾移除最后一项,减少length值。然后返回移除的项。
//创建一个数组
var arr = new Array();
//推入两项
var count = arr.push("alvin","bob");
alert(count); //2
//再推入一个
count = arr.push("finally");
alert(count);
//取得最后一项
var item = arr.pop();
alert(item); //这里返回的是 finally。 也就是最后一项
//结果
alert(arr);
接着我们说说队列。队列和栈一样都是受限制的线性表。然后队列和栈是相反的数据结构,可以参考博客栈和队列的基本概念。栈是先进后出,而队列则是先进先出。由于push()是向数组末尾添加项的方法,所以模拟队列就需要一个从数组前端取的项的方法。而实现这个操作的方法则是shift()。它能够移除数组的第一项并且返回该项,然后数组长度-1。shift和push结合可以让数组用起来像是队列。
//创建一个数组
var arr = new Array();
//推入两项
var count = arr.push("alvin","bob");
alert(count); //2
//再推入一个
count = arr.push("finally");
alert(count);
//取得最后一项
var item = arr.shift();
alert(item); //这里返回的是 finally。 也就是最后一项
//结果
alert(arr);
我们发现代码其实没什么改变,只是把pop换成了shift而已~
排序方法
在数组中提供了两个用来排序的方法。它们分别是sort和reverse。sort是顺序,reverse是逆序,也就是翻转。
迭代方法
在JavaScript中为数组定义了五个迭代方法。每个方法接收两个参数。要在每一项上运行的函数作为该函数作用域对象。影响this本身。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。根据使用的方法不同,这个函数执行后的返回值可能会也可能不会影响方法的返回值。这里分别介绍一下
every() | 对数组中的每一项给定运行函数,如果该函数对每一项都返回true,那么就返回true |
filter() | 对数组中的每一项给定运行函数,返回该函数会返回true的项组成数组。 |
forEach() | 对数组中的每一项给定运行函数,这个方法没有返回值/ |
map() | 对数组中的每一项给定运行函数,返回每次调用的结果组成的数组 |
some() | 对数组中的每一项给定运行函数,如果该函数对任一项返回true那么就返回true。 |
语法示例
var numbers = [1,2,3,4,5,6,7];
var result = numbers.some(function(item,index,array){
return (item > 2);
});
alert(result);
归并方法
在JavaScript中还为数组提供了两个归并数组的方法。他们都会迭代数组的所有项然后构建一个最终返回的值。reduce()是从第一个开始。而reduceRight()则是从最后一个开始。
//求数组中所有值之和
var arr = [1,2,3,4,5];
var sum = arr.reduce(function(prev,cur,index,array){
return prev + cur;
});
alert(sum);
Date类型
JavaScript中的Data类型是在早期Java语言中util包中的Date基础上构建的。方法比较多,使用的时候可以看手册或者API。
//获得当前的时间
var now = new Date();
alert(now);
//设置时间
now = new Date("2018-9-12");
alert(now);
toDateString() | 以特定的格式显示年,月,日,周 |
toTimeString() | 以特定的格式显示时,分,秒,地区 |
toLocaleDateString() | 以特定地区的格式显示年,月,日,周 |
toLocaleTimeString() | 以特定地区的格式显示年,月,日,周 |
toUTCString() | 以特定的格式完整的UTC日期 |
RegExp
JavaScript通过RegEXp类型来支持正则表达式
var patt=/pattern/modifiers;
pattern(模式) 描述了表达式的模式
modifiers(修饰符) 用于指定全局匹配、区分大小写的匹配和多行匹配
当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。比如,以下是等价的:
var re = new RegExp("\\w+");
var re = /\w+/;
每个正则表达式都可带有一或多个标志(flags),用来表明正则表达式的行为。正则表达式的匹配模式支持三种标志。
g : 表示全局模式。这个模式将被应用于所有字符串,而不是在发现第一个匹配项的时候就立即停止。
i : 表示不区分大小写模式。也就是确定匹配项时忽略模式和字符串的大小写。
m :表示多行模式,就是在到达一行文本末尾时还会继续查找下一行中是否与模式匹配的项。
所以说一个正则表达式就是一个模式和三个标志的组合体。不同的组合产生不同的效果。
//匹配字符串中所有good 实例
var pattern = /good/g;
//匹配第一个bat或cat 不区分大小写
var pattern2 = /[bc]at/i;
//匹配所有以at结尾的三个字符的组合,不区分大小写
var pattern3 = / .at/gi;
字面量模式 | 等价的字符串 |
/
|
"\ \[bc\\]at" |
/\.at/ | "\\.at" |
/name\/age/ | "name\\/age" |
/\d. \d{1,2}/ | "\\d. \\d{1,2}" |
/\w\\hello\\123/ | "\\w\\\\hello\\\\123" |
使用正则表达式字面量和使用RegExp构造函数创建的正则表达式不太一样。在JavaScript中正则表达式字面量始终会共享同一个RegExp实例,而使用构造函数创建的每一个RegExp实例都是一个新的实例。
RegExp实例属性
global | 布尔值,表示是否设置了g的标志 |
ignoreCase | 布尔值,表示是否设置了i的标志 |
lastIndex | 整数,表示开始搜索下一个匹配项的字符位置,从0算起。 |
multiline | 布尔值,表示是否设置了m的标志 |
source | 正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。 |
通过这些属性可以获知一个正则表达式的各方面信息
var pattern = /\[bc\]at/i;
//false
alert(pattern.global);
//true
alert(pattern.ignoreCase);
//false
alert(pattern.multiline);
//0
alert(pattern.lastIndex);
//\[bc\]at
alert(pattern.source);
Day2
前言
今天是国庆假期的第三天,也是我学JavaScript的第二天。我们知道,对于一个已经在职的程序员来说,学习一门新的编程语言,其实也就是学习它的语法,因为编程语言的概念大部分都是互通的,只要语法理解了就好上手。JavaScript我是用速成的方法学习,主要目的还是想把里面的东西都过一遍知道这些到底是怎么一回事。以后写代码看API的时候也容易看得懂,但是由于时间过短。语法和特性有可能会忘记一些,这种情况是很糟糕的。为了确保这七天下来,我能把语法和一些特性给记住,所以我决定每天学习完当天的内容之后,再使用JavaScript实现一种数据结构。这样七天下来我才能够记住语法并且看API也可以写的来。
第二天学习的内容
面向对象程序设计
链表数据结构(面向对象语法练习)
BOM
DOM
事件
RegExp后续
RegExp构造函数属性
RegExp构造函数包含了一些属性,这些属性适用于作用域中的所有正则表达式,并且基于所执行的最近一次正则表达式操作而变化。关于这些属性的另一个独特之处,就是可以通过两种方式访问他们。换句话说这些属性分别有一个长属性名和一个短属性名。
长属性名 | 短属性名 | 说明 |
input | $_ | 最近一次要匹配的字符串。Opera未实现此属性 |
lastMatch | $& | 最近的一次匹配项。Opera未实现此属性 |
lastParen | $+ | 最近一次匹配的捕获组。Opera未实现此属性 |
leftContext | $' | input字符串中lastMatch之前的文本 |
multiline | $* | 布尔值,表示是否所有表达式都是多行模式。IE和Opera未实现此属性 |
rightContext | $' | input字符串中lastMatch之后的文本 |
面向对象程序设计
关于面向对象的概念呢,这里就不多说了,直接学习语法就可以了。面向对象编程思想
昨天学习了引用数据类型Object。所以现在也就大概知道对象是怎么创建的了。今天写两段代码回顾一下
对象的创建
构造函数法
var person = new Object();
person.name = "alvin";
person.age = 18;
//对象的方法
person.sum = function(){
alert(person.name);
}
//调用
person.sum();
字面量法
var person = {
name : "alvin",
age : 19,
fun : function(){
alert("hello world");
}
};
person.fun();
除了这两种方法以外我们还有其他创建方式
工厂模式(寄生构造函数模式)
工厂模式是软件工程领域的一种广为人知的设计模式。这种模式抽象了创建具体对象的过程。
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.hello = function(){
alert("hello");
}
return o;
}
var person = createPerson("alvin",19,"work");
person.hello();
alert(person.name);
构造函数模式
构造函数和普通的函数本质上没什么区别,只是构造函数在调用的时候是用new罢了。按照写代码的规范,构造函数一般就使用大写字母开头。
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.hello = function(){
alert("hello");
};
}
var per = new Person("alvin",19,"work");
per.hello();
alert(per.name);
原型模式
我们创建的所有函数都包含了prototype属性,这个属性是一个指针,指向一个对象。而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
function Person(){
}
Person.prototype.name = "alvin";
Person.prototype.age = 29;
var per1 = new Person();
var per2 = new Person();
alert(per1.name == per2.name); //true
in操作符除了可以在for循环的时候使用,也可以用来判断一个属性是否存在一个对象里面。如果有就返回true,否则返回false。如果想要删除对象的属性的值则可以使用delete
function Person(){
}
Person.prototype.name = "alvin";
alert("name" in Person); //true
alert(Person.prototype.name); //alvin
delete Person.name;
alert(Person.name); //什么也没有
更简单的原型语法
function Person(){
}
Person.prototype={
name : "alvin",
age : 29,
job : "java",
hello : function(){
alert("hello");
}
}
var per = new Person();
per.hello();
alert(per.name);
组合使用构造函数模式和原型模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype = {
constructor : Person,
hello : function(){
alert("hello");
}
}
var per = new Person("alvin",19,"java");
alert(per.name);
per.constructor.age = 7;
alert(per.constructor.age);
继承
在JavaScript里面描述了原型链的概念,并且将原型链作为继承的主要方法。基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。实现原型链的一个基本模式代码如下
function SuperType(){
this.prototype = true;
}
SuperType.prototype.getSuperValue = function(){
return this.prototy;
}
function SubType(){
this.subproperty = false;
}
//继承SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSuperValue = function(){
return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue());
面向对象这块,内容比较多。下次有时间我单独学这一块。因为对于后端的我来说可能用的也不太多。今天还是主要把精力放在BOM和DOM上。接下来就再实现一个单链表数据结构来巩固下语法。
面向对象练习(实现单链表数据结构)
关于单链表数据结构,我过去也写过一些这样的博客。那么今天为了巩固JavaScript在面向对象这一块儿的语法,就用JavaScript来实现一遍单链表的增删查改吧~不过我说实话...数据结构这种东西和编程语言也没有太大关系。它只是一种思想。所以等下我的代码风格可能还是和以前写C语言的风格差不多。
这里就再用JavaScript写一遍链表。
//单向链表类
function SingleLinkList(){
//内部类
function Node(data){
this.data = data;
this.next = null;
}
//头节点
var head = new Node(null);
//新增
this.add = function(data){
var temp = new Node(data);
temp.next = head.next;
head.next = temp;
};
//遍历
this.print = function(){
var temp = head.next;
while(temp!= null){
if(temp.next != null){
console.log(temp.data + "->");
}else{
console.log(temp.data);
}
temp = temp.next;
}
};
//修改
this.replace = function(index,newData){
var temp = head.next;
var i = 0;
//先找到它,找到之后直接改就是
while(temp != null){
if(i == (index - 1)){
break;
}
i++;
temp = temp.next;
}
var f = new Node(newData);
temp.next.data = f.data;
};
//删除
this.del = function(index){
//找到之后直接删就是。。。
var temp = head.next;
var i = 0;
//先找到它,找到之后直接改就是
while(temp != null){
if(i == (index - 1)){
break;
}
i++;
temp = temp.next;
}
temp.next = temp.next.next;
}
}
//main函数
function main(){
var list = new SingleLinkList();
for(var i = 0; i < 10; i++){
list.add(i);
}
list.replace(3,666);
list.del(6);
list.print();
}
main();
BOM
window对象
BOM的核心对象是window,它表示一个浏览器的实例。在浏览器中,window对象有双重角色。它既是通过JavaScript访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象。这意味着网页中定义的任何一个对象、变量和函数,都以window作为其Global对象,因此也有权限访问parseInt()等方法。
window常用的属性
closed | 返回窗口是否已被关闭 |
document | 文档对象 |
history | 客户访问过的URL的信息 |
location | 当前 URL 的信息 |
navigator | 管理浏览器基本信息 |
opener | 返回对创建此窗口的窗口的引用 |
screen | 客户端的屏幕和显示性能的信息 |
self | 返回对当前窗口的引用。等价于 Window 属性 |
status | 设置窗口状态栏的文本 |
top | 返回最顶层的先辈窗口 |
window常用的函数
alert() | 显示带有一段消息和一个确认按钮的警告框。 |
confirm() | 显示带有一段消息以及确认按钮和取消按钮的对话框。 |
prompt() | 显示可提示用户输入的对话框 |
open() | 打开一个新的浏览器窗口或查找一个已命名的窗口。 |
close() | 关闭浏览器窗口 |
setInterval() | 按照指定周期(以毫秒计)来调用函数或计算表达式。 |
setTimeout() | 在指定的毫秒数后调用函数或计算表达式。 |
clearInterval() | 取消由 setInterval() 设置的 timeout。 |
clearTimeout() | 取消由 setTimeout() 方法设置的 timeout。 |
location对象
location对象是最有用的BOM对象之一。它提供了与当前窗口中加载的文档信息,还提供了一些导航功能。事实上,localtion还是一个很特别的一个对象。因为它即是window对象的属性,也是document的属性。换句话说,window和document引用的都是同一个location。
至于属性和方法会用就行,不用去记。需要的时候可以翻API。
document.write("<h3>location对象:代表当前打开窗口的URL</h3>")
document.write("<br>主机名:"+location.hostname);//主机名 127.0.0.1
document.write("<br>端口名:"+location.port); // 端口 8020
document.write("<br>主机名+端口名:"+location.host);//127.0.0.1:8020
document.write("<br>当前文档URL:"+location.href);//!!!!!! 完整的URL
document.write("<br>"+new Date().toLocaleString());
history对象
history对象保护着用户上网的记录,从窗口被打开的那一刻算起。因为history是window对象的属性。所以每个浏览器窗口,每个标签页乃至每个框架都有自己的history对象与特定的window对象关联。因为安全方面的考虑,开发人员无法得知用户浏览过的URL。不过借由用户访问过的页面列表,同样可以在不知实际URL的情况下实现后退和前进。
//后退一页
history.go(-1);
//前进一页
history.go(1);
//跳转最近的某个页面
history.go("wrox.com");
navigator对象
这个对象的主要作用就是管理浏览器基本信息
document.write("<h3>history对象:有关客户访问过的URL的信息</h3>")
document.write("<h3>navigator对象:管理浏览器基本信息</h3>")
document.write("<br>浏览器名称:"+navigator.appName);
document.write("<br>浏览器版本:"+navigator.appVersion);
document.write("<br>浏览器类型:"+navigator.userAgent);//!!!!!
document.write("<br>操作系统:"+navigator.platform);
document.write("<br>是否启用java:"+navigator.javaEnabled());
var browserType = navigator.userAgent.toLowerCase();
//输出浏览器名称
if(browserType.indexOf("msie")>=0){
document.write("IE");
}else if(browserType.indexOf("chrome")>=0){
document.write("chrome");
}else if(browserType.indexOf("firefox")>0){
//document.write(" 火狐");
alert("火狐");
}else{
document.write("other");
}
DOM
DOM是针对HTML和XML文档的一个API,DOM描绘了一个层次化的结点树。允许开发人员添加、移除、修改某个页面的部分。
Node类型
DOM1级定义了一个Node接口,该接口将由DOM中的所有结点类型实现。这个Node接口在JavaScript中作为Node类型实现的。除了IE以外,在其他所有浏览器中都可以访问这个类型。JavaScript中的所有类型都继承自Node类型,因此所有结点都共享相同的结点属性和方法。
document类型
JavaScript中通过Document类型表示文档。在浏览器中document对象是HTMLDocument的一个实例(继承自Document类型),表示整个HTML页面。而且document对象是window对象的一个属性。因此可以将其作为全局对象来访问。
Element类型
除了Docuemnt以外,Element算是最常用的类型了。Element类型用于表现XML或HTML元素,提供了对元素标签名、子节点及特性的访问。
document的基本使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
function testGetElementById(){
//获得名字的id
var elem = document.getElementById("username");
//直接打印那条id所在的Input语句
console.info(elem);
//
console.info(elem.type+" "+elem.id+" "+elem.name+" "+elem.value);
elem.value="修改后的value";
}
function testGetElementsByName(){
//获得所有name是hobby的数组
var arr = document.getElementsByName("hobby");
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
}
function testGetElementsByTagName(){
//获得所有的标签名称,可以是option,也可以是span。
var arr = document.getElementsByTagName("option");
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
}
function testParentNode(){
var elem = document.getElementById("username");
console.info(elem);
var formElem = elem.parentNode.parentNode.parentNode.parentNode.parentNode;
console.info(formElem);
}
function testChildNodes(){
var elem = document.getElementById("professional");
var arr = elem.childNodes;
console.info(arr.length);
for(var i=0;i<arr.length;i++){
if(arr[i].nodeType==1){
console.log(arr[i]+ " "+arr[i].value+" "+arr[i].nodeType);
}
}
}
function testSiblings(){
var elem = document.getElementById("p2");
var elem2 = elem.previousElementSibling;
console.info(elem2)
}
window.onload = testParentNode;
</script>
</head>
<body>
<form action="" id="form1">
用户名:<input type="text" name="username" id="username" value="请输入姓名" ><br />
密码:<input type="password" name="pwd" id="pwd" /><br />
爱好<input type="checkbox" name="hobby" value="music" checked/>音乐
<input type="checkbox" name="hobby" value="sports" />体育
<input type="checkbox" name="hobby" value="art" />美术<br />
职业:<select name="professional" id="professional">
<option value="1">工人</option>
<option value="2" id="p2">农民</option>
<option value="3" selected="selected">解放军</option>
<option value="4">知识分子</option>
</select><br />
<input type="button" value="提交" onclick="testGetElementsByTagName()"/>
</form>
</body>
</html>
事件
事件这个东西比较简单,主要作用就是让客户点击HTML按钮的时候触发某个JavaScript的函数...而且刚刚操作DOM的时候也用到了onclick单击事件。当然还有好多其他的事件,也不用去记。要的时候看API或者看手册就可以了~
可能今天学的东西都不太深入。其实我是打算最后两天的时候再做个总结。
Day3
前言
今天是国庆假期的第四天,也是我学习JavaScript的第三天。为了能够熟练语法,今天就打算用JavaScript实现一遍二叉树数据结构。然后今天还打算把Ajax和Json复习一下,再把Jquery的一些常用操作复习一下。明天就开始写前端项目,还有bootstrap和Vue框架。
今天学习的内容
二叉树数据结构(面向对象语法复习)
Ajax和Json
jQuery的使用
表单验证案例
增删查改的购物车
错误处理和调试
二叉树数据结构
二叉树数据结构如果仅仅只是说我要遍历的话,那还是比较简单的。二叉树的遍历方法呢,我们可以使用递归来遍历,但是递归的话如果真正实践的时候还是不建议使用的。因为一旦数据量大了,采用递归容易栈溢出。当然我们还有其他遍历的方式。比如说我用栈辅助循环来遍历,比如说我可以将二叉树线索化来遍历都可以。那么今天呢,为了更好的巩固JavaScript面向对象的语法,我就想先序遍历和后序遍历使用栈辅助循环,然后中序遍历我就使用递归。两种遍历的方式都用上,更好巩固语法。
在过去呢,我也曾写过一些数据结构的博客,这里可以列出来分享。
树与二叉树
二叉树遍历的四个应用案例
二叉树层次遍历
栈辅助循环遍历二叉树
数据结构的实现
//二叉树类
function BinaryTree(){
//懒得写get set 就直接把结点放这了
this.root = null;
this.left = null;
this.right = null;
//构造叶子结点
this.getTree = function(root){
var tree = new BinaryTree();
tree.left = null;
tree.right = null;
tree.root = root;
return tree;
}
/**
* 先序遍历
* 这里采用栈辅助循环
* @param {Object} tree
*/
this.preOrder = function(tree){
//定义一个栈
var stack = new Array();
//初始化栈
var top = -1;
var p = new BinaryTree();
//根节点入栈
stack[++top] = tree;
//栈空循环退出,遍历结束
while(top != -1){
//出栈并输出栈顶结点
p = stack[top--];
//使用document输出
document.write(p.root + " ");
//栈是先进后出的,所以先让右孩子进去,再进左孩子
//等下出来的时候.就是左孩子先出来,右孩子后出来
//栈顶结点的右孩子存在,则右孩子入栈
if(p.right != null){
stack[++top] = p.right;
}
//栈顶结点左孩子存在就让左孩子入栈
if(p.left != null){
stack[++top] = p.left;
}
}
}
/**
* 中序遍历
* 这里就采用递归了
* @param {Object} tree
*/
function minOrder(tree) {
if(tree){
if(tree.left){
minOrder(tree.left);
}
document.write(tree.root + " ");
if(tree.right){
minOrder(tree.right);
}
}
}
this.inOrderTraversal = function(tree){
minOrder(tree);
}
/**
* 后序遍历
* 这里则又是采用栈辅助循环
* 具体的原理在(使用自定义的栈优化二叉树的遍历那篇文章有说过)
* @param {Object} tree
*/
this.postOrder = function(tree){
if(tree != null){
//定义两个栈
var stack1 = new Array();
var stack2 = new Array();
var top1 = -1, top2 = -1;
var p = new BinaryTree();
stack1[++top1] = tree;
while(top1 != -1){
p = stack1[top1--];
stack2[++top2] = p;
if(p.left != null){
stack1[++top1] = p.left;
}
if(p.right != null){
stack1[++top1] = p.right;
}
}
while(top2 != -1){
p = stack2[top2--];
document.write(p.root + " ");
}
}
}
}
//main 函数
function main(){
var binary = new BinaryTree();
//规划二叉树
var tree = binary.getTree('A');
tree.left = binary.getTree('B');
tree.right = binary.getTree('C');
tree.left.left = binary.getTree('D');
tree.left.right = binary.getTree('E');
//先序遍历
binary.preOrder(tree);
//换行
document.writeln("<br/>");
//中序遍历
binary.inOrderTraversal(tree);
//换行
document.writeln("<br/>");
//后序遍历
binary.postOrder(tree);
}
main();
Ajax和Json
在今年六月份时候,我曾写过一篇【大话Ajax】的文章。那篇文章主要就是使用Servlet和JSP发送和接收Json格式字符串。当然SpringMVC的Responsebody注解发给后台的也是JSON格式字符串。那今天呢,就再学一遍吧~
XMLHttpRequest对象
XMLHttpRequest 是浏览器接口对象,该对象的 API 可被JavaScript、VBScript 以及其它web 浏览器内嵌的脚本语言调用,通过 HTTP 协议在浏览器和 web 服务器之间收发 XML 或其它数据。XMLHttpRequest 可以与服务器实现异步交互,而无需让整个页面刷新,因此成为Ajax编程的核心对象。
Ajax的使用步骤
创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
给定请求方式以及请求地址
xhr.open("get","http://www.baidu.com");
发送请求
xhr.send();
获取服务器端给客户端的响应数据
xhr.onreadystatechange = function () {
if(xhr.readyState == 4 && xhr.status == 200){
document.getElementById("span").innerHTML = xhr.readyState;
alert(xhr.readyState);
}
}
JSON
语法
Json的语法可以表示三种类型的值
简单值 : 使用JavaScript相同的语法,可以在Json中表示字符串、数值、布尔值和Null。
对象: 对象作为一种复杂数据类型,表示的是一组无序的键值对。而每个键值对的值可以是简单值,也可以是复杂数据类型的值。
数组: 数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值。数值的值也可以是任意类型——简单值,对象或者数组
在 JSON 未出现之前在 Ajax 中对于数据传递方式,会使用 XML 作为主要数据格式来传输数据。直到 JSON 出现后逐渐放弃使用 XML 作为数据传输格式。JSON 比 XML 更小、更快,更易解析。
Josn六种数据类型
string:字符串,必须要用双引号引起来。
number:数值,与JavaScript的number 一致。
object:JavaScript的对象形式,{key:value}表示方式,可嵌套。
array:数组,JavaScript的Array表示方式[value],可嵌套。
true/false:布尔类型,JavaScript 的boolean 类型。
null:空值,JavaScript的null。
使用JSON接收数据的案例
@GetMapping("/test")
@ResponseBody
public User testController(){
return new User("alvin","123456");
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
//请求方式和地址
xhr.open("get","test");
//发送
xhr.send();
xhr.onreadystatechange = function () {
var parse = JSON.parse(xhr.responseText);
alert(parse.username + " " + parse.password);
document.getElementById("data").innerHTML
= parse.username + "<br/>" + parse.password;
}
</script>
</head>
<body>
<span id="data"></span>
</body>
</html>
jQuery
jQuery是JavaScript的一个函数库,对JavaScript进行了一个封装。jQuery将常用的、复杂的操作进行函数化封装,直接调用,大大降低了使用JavaScript的难度,改变了使用JavaScript的习惯。 jQuery能做的JavaScript也能做,但使用jQuery能大幅提高开发效率。
JavaScript中获取元素内容的方式
getElementById( ) :返回一个节点对象。
getElementsByName( ):返回多个(节点数组)。
getElementsByTagName( ) :返回多个(节点数组)
jQuery选择器
基本选择器
标签选择器 $("a")
ID选择器 $("#id") $("p#id")
类选择器 $(".class") $("h2.class")
通配选择器 $("*")
并集选择器$("elem1,elem2,elem3")
后代选择器$(ul li)
父子选择器 $(ul>li)
属性选择器
[attribute] 匹配包含给定属性的元素
[attribute1][attribute2] 复合属性选择器,需要同时满足多个属性
[attribute=value] 匹配给定的属性是某个特定值的元素
[attribute!=value] 匹配所有属性不等于特定值的元素
[attribute^=value] 匹配给定的属性是以某些值开始的元素
[attribute$=value] 匹配给定的属性是以某些值结尾的元素
[attribute*=value] 匹配给定的属性是以包含某些值的元素
位置选择器
针对整个页面而言的位置选择器
first 获取第一个元素
:last 获取最后一个元素
odd 匹配所有索引值为奇数的元素,从 0 开始计数
even匹配所有索引值为偶数的元素,从 0 开始计数
eq(n) 匹配一个给定索引值的元素
gt(n) 匹配所有大于给定索引值的元素
lt(n) 匹配所有小于给定索引值的元素
针对上级标签而言的位置选择器
first-child 匹配第一个子元素
last-child匹配最后一个子元素
only-child如果某个元素是父元素中唯一的子元素,将会被匹配
nth-child(n) :nth-child(odd|even) :nth-child(xn+y) 匹配其父元素下的第N个子或奇偶元素
表单选择器
关于表单项的选择器
text :password :radio :checkbox :hidden :file :submit
input 匹配所有 input, textarea, select 和 button 元素
关于表单项状态的选择器
selected :checked :enabled :disabled
hidden :visible :not
注意$("input")和$(":input")的区别
$("input"):标签选择器,只匹配input标签
$(":input"): 匹配所有 input, textarea, select 和 button 元素
jQuery操作Json案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$.ajax({
type:"get",
url:"/test",
//传递参数
data:"username=alvin&password=12345",
success:function (result) {
$("#username").html(result.username);
$("#password").html(result.password);
}
});
})
</script>
</head>
<body>
<span id="username"></span>
<span id="password"></span>
</body>
</html>
表单验证案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
function checkForm(){
//判断用户名是否符合验证规则
var flag1 = checkUser();
//判断邮箱是否符合验证规则
var flag2 = checkEmail();
//如果均符合验证规则,验证成功,否则验证出错
if(flag1 && flag2){
return true;
}else{
return false;
}
}
function checkUser(){
//清空上次检查的提示信息
//$("#usererror").html("");
$("#usererror").empty();
// 用户名不能为空
var user = $("#user").val();
if(user == ""){
//alert("用户名不能为空");
$("#usererror").html("用户名不能为空");
return false;
}
// 用户名长度大于6
if(user.length <=6){
//alert("用户名长度需要大于6");
$("#usererror").html("用户名长度需要大于6");
return false;
}
// 用户名中不能有数字 ad34adf
for(var i=0;i<user.length;i++){
var ch = user.charAt(i);
if(ch>='0' && ch<='9' ){
//alert("用户名中不能有数字");
$("#usererror").html("用户名中不能有数字");
return false;
}
}
return true;
//return undefined
}
function checkEmail(){
//清空上次验证邮箱的提示信息
$("#emailerror").empty();
var email = $("#email").val();
if(email.indexOf('@')<0){
//alert("邮箱中必须有@");
$("#emailerror").html("邮箱中必须有@");
return false;
}
if(email.indexOf('.')<0){
//alert("邮箱中必须有.");
$("#emailerror").html("邮箱中必须有.");
return false;
}
return true;
}
function operUser(){
$("#user").select();
//$("#user").val("");
}
</script>
</head>
<body>
<table id="center" border="0" cellspacing="0" cellpadding="0">
<form action="doRegister.jsp" method="post" name="myform" onsubmit="return checkForm()" >
<tr>
<td >您的姓名:</td>
<td>
<input id="user" type="text" onfocus="operUser()" onblur="checkUser()"/>
<div id="usererror" style="display: inline;"></div>
</td>
</tr>
<tr>
<td >输入密码:</td>
<td><input id="pwd" name="pwd" type="password"/></td>
</tr>
<tr>
<td >再输入一遍密码:</td>
<td><input id="repwd" type="password"/></td>
</tr>
<tr>
<td >您的Email:</td>
<td>
<input id="email" type="text" onblur="checkEmail()"/>
<span id="emailerror"></span>
</td>
</tr>
<tr>
<td> </td>
<td ><input name="btn" type="submit" value="注册" class="rb1" /></td>
</tr>
</form>
</table>
</body>
</html>
购物车案例
需求:使用jQuery实现对购物车的增删查改全选反选功能。单个选择复选框的时候如果满了,全选框也必须自动勾上。修改数量的时候数量变成文本格式,修改数量按钮自身变成确定按钮。修改的时候要检查数量是否正确。
做这个的目的就和我写数据结构一样,主要是为了顺顺手。因为这些选择器也好还是事件也好都太多了。我不可能一个一个去背,只能说下次要用的时候看看文档可以上手。待会儿也会用到各种选择器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="./js/jquery.min.js"></script>
<script type="text/javascript">
//全选操作
$(function(){
//全选操作
$("#chks").click(function(){
//获取全选框的值,this就相当于是chks。
//prop会根据是否选中返回true和false,也可以在后面修改true和false
var flag = $(this).prop("checked");
//这句话的意思是将所有input name = chk 的值都根据flag改变
//触发chks单机事件勾选了的时候flag是true,没勾选的时候就是false
//所以当全选框是true的时候,下面全改成true。全选是false下面就全改成false就好了
$("input[name=chk]").prop("checked",flag);
});
//为了防止复选框被一个一个点满的时候全选框没有被改变.所以这里要处理一下
//使用了该选择器后,用户每次点击复选框,都会在这里进行判断一下
$("input[name=chk]").click(judgeAll());
//反选操作
$("#fx").click(function(){
//获取所有复选框
$("input[name=chk]").each(function(){
//获取原来的值
var flag = $(this).prop("checked");
//修改相反的值
$(this).prop("checked",!flag);
})
//直接调用就可以了
judgeAll();
});
/**
* 新增
*/
$("#addRow").click(function(){
//创建一个
var newRow = $('<tr>'+
'<td><input type="checkbox" name="chk" id="" value="2"/></td>'+
'<td>《c primer plus》</td>'+
'<td>Stephen Prata</td>'+
'<td>10</td>'+
'<td>'+
'<input type="button" name="aa" id="" value="修改数量" οnclick="updateAmount(this)"/>'+
'<input type="button" name="" id="" value="删除" οnclick="delRow(this)"/>'+
'</td>'+
'</tr>');
//======================================
//这里用到了位置选择器,last是最后一个。如果要放在第一个就用first
$("tr:last").after(newRow);
});
/**
* 多行删除
*/
//这个对应的是横着那一排的删除id。不是单独删除的那个单击事件
$("#delRow").click(function(){
//获取所有被选中的复选框
var toDelArr = $("input[name=chk]:checked");
//先判断是否选择,如果没选就提示
if(toDelArr.length == 0){
alert("至少选中一行");
}else{
//toDelArr.remove();是反面教材,因为刚刚只是获得复选框。直接删自然也只会删掉复选框
//toDelArr.parent().remove();也不行,因为它只会删掉当前的td。要想删掉tr需要两个parent
//toDelArr.parent().parent().remove(); 这种写法虽然可以但是也太麻烦了
//最好的写法还是这种。parents里面一定要写东西。不然整个页面都删掉了。。。
toDelArr.parents("tr").remove();
}
});
/**
* 复制多行
*/
$("#copyRow").click(function(){
//获取所有被选中的复选框
var toCopyArr = $("input[name=chk]:checked");
//先判断是否选择,如果没选就提示
if(toCopyArr.length == 0){
alert("至少选中一行");
}else{
//each是在循环,所以循环里面一个一个加就相当于多行增加
toCopyArr.each(function(){
//复制一份
var cloneRow = $(this).parents("tr").clone();
//粘贴一份
$("#ta").append(cloneRow);
});
}
});
})
/**
* 为了让反选和普通选择都进行判断并且代码不用重复写
* 所以这里就封装成一个函数让它们调用
*/
function judgeAll(){
//获取所有的复选框
var arr = $("input[name=chk]");
//先默认全部选中
var flag = true;
//arr.each就相当于是在循环遍历
arr.each(function(){
//判断所有复选框是否被选中
var flagplus = $(this).prop("checked");
//假如有一个没被选中,那么全选框就是false
if(flagplus == false){
flag = false;
return;
}
});
//决定全选框的值
$("input[name=chks]").prop("checked",flag);
}
/**
* 修改当前数量
*/
function updateAmount(obj){
//数量变成文本框的值,文本框变成数量的值
//获取原来的数量 prev是指修改数量的前面一个表格。不然就会把自己变成下面input的格式
//如果要把input格式换成作者那个位置,可以用两个prev()试试
var amountCell = $(obj).parent().prev();
var amount = amountCell.html();
//将指定位置的td改成input文本格式
amountCell.html('<input type="text" value = "'+ amount +'" οnblur="checkAmount(this)"/>');
//把修改按钮变成确定按钮
//获得当前按钮单元格
var buttonCell = $(obj).parent();
//准备新按钮
var newButton = $('<input type="button" name="" id="" value="确定" οnclick="confirmAmount(this)"/>'+
'<input type="button" name="" id="" value="删除" οnclick="delRow(this)" />');
//添加新按钮
buttonCell.html(newButton);
}
/**
* 确定数量
* @param {Object} obj
*/
function confirmAmount(obj){
//文本框变成数量
//获取原来的数量
var amountInput = $(obj).parent().prev().find("input");
var amount = amountInput.val();
//修改文本框的数量
$(obj).parent().prev().html(amount);
//确定按钮变成修改按钮
//获得当前按钮单元格
var buttonCell = $(obj).parent();
//准备新按钮
var newButton = $('<input type="button" name="" id="" value="修改数量" οnclick="updateAmount(this)"/>'+
'<input type="button" name="" id="" value="删除" οnclick="delRow(this)" />');
//添加新按钮
buttonCell.html(newButton);
}
//判断数量是否正确
function checkAmount(obj){
//获取值
var amount = $(obj).val();
//判断是否正确
if(isNaN(amount) || amount < 1 || parseInt(amount) != amount){
alert("必须是大于0的整数!");
}
}
/**
* 删除当前行
*/
function delRow(obj){
//这里就是一句话解决了。。。
$(obj).parents("tr").remove();
}
</script>
</head>
<body>
<h3>购物车</h3>
<hr />
<input type="button" id="fx" value="反选" />
<input type="button" id="addRow" value="新增一行" />
<input type="button" id="delRow" value="删除行"/>
<input type="button" id="copyRow" value="复制行" />
<table border="1px" cellpadding="10px" cellspacing="0" id="ta">
<tr>
<td width="50px"><input type="checkbox" name="chks" id="chks" value="1" /></td>
<td width="200px">书名</td>
<td width="200px">作者</td>
<td width="200px">数量</td>
<td width="200px">操作</td>
</tr>
<tr>
<td><input type="checkbox" name="chk" id="" value="2"/></td>
<td>《计算机组成原理》</td>
<td>Alan Clements</td>
<td>10</td>
<td>
<input type="button" name="aa" id="" value="修改数量" onclick="updateAmount(this)"/>
<input type="button" name="" id="" value="删除" onclick="delRow(this)"/>
</td>
</tr>
<tr>
<td><input type="checkbox" name="chk" id="" value="3" /></td>
<td>《深入理解计算机系统》</td>
<td>布赖恩特</td>
<td>10</td>
<td>
<input type="button" name="" id="" value="修改数量" onclick="updateAmount(this)"/>
<input type="button" name="" id="" value="删除" onclick="delRow(this)" />
</td>
</tr>
<tr>
<td><input type="checkbox" name="chk" id="" value="4" /></td>
<td>《编译原理》</td>
<td>Alfred V.Aho</td>
<td>30</td>
<td>
<input type="button" name="" id="" value="修改数量"οnclick="updateAmount(this)"/>
<input type="button" name="" id="" value="删除" onclick="delRow(this)"/>
</td>
</tr>
</table>
</body>
</html>
错误处理和调试
由于JavaScript本身是动态语言,而且这么多年来也没有一个固定的开发工具。事实上,你就是新建一个记事本,也可以写JavaScript代码然后放浏览器上运行。不同的浏览器自然对JavaScript的编译支持等都不太相同。今天就来学习一下前端的调试问题。至于try catch的话,明天写代码的时候再用两遍就熟了吧~
现在我就随便打开一个SpringBoot的项目去运行。然后按F12打开浏览器的控制台,这里是用谷歌浏览器。其实学Web开发是比较建议用谷歌或者火狐的。按F12之后进入调试页面就会看到很多选项
Elements(元素)
这个页面显示的都是后台html代码,如果想要定位到某个位置可以右键检查,就自然跳过来了。
Console(控制台)
这个界面会显示控制台的信息,比如代码报错了...或者console.log()等可以把内容输出到这里。就跟平时写Java代码IDEA或者eclipse下面的控制台差不多。
Sources(资料来源)
点击它可以看到后台代码的文件信息
Network
Network可以查看当前url的请求内容,请求状态等信息,还可以分析网络状态
工具打开之后,点击network,就可以查看当前网络录制情况,默认是开启网络录制的,查看图中圈中的部分,判断是否开启了网络录制,红色代表正在录制,点击之后关闭,变为灰色,那就是停止录制
选择XHR更是可以直接找到后台接口甚至查看Json。Preview就可以看到Json
好了,今天差不多先学到这。明天是计划先用HTML+CSS+JavaScript做个纯底层的案例。接着再学习bootstrap和vue。好好加油!
Day4
前言
今天是国庆假期的第五天了,同时也是我学习JavaScript的第四天。经过了前面三天的学习,基本的概念也都过了一遍,是时候该做项目了。其实我之所以会选择国庆期间学前端,是因为我打算国庆之后开始来做一个电商项目。这个电商项目会很大,我应该是会采用分布式,主要目的不是为了上线也不是为了赚钱。而是单单纯纯的想全栈的做一次,提高技术水平。所以我必须先把前端学好。今天的学习打算呢,我是计划先用最原始的HTML,CSS,JavaScript来做一个页面好看点的项目,当然实际功能可能还是和昨天的购物车差不多。接着呢,我今天还要学习bootstrap和vue两大前端框架。不过我更多的还是会学习bootstrap,因为我是计划在我的项目中去使用它。
第四天的学习内容
单链表的翻转(面向对象语法复习)
CSS样式
购物车(图形版)
bootstrap框架
Vue框架
登录框(bootstrap实现)
单链表的翻转
前天呢,学习第二天的时候我说过为了巩固面向对象的语法,所以是决定每天写一遍数据结构的。不过从明天开始就正式进入项目阶段了也就没必要写了。今天就写个单链表的翻转,然后写下购物车,当然这次的购物车要比昨天的购物车多了一些图片素材,主要目的还是为了巩固。
我们都知道栈数据结构是先进后出的,所以其实你要翻转单链表特别简单。只需要把数据放到栈里面再吐出来就可以了~没什么难度。但是呢,我前天写单链表的那种写法遍历出来和添加的顺序都是反的。所以应对这种情况使用栈反而无法翻转,因为翻转后的数据再经历一次翻转就又相当于是还原了。所以这种情况下如果我要达到翻转效果,可以使用队列。队列是先进先出的,把本来就已经翻转的数据重新插入再遍历可以达到效果。
在这里我要声明一下,正常情况下都是使用栈来达到翻转效果。但是我这种情况使用队列会更好一些。
关于栈和链表的数据结构理论的话我过去也写过博客。这里就列出来分享一下。
栈和队列的基本概念
顺序栈和链表栈
顺序队列和链表队列
代码实现
/**
* 链表类
*/
function LinkList(){
//结点类
function Node(data){
this.data = data;
this.next = null;
}
//头节点
var head = new Node(null);
//插入元素
this.add = function(data){
var temp = new Node(data);
temp.next = head.next;
head.next = temp;
};
//遍历元素
this.print = function(){
var temp = head.next;
while(temp != null){
document.write(temp.data + " ");
temp = temp.next;
}
};
//翻转
this.rev = function(){
var temp = head.next;
//定义一个队列
var queue = new Array();
//把链表元素存入队列内
while(temp != null){
queue.push(temp.data);
temp = temp.next;
}
//将 head 置空 然后重新添加
head = new Node(null);
//把队列的结点吐出来
while(queue.length > 0){
//刚刚push是从后往前添加,所以现在shift是
//从前往后吐出来。因此达到先进先出的效果
this.add(queue.shift());
}
};
}
//main 函数
function main(){
var list = new LinkList();
//添加元素
for(var i = 0; i < 10; i++){
list.add(i);
}
//打印原链表
list.print();
document.write("<br/>");
//翻转链表
list.rev();
//打印翻转后的
list.print();
}
main();
翻转
购物车
刚才把链表翻转了一下,主要目的不是锻炼数据结构,而是巩固JavaScript编程语法。如果要学习数据结构,个人是建议使用C语言或者C++语言来实现会更好一些。因为C/C++语言比较接近底层,特别是C语言。
购物车呢,昨天使用jQuery已经实现过一遍了,那么今天我就打算使用JavaScript来实现一遍。当然,这一次我会尽量把网页做的好看一点,当然实际的功能和昨天还是差不多。更多的还是为了巩固。做完购物车之后就要开始学习bootstrap和vue了。
购物车的页面
这个购物车的页面我是对京东购物车的一个模仿。当然我也只是拿来学习用的,并不是拿去商业用途。还望别介意哈。
这个页面呢是使用纯HTML+CSS画的。然后JavaScript是用来干什么的呢?需求如下:
功能需求:
1: 全选功能:而且点击复选框也会自动勾选全选框。不能有BUG
2: 计算功能:通过商品数量的增加旁边的价格也跟着增加
3: 删除功能:删除购物车中的商品
4: 结算功能:算出最后应该付款的价格
这个项目在JavaScript上的需求比昨天的都要简单,主要练习的方向是HTML和CSS。因为等下学框架的时候,比如说bootstrap框架它都是把这些底层封装好的。所以在学习框架之前先赶紧用一遍底层。
如果想到了一个需求的解决方法,但是又不知道用什么标签或者属性。那么《菜鸟教程》或者《w3school》这两个网站可以帮助自己。也可以在额外创建一个专门做实验的html文件。可以临时试试它的效果如何。
还有一件事就是,不管是HTML、CSS还是JavaScript。又或者其他语言,比如说Java,Python等。永远都不要花心思去记那些工具,方法什么的。只要知道有这个东西,然后它底层是怎么一回事就好了。知道原理写代码的时候看API能够看得懂就好了,因为人不可能全都记得住。有这个时间,还不如多去钻研一些逻辑思维,或者数据结构与算法。RBAC,设计模式什么的。当然学习底层个人觉得比较好的方法可以先学点C/C++语言。因为C语言是底层。就比如说垃圾回收机制,如果学过C语言的人他就能很快听得懂,学过C++就知道析构函数这种东西。个人观点,不喜勿喷,当然如果有大神的话,请求指点。因为本人是个菜鸟。哈哈^ ^。
在这里呢,使用两个文件来写。一个文件专门写CSS,另一个则是HTML+JavaScript。文件名字我也懒得取了,直接new_file省事。
代码实现
CSS全局设置
这些都是比较常用的格式,主要是为了美观。我自己也是在网上搜索的。甚至说接下来的页面,我也会边看手册边写,就像看字典一样。因为我实话实说我真的没法记住它们。但是看手册的话,还是可以拼出来的。
/*清除所有格式*/
body,div,h1,h2,h3,h4,h5,h6,li,ol,ul{
margin: 0px; padding: 0px;}
/*整个文本默认居中*/
body{
text-align: center;font-size:14px;}
/*所有a标签去掉下划线*/
a{
text-decoration: none;}
/*li的点去掉*/
li{
list-style: none;}
如何使用CSS定位HTML标签的位置来设置格式?
<!-- 这里先写好class,等下到了CSS文件里,就可以根据这个class
找到该标签的位置,然后设置格式
-->
<div class="nav">
</div>
/*这里面的navigation,是根据前台html标签里面的class找到的*/
.nav{
height: 30px;
/*#f1f1f1是颜色,具体的对应可以查百度*/
background-color: #f1f1f1;
}
基本的事项刚刚也说完了,现在直接放代码了。由于HTML和CSS代码比较多,而且也都是拼出来的没什么逻辑性,所以CSS就不放笔记里来了,HTML我也删减一部分,只保留绑定了事件的标签。笔记尽量记一些有逻辑性的东西。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>购物车</title>
<link rel="stylesheet" type="text/css" href="css/shop.css"/>
<script type="text/javascript">
//获得所有多选框的对象
var all = document.getElementsByName("select");
/**
* 全选操作,点击这个按钮其他的都会自动全选
* 但是这里不能使单选来决定是否全选
* 我们还需要另一个函数
* @param {Object} obj
*/
function isSelectAll(obj){
var flag = obj.checked;
for(i in all){
all[i].checked = flag;
}
}
/**
* 单选框决定全选框
* @param {Object} obj
*/
function isSelectAllPlus(obj){
//默认全选
var flag = true;
/**
* 之所以这样循环,是因为第一个和最后一个按钮都不是商品的按钮
* 而是全选的按钮,所以这里就避过了第一个和最后一个两个按钮
*/
for(var i = 1; i < all.length - 1; i++){
//如果有一个没选那就不是全选
if(!all[i].checked){
flag = false;
//也没必要继续循环判断了
break;
}
}
//改变第一个和最后一个框
all[0].checked = flag;
all[all.length - 1].checked = flag;
}
/**
* 控制增加减少
* @param {Object} obj
* @param {Object} sigle
*/
function checkAdd(obj,sigle){
var pre;
if(sigle == "1"){
//获得下一个结点
pre = obj.nextElementSibling;
//如果数量大于0
if(Number(pre.value) > 0){
//获得节点的value值
pre.value=Number(pre.value)-1;
}
}else{
//获得上一个结点对象
pre = obj.previousElementSibling;
//获得结点value的值
pre.value = Number(pre.value) + 1;
}
//计算每一个商品的价格
//获得每一个商品的单价
var val=pre.parentNode.previousElementSibling.innerHTML;
//计算总的价格
var num =Number(val)*Number(pre.value);
//把总的价格赋值给指定的对象
pre.parentNode.nextElementSibling.innerHTML="¥"+num;
}
/**
* 删除结点
*/
function deleteByThis(obj){
//获得父节点的div 这么多parent的原因昨天体验过
var divNode = obj.parentNode.parentNode.parentNode;
divNode.remove();
}
/**
* 结算最后的价格
*/
function countMoney(){
//统计商品的总价格
var count = 0;
//统计是否有勾选的对象
var checkedNum = 0;
//统计商品的数量
var number = 0;
//循环遍历
for(var i = 0; i <all.length; i++){
//如果选中才会进入计算
if(all[i].checked){
//商品的数量
checkedNum++;
//获得ul父结点
var par = all[i].parentNode.parentNode;
//获得指定ul下面的所有的li
var li= par.getElementsByTagName("li");
//单个商品的总价格
var money=li[6].innerText.split("¥")[1];
//获得所有商品的总价格
count += Number(money);
document.getElementById("countMoney").innerText=count;
//获得商品的数量
var shopCount=li[5].getElementsByTagName("input");
var num=shopCount[0].value;
number+=Number(num);
//获得商品数量统计的对象
document.getElementById("snum").innerText=number;
}
}
//如果没有勾选自然就都是0
if(checkedNum==0){
document.getElementById("countMoney").innerText=0;
document.getElementById("snum").innerText=0;
}
}
</script>
</head>
<body>
<!--显示菜单的结束-->
<!--商品详情展示开始-->
<div class="info warp">
<ul>
<li class="info_1"><input type="checkbox" name="select" onclick="isSelectAllPlus(),countMoney()"/> </li>
<li class="info_2"> <img src="img/img1.jpg" width="80px"/> </li>
<li class="info_3"><a>刀锋之影</a></li>
<li class="info_4"><a>经典皮肤</a> </li>
<li class="info_5">6300</li>
<li class="info_6">
<button onclick="checkAdd(this,1),isSelectAllPlus(),countMoney()">-</button>
<input type="text" name="" id="" value="1" />
<button class="bot" onclick="checkAdd(this,2),isSelectAllPlus(),countMoney()">+</button>
</li>
<li class="info_7">¥6300</li>
<li>
<a href="javascript:viod(0)" onclick="deleteByThis(this),countMoney()">删除</a><br />
<a>已到我的关注</a>
</li>
</ul>
</div>
<div class="info warp">
<ul>
<li class="info_1"><input type="checkbox" name="select" onclick="isSelectAllPlus(),countMoney()"/> </li>
<li class="info_2"> <img src="img/img1.jpg" width="80px"/> </li>
<li class="info_3"><a>刀锋之影</a></li>
<li class="info_4"><a>经典皮肤</a> </li>
<li class="info_5">6300</li>
<li class="info_6">
<button onclick="checkAdd(this,1),isSelectAllPlus(),countMoney()">-</button>
<input type="text" name="" id="" value="1" />
<button class="bot" onclick="checkAdd(this,2),isSelectAllPlus(),countMoney()">+</button>
</li>
<li class="info_7">¥6300</li>
<li>
<a href="javascript:viod(0)" onclick="deleteByThis(this),countMoney()">删除</a><br />
<a>已到我的关注</a>
</li>
</ul>
</div>
<div class="info warp">
<ul>
<li class="info_1"><input type="checkbox" name="select" onclick="isSelectAllPlus(),countMoney()"/> </li>
<li class="info_2"> <img src="img/img1.jpg" width="80px"/> </li>
<li class="info_3"><a>刀锋之影</a></li>
<li class="info_4"><a>经典皮肤</a> </li>
<li class="info_5">6300</li>
<li class="info_6">
<button onclick="checkAdd(this,1),isSelectAllPlus(),countMoney()">-</button>
<input type="text" name="" id="" value="1" />
<button class="bot" onclick="checkAdd(this,2),isSelectAllPlus(),countMoney()">+</button>
</li>
<li class="info_7">¥6300</li>
<li>
<a href="javascript:viod(0)" onclick="deleteByThis(this),countMoney()">删除</a><br />
<a>已到我的关注</a>
</li>
</ul>
</div>
<!--商品详情展示结束-->
<!--结算开始-->
<div class="balance warp">
<ul class="balance_ul1">
<li>
<input type="checkbox" name="select" id="" value="" onclick="isSelectAll(this),isSelectAllPlus(this),countMoney()"/>
全选
</li>
<li><a>删除选中商品</a></li>
<li><a>移到我的关注</a></li>
<li><a>清除下柜商品</a></li>
</ul>
<ul class="balance_ul2">
<li>已经选择<span id="snum">0</span>件商品</li>
<li>总价 <span id="countMoney">¥0</span></li>
<li>
<button class="butt">去结算</button>
</li>
</ul>
</div>
<!--结算结束-->
</body>
</html>
Vue框架
Vue这个框架一般多用于前后端分离的项目,就像我上班的时候前端很多都是用Vue框架。前后端分离的好处就是可以让我们后端程序员只关心后端的代码,不用去管前端。还有就是开发的时候前端和后端各顾各的,不用谁先等谁写完。后端程序员用Responsebody发个Json给前端就没啥事了。其他的页面效果都让他们写。。。我也是因为长期这样,所以前端学的特别差。不过呢,前面我也说了我是打算自己全栈的来做一次分布式电商项目,我自己的电商项目可能还是会使用bootstrap框架,个人也更喜欢那个。
学习
学习框架这一块呢,有时间可以买本书系统的学。也可以去vue官网看教程和API。真正系统的学习Vue内容还是很丰富的。我这里之所以一天学两个框架,是因为一方面我从事的是后端开发,并不是靠前端吃饭,我也想国庆以后再慢慢深入,二方面是这个东西我个人认为,还是多在项目中实践才不容易忘。不然长期不用也还是会忘记的。就像我们用惯了键盘打字以后,就很容易提笔忘字一个道理。
实现前后端分离的常用前端框架。
Vue框架用的很多,但并不是唯一。其他的前后端分离框架也有,最常用的有三款。
Vue.js 小巧,灵活,功能却很强大。在市场上占有率更高,属于成熟稳定的框架。
React相比Vue.js更新一些,近几年有追赶Vue.js的架势。更适合做移动项目。
AngularJS相比Vue更加大量一些。只有在一些大型项目中才可能被使用。
安装
安装直接运行安装软件就可以了。然后输入CMD进入命令行,输入node-v和npm-v看见版本号就知道是否安装成功。然后下面的命令也都是在CMD命令行里面使用
安装淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装webpack
cnpm install -g webpack webpack-cli
安装 Vue Cli
cnpm install -g @vue/cli
安装Vue.js插件(我这里是用IDEA)。创建项目的时候名字最好不要大写
template和script交互
<template>
<div id="app">
<div>
我是{
{name}},我的上司是{
{king}}
我是{
{person.name}} 今年 {
{person.age}} 岁
</div>
</div>
</template>
<script>
// export是一个数据对象,我们可以写多个属性或者函数
export default {
data(){
return{
name:"诸葛亮",
king:"刘禅",
person:{
name:"小明",
age : 16
}
}
}
}
</script>
条件判断加单机事件
<!-- template -->
<div>
我是{
{person.name}} 今年 {
{person.age}} 岁
<!-- 单击事件,直接写动作,然后用 v-on: 绑定 -->
<input type="button" v-on:click="person.age = person.age + 1" value="年龄 + 1"/>
<!-- 也可以在下面定义一个函数(也可以叫方法)拿来调用,绑定的话也可以用@来作为v-on的简写 -->
<input type="button" @click="AddAge" value="年龄-1"/>
<!-- if判断 -->
<span v-if="person.age<18">未成年</span>
<span v-else-if="person.age >= 18 && person.age < 35">青年</span>
<span v-else-if="person.age >= 35 && person.age < 50">壮年</span>
<span v-else-if="person.age >= 50 && person.age < 60">中年</span>
<span v-else>老年</span>
</div>
<!-- script : export default -->
methods:{
//定义当前组件中可以使用的所有函数
AddAge:function () {
this.person.age = this.person.age - 1;
}
}
循环语句
<!-- template -->
<div>
<!--
v-bind:key 绑定一个变量,相当于定义一个临时变量
v-for="变量 in 集合" 变量是使用某已有变量,不能定义新变量。
-->
学校学院分别有
<ul>
<li v-for="My in MyClass" v-bind:key="My">
学院{
{My.name}} 班级数 {
{My.number}}
</li>
</ul>
</div>
<!-- script : export default -->
//在return返回下面再定义一个数组,我们等下用循环来遍历
MyClass:[
{"name":"信息工程系","number":8},
{"name":"机电工程系","number":6},
{"name":"经济管理系","number":7}
]
Html支持
如果希望能够解析HTML,必须使用v-html指令。v-html是任意HTML标签的属性,v-html的取值可以是Model中定义的字段。
<!-- template -->
<span v-html="MyJava"></span>
<!-- script data() return~ -->
MyJava:"我爱<b>Java</b>编程"
组件
组件:如果项目中多次用到类似效果,就可以把这个效果进行自定义组件。新建项目后默认存在HelloWorld.vue就是一个组件。组件文件必须导入才能使用。其中Helloworld为自定义名称,通过这个名称就可以调用对应组件。如果import时直接写组件名(大小写相同)IDEA会提升生成组件的路径,所以一般习惯上都是把名称定义为组件文件名。components: 组件文件只import是不能被使用的。必须在components中注册组件,注册后在中就可以通过组件名直接引用组件了。在中组件以标签形式存在,标签名为组件名。其中msg是在Helloworld中定义的props参数,表示需要传递给组件的数据。
在src下面的components目录新建一个文件,名字随便取
<template>
<div>
<div>这是一个组件</div>
<!-- 获取组件传递的参数名称和类型 -->
<div>{
{MyLove}}</div>
</div>
</template>
<script>
export default {
//我的组件名
name: "MyComponents",
//props:定义组件传递的参数名称和类型
props:{
MyLove:String
}
}
</script>
<style scoped>
</style>
现在回到刚刚那个地方
<template>
<div id="app">
<div>
<MyComponents MyLove="Java"/>
</div>
</div>
</template>
<script>
//导入,不导入会报错
import MyComponents from "@/components/MyComponents";
// export是一个数据对象,我们可以写多个属性或者函数
export default {
components:{
MyComponents
},
</script>
bootstrap框架
bootstrap框架也是我比较喜欢的一个框架。经过了四天的学习,明天第五天是要开始做项目了。虽然今天和昨天也做了项目,但那都是基于底层的。如果是要做比较大的项目会很费劲。就像我刚刚的那个购物车,仅仅只是一个页面,我光CSS代码就写了三百多行,这样一来效率是很低的,后天就差不多可以开始为电商做准备了。
bootstrap的官网也好还是菜鸟教程都有文档和API,官方博客等都可以看一看。如果没有能力盲写代码的话,其实看着API写代码也并没有什么不好。事实上我每次写前端代码都是看着API写的,就像JavaScript那么多事件和方法,HTML那么多标签,我也很难做到全都记住。就把它们当成字典就好了,逻辑思维其实才是更重要的。这也是为什么很多地方都喜欢面试问算法的原因。
栅格系统
Bootstrap包含了一个响应式的、移动设备优先的、不固定的网格系统,可以随着设备或视口大小的增加而适当地扩展到12列。它包含了用于简单的布局选项的预定义类,也包含了用于生成更多语义布局的功能强大的混合类。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
<link rel="stylesheet" href="../css/bootstrap.css"/>
<script type="text/javascript" src="../js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="../js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<div class="row" >
<div class="col-xs-6 col-sm-3"
style="background-color: #dedef8;
box-shadow: inset 1px -1px 1px #444, inset -1px 1px 1px #444;">
<p>我热爱数据结构与算法分析</p>
</div>
<div class="col-xs-6 col-sm-3"
style="background-color: #dedef8;box-shadow:
inset 1px -1px 1px #444, inset -1px 1px 1px #444;">
<p>
bootstrap是一个非常流行的框架
</p>
<p>
C语言是一门面向过程的编程语言
</p>
</div>
<div class="clearfix visible-xs"></div>
<div class="col-xs-6 col-sm-3"
style="background-color: #dedef8;
box-shadow:inset 1px -1px 1px #444, inset -1px 1px 1px #444;">
<p>
C++是一个面向对象的编程语言
</p>
</div>
<div class="col-xs-6 col-sm-3"
style="background-color: #dedef8;box-shadow:
inset 1px -1px 1px #444, inset -1px 1px 1px #444;">
<p>
分布式
</p>
</div>
</div>
</div>
</body>
</html>
查看源码
平时呢,写Java代码的时候总会遇到各种各样的类,各种各样的框架。所以,要了解一个没见过的框架最快速的方法就是看源码。看源码,不仅方便学习框架,也方便学习里面的算法。同样的道理放到JavaScript里面,也是行得通的。
在刚刚写购物车的时候,临时学了下CSS。其实我过去很少接触这玩意儿...因为后端学习HTML和JavaScript里面的Ajax和Json就已经足够了。jstl和thymeleaf等技术都有它们自己独特的语法。不过,现在我知道CSS文件对应着HTML页面的class。所以更换样式的话也可以根据CSS文件里面的样式,把class的名字改成框架里面CSS的名字就可以了~
比如我可以把刚才的栅格系统换一个样式,其实也很简单。直接打开bootstrap的源码就可以了。搜索我刚刚使用的col-lg-6,找到它,我可以换成一个和它同类的样式,看看变化。
当我把所有的col-lg-6换成10以后,样式就变成了这个样式。其实只要肯看源码,学习起来还是特别迅速的。虽然我不怎么学前端,但是把学习Java的这个概念移植过来。道理也还是那个道理。
BootStrap组件
在bootstrap官网里面有很多很多的组件源码参考。要用的时候可以直接拿过来,或者拿过来再修改一点点
Bootstrap按钮
<button type="button" class="btn btn-primary">主要</button>
<button type="button" class="btn btn-secondary">副手</button>
<button type="button" class="btn btn-success">成功</button>
<button type="button" class="btn btn-danger">危险</button>
<button type="button" class="btn btn-warning">警告</button>
<button type="button" class="btn btn-info">信息</button>
<button type="button" class="btn btn-light">明亮</button>
<button type="button" class="btn btn-dark">黑暗</button>
<button type="button" class="btn btn-link">链接</button>
按钮组
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn btn-secondary">左边</button>
<button type="button" class="btn btn-secondary">中间</button>
<button type="button" class="btn btn-secondary">右边</button>
</div>
小弹窗(英文翻译是卡片...我感觉不太对劲所以就理解成小弹窗)
<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">一些快速的示例文本可在卡标题上构建,并构成卡内容的大部分。</p>
<a href="#" class="btn btn-primary">跳转</a>
</div>
</div>
轮播
<div id="carouselExampleSlidesOnly" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="../img/tree.png" class="d-block w-100" alt="..." height="200">
</div>
<div class="carousel-item">
<img src="../img/wather.png" class="d-block w-100" alt="..." height="200">
</div>
<div class="carousel-item">
<img src="../img/montain.png" class="d-block w-100" alt="..." height="200">
</div>
</div>
</div>
其实还有好多好多东西,我就不一 一再CSDN上面试了。其实这个框架最主要还是要学会前后端交互。不过前后端交互可能就要等到写项目的时候了。因为平时上班我也只是发个Json给前端就不管不问了,这次全栈的来写一个大项目,还是要多多学习的。今天就用Bootstrap随便写一个登陆页面和后台管理就结束了吧。
使用BootStrap实现一个登录框
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
<link rel="stylesheet" href="../css/bootstrap.css"/>
<script type="text/javascript" src="../js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="../js/bootstrap.js"></script>
</head>
<body background="../img/tree.png"; style=" background-repeat:no-repeat ;background-size:100% 100%; background-attachment: fixed;">
<div class="modal-dialog" style="margin-top: 10%;">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title text-center" id="myModalLabel">登录</h4>
</div>
<div class="modal-body" id = "model-body">
<div class="form-group">
<input type="text" class="form-control"placeholder="用户名" autocomplete="off">
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="密码" autocomplete="off">
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<button type="button" class="btn btn-primary form-control">登录</button>
</div>
<div class="form-group">
<button type="button" class="btn btn-default form-control">注册</button>
</div>
</div>
</div>
</div>
</body>
</html>
刚刚在网上随便找了张图片做背景。今天先学到这里。明天还是老规矩,先用JavaScript实现一个数据结构,巩固语法的记忆。然后就来一个SpringBoot和Bootstrap联合的小项目。国庆七天!绝不颓废!
转载:https://blog.csdn.net/qq_41424688/article/details/108891135