Javascript == Java == C++
HTML
HTML主要头结构
<html lang="zh-CN">//设置语言
<head>
<meta charset="utf-8">//设置编码
<title>我的测试站点</title>//设置标题
<meta name="description" content="The MDN Web Docs site
provides information about Open Web technologies
including HTML, CSS, and APIs for both Web sites and
progressive web apps.">//meta的name-content形成了键值对,某些自动化程序对其有特殊的意义,description用于搜索引擎显示结果时下面的描述
<link rel="stylesheet" href="my-css-file.css">//加载CSS样式表
<script src="my-js-file.js"></script>//加载Javascript
</head>
<body>
....
</body>
</html>
元数据协议——Open Graph Data
文本标签
<p></p>//段落
<h1></h1><h2></h2><h3></h3><h4></h4>....<h6></h6>//各级标题
<span></span>//行内通用标签
<div id="someId" class="someClass"></div>//块通用标签
<ul><li>L1</li><li>L2</li><li>L3</li></ul>//无序列表 unorderd list and list item
<ol><li>L1</li><li>L2</li><li>L3</li></ol>//有序列表 orderd list and list item
<em></em><strong></strong>//强调和非常强调(斜体和加粗)
<abbr title="some hint"></abbr>//提示
<time datetime="2016-01-20">2016年1月20日</time>//显示时间
<time datetime="2016-01-20T19:30+01:00">7.30pm, 20 January 2016 is 8.30pm in France</time>
id
属性全文档唯一,class
可以不唯一。
在URL最后添加#id
,浏览器会在页面加载完成后跳转到标记了id
的元素所在的位置。
多媒体标签
<a href="https://www.baidu.com" title="百度一下你就不知道">balabala</a>//链接以及提示
<img src="...">//最简单的图像
<figure>
<img src="..."
alt="some hint"
width="width"
height="height">
<figcaption>曼彻斯特大学博物馆展出的一只霸王龙的化石</figcaption>
//宽和高会在CSS加载前应用
</figure>//带注释的图像
<video controls autoplay loop muted poster="poster.png">//使用浏览器自带控制,自动播放,循环播放,静音,封面
<source src="rabbit320.mp4" type="video/mp4">//如果不支持会fallthrough
<source src="rabbit320.webm" type="video/webm">
<p>你的浏览器不支持 HTML5 视频。可点击<a href="rabbit320.mp4">此链接</a>观看</p>
</video>
<audio controls>//同上
<source src="viper.mp3" type="audio/mp3">
<source src="viper.ogg" type="audio/ogg">
<p>你的浏览器不支持 HTML5 音频,可点击<a href="viper.mp3">此链接</a>收听。</p>
</audio>
表格标签
<table>
<caption>表格标题</caption>
<tr>//table row
<td> </td>//table data
<th scope="col">Knocky</th>/table header
<th scope="col">Flor</th>
<th scope="col" colspan="2">Ella</th>//横跨2个列 单元格
</tr>
<tr>
<th scope="row">Breed</th>
<td>Jack Russell</td>
<td>Poodle</td>
<td>Streetdog</td>
<td>Cocker Spaniel</td>
</tr>
<tr>
<th scope="row">Age</th>
<td>16</td>
<td>9</td>
<td>10</td>
<td>5</td>
</tr>
</table>
表单标签
<buttom></buttom>
<input type="checkbox"></input>
<textarea></textarea>
<input type="file" id="avatar" accept="image/png, image/jpeg">
CSS
HTML和CSS的联系
HTML只涉及到文本图片逻辑等元素的树状逻辑表示,即HTML只是一个结构化的文本,最终会形成一个DOM树,和JSON、YAML这些结构化文本格式并无不同。
CSS怎么计算的
一个元素的样式属性是这样计算的
-
计算各个选择器的优先级,优先级高的选择器描述的属性覆盖掉优先级低的选择器的属性
-
选择器的优先级由一个四元组组成
(x,y,z,w)
-
如果是在HTML内
style
声明的属性,令x=1
否则x=0
-
y
为选择器中id选择器的数量 -
z
为选择器中类选择器、属性选择器或者伪类的数量 -
w
为元素、伪元素选择器的数量
-
-
通用选择器 (
*
),组合符 (+
,>
,~
, ' '),和否定伪类 (:not
) 不会影响优先级。
-
-
在DOM树上的父亲应用继承,所有含有
inherit
的属性顺延父亲的属性,如果父亲该属性也是inherit
继续顺延。
盒子模型
一个盒子由margin
-border
-padding
-(子级内容)
组成。不同元素的margin
可重合复用区域。
每个元素均有height
和width
属性,默认为子级内容的大小,设置box-sizing:border-box
即可认为是border+padding+子级内容
的大小。
display:box
在上一个元素下换行;display:inline-box
不换行,文本将对齐到上一个元素的水平位置。
每一个元素还有几种定位方式
position:static
(默认定位),position:fixed
(相对浏览器固定,浮动在static上),position:relative
相对static
>
当内容溢出盒子时,可以设置overflow
设置溢出时行为。
弹性盒子模型
弹性盒子的所有亲儿子就会变为flex元素,flex元素具有以下行为。
- 元素按
flex-direction
排列(主轴) flex-basis
属性为auto
。(auto
遵从盒模型的width
,height
属性,content
遵从内容)flex-grow
属性为0flex-shrink
属性为1flex-wrap
属性为nowrap
。(单行显示)
flex元素确定大小首先考虑flex-basis
,如果其总和超过弹性盒子的大小,将超过空间以flex-shrink
按比例缩小至各个flex元素。如果少于,则将剩余空间以flex-grow
按比例扩大给各个flex元素。
文本显示
字体
@font-face {
font-family: "Open Sans";
src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),
url("/fonts/OpenSans-Regular-webfont.woff") format("woff");
}
xxxx {
font-family: "Open Sans"
}
大小font-size
CSS选择器
通配符选择器*
HTML选择器
HTML标签选择器tagname
类选择器.classname
ID选择器#id
标签属性选择器someselector[attrname]
orsomeselector[attrname=attrvalue]
伪类&伪元素
伪类用于表示元素的特殊状态,伪元素表示特定的元素。
常用伪类:hover
:visited
:checked
:focous
:activate
常用伪元素::after
::before
选择器计算
后代选择器(所有的孩子)selector1 selector2
子代选择器(第一个亲子代)selector1 > selector2
通用兄弟(同一个父亲,之后的所有兄弟)选择器selector1 ~ selector2
相邻兄弟(同一个父亲,第一个兄弟)选择器selector1 + selector2
选择器操作符可以连着写,selector1 selector2 selector3
将倒着应用:
选择这样的
selector3
selector1
*
selector2
*
slector3
CSS属性函数
CSS用函数表示类型以及进行计算
rgb(255,255,255)
url("http://")
用于表示url
calc(1px + 1cm)
加减乘除
其他常见数学函数
blur()
,brightness()
用于filter,对一个元素应用修改器。
Javascript
类型
基本类型
有7种基本类型:String,Number,Bigint,Boolean,undefined,null,symbol
所有未初始化的变量都是undefined,所有的基本类型的值都是不可改变的,即不存在把基本类型变量传给一个函数,函数内部可以修改这个变量,同样String不可以看成字符数组。
number内部实现为double。
对象
数组Array(从0开始),映射Map,集合Set等都是Object。对象的属性可以用点运算符或者方括号运算符访问,其参数将会转换为String访问对应的属性。大部分情况下可以看成一个特殊的字典。
所有的方法是函数类型属性,函数内部使用this关键字能访问到类实例。以new [function call]
为新建实例语法,函数内部访问的this
就是一个新对象,这叫做构造函数。
一个object的__proto__属性表示其父类。
因为没有具体类型的概念,在JS中以构造函数的差别来区别对象与对象之间的不同。
在ES6之后,可以使用类似C++的对象定义语法。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
new Point(1,2);
函数
在全局作用范围内的具名function表示定义全局函数,在局部作用范围内的具名function依据实现定义行为。
可以传入与参数列表不匹配的值,以类似解包的形式赋值。
Lambda
(...arguments) =>{ <function body> }
(...arguments) => expression;
生成器函数
生成器函数和数组差不多
function* func(){
yield 1;
yield 2;
}
//same as
function* func(){
yield* func();
}
//same as
function* func(){
for (let i=1;i<=2;i++)
yield i;
}
a=func()//获得生成器实例
a.next();//return {value:1,done:false}
a.next();//return {value:2,done:false}
a.next();//return {value:undefined,done:true}
表达式
隐式转换
对象转换成基本类型首先调用对象的valueOf方法,如果其还是对象就调用toString()
隐式转换为Boolean规则为,除了undefined,null,false,0,NaN,""是false外都是true。
运算符
数值运算运算符基本等于C++
字符串按字典序比较;至少有一个为非字符串,两操作数都将隐式转为Number比较。
对象参与运算会调用toString
方法,如果还是返回对象则调用valueOf
方法。隐式转换为基本类型然后按基本类型的比较规则比较。
对于基本类型严格相等===也会比较类型,对于对象严格相等会比较对象地址。
- 指数运算符
> 2 ** 3 ** 2
512
> (2**3)**2
64
- 链判断运算符
message?.text
如果message
为undefined
或null
整体返回undefined
- Null判断运算符
message?.text ?? "no text"
如果message?.text
返回null
或undefined
时,返回"no text"
- 扩展运算符
console.log(...[1, 2, 3])
//same as console.log(1,2,3)
function sum(...rest){
let ans=0;
for (let i of rest)
ans+=i;
return ans;
}
C++人困惑
语句
定义标识符
let
定义以最近大括号为生命周期的变量,可以使用类似C++的结构化绑定的语法写数组绑定和对象绑定。
const
同let
,但是因为没有const
方法,JS中只指变量不可被赋值。
分支
同C++,但switch
判断等于使用===
操作符。
循环
for (...;...;...)
,while (...){}
,do {} while(...);
同C/C++。
for (... of ...)
按value
遍历。
for (... in ...)
按 key
遍历
发送HTTP请求(XMLHttpRequest)
url='https://httpbin.org/ip';
let req=new XMLHttpRequest();
req.addEventListener("load" , (e)=>{
console.log(JSON.parse(e.currentTarget.response))
});
req.open("GET",url,true);
req.setRequestHeader("Content-type","application/json");
req.send()
//{origin: '23.237.66.140'}
open(method,url,async)
send(string):POST时发送string
支持事件
abort
请求被终止
error
请求错误
load
请求成功完毕
loadend
请求处理完毕
loadstart
请求准备接收信息
progress
用于上传文件时更新进度
timeout
服务器响应超时
模块
每个Javascript文件处于属于唯一的一个属于自己的运行上下文,可以使用模块导入导出引入。
导出
//profile.js
export var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export { lastName, year };
export function multiply(x, y) {
return x * y;
};
function v1() { ... }
function v2() { ... }
export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion
};
export default function(){
return {
function func(){
console.log(1);
}
};
}
导入
每一个导入语句均会被提升到代码最前面,在编译期确认模块之间的导入导出关系。
不使用默认导出则必须使用大括号。
import { firstName, lastName, year } from './profile.js';
import func from './profile.js';
Vue
本文使用vue-cli
创建项目
运行vue create hello-world
创建hello world
项目
文件结构说明
├── babel.config.js Babel配置
├── jsconfig.json 给IDE看的javascript项目配置
├── node_modules npm包目录
├── package.json npm包配置
├── package-lock.json npm包配置
├── public
│ ├── favicon.ico
│ └── index.html html-webpack-plugin
├── README.md
├── src vue代码文件
│ ├── App.vue
│ ├── assets
│ ├── components
│ └── main.js
└── vue.config.js vue配置
在release编译过程中首先使用vue
编译src
目录下的js
文件,其入口文件为main.js
,然后将public
内所有文件经过html-webpack-plugin
打包发布。
main.js解释
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount();
通过default
方式import
导入其他vue
组件,createApp(someApp)
实例化之后调用挂载方法挂载到index.html
上面。
单文件组件vue
文件,选项式 API的构成
一个使用选项式API的vue
文件由以下三部分组成
<template>
//HTML code
</template>
<script>
//javascript code
</script>
<style>
//CSS code
</style>
在一个vue
文件被import
时按照ES6标准执行script内部的javascript代码。挂载时由vue
框架将template
解析渲染挂载到相应div
的孩子和style
应用到页面上。被卸载时将对应的HTML
和css
代码去除。
<template>
里面的<template>
将不会实际上渲染到HTML
,但是vue
框架将会处理包含的指令。
一个HTML元素只能被挂载一个组件。
Vue模块典型组成
export default {
// data() 返回的属性将会成为vue组件响应式的状态
// 并且暴露在 `this` 上
data() {
return {
count: 0,
firstName: 'John',
lastName: 'Doe'
}
},
// watch 包含监听data()内响应式状态的函数
// 只要 data() 内同名状态改变,就会调用相应的函数
watch:{
count(oldCount,newCount){
console.log("from"+oldCount+",to "+newCount);
}
}
// methods 是一些用来更改状态与触发更新的函数
// 它们可以在模板中作为事件监听器绑定
methods: {
increment() {
this.count++
}
},
computed: {
// 计算属性将被缓存,根据参数动态更新
// 在使用计算属性时不需要函数调用
publishedBooksMessage() {
// `this` 指向当前组件实例
return this.author.books.length > 0 ? 'Yes' : 'No'
}
//this.fullName = 'John Doe'会调用这里的set()
fullName: {
// getter
get() {
return this.firstName + ' ' + this.lastName
},
// setter
set(newValue) {
[this.firstName, this.lastName] = newValue.split(' ')
}
}
},
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
// 例如这个函数就会在组件挂载完成后被调用
mounted() {
console.log(`The initial count is ${this.count}.`)
}
}
Vue组件交互
//ButtonCounter.vue
<script>
export default {
props: ['text']
}
</script>
<template>
<button @click="$emit('mybuttomClicked')">{{ text }}</button>//throw a event
</template>
//main.vue
<template>
<ButtonCounter text="name" @mybuttomClicked="buttomClicked"/>//static
<ButtonCounter :text="name" @mybuttomClicked="buttomClicked"/>//dynamic
</template>
<script>
import ButtonCounter from './ButtonCounter.vue'
export default {
data(){
return {
name:"click me",
}
},
method{
buttomClicked(){
this.name="clicked";
}
},
components: {
ButtonCounter,
}
}
</script>
Vue组件生命周期
template内HTML渲染
插值
带转义文本插值
<span>Message: {{ msg }}</span>//直接使用data里的变量
<span>{{ ok ? 'YES' : 'NO' }}</span>//表达式
不能在HTML标签内使用,所有的插值都是动态(响应式)更新的。
vue指令
vue指令是可以改变DOM树的vue定义的html标签语法。
任何v-cmd:key="value"
的形式可以使用v-cmd="objectValue"
以对象为kv对应用v-cmd
。
不带转义文本插值
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
设置span
的后代为vue组件rawHtml
字符串的内容。
标签插值
<div id="StaticId"></div>
<div v-bind:id="dynamicId"></div>//dynamic javascript
<div :id="dynamicId"></div>//same above
:id
是v-bind:id
的缩写。
v-bind
的值会响应式更新。
选择插值
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-if="Math.random() > 0.5">
Now you see me
</div><div v-else>
Now you don't
</div>
<div v-if="type === 'A'">
A
</div><div v-else-if="type === 'B'">
B
</div><div v-else-if="type === 'C'">
C
</div><div v-else>
Not A/B/C
</div>
v-if
直接应用于DOM树,判断假的话不会渲染到html上。
<div v-show="Math.random() > 0.5">
Now you see me
</div>
v-show
不会改变DOM树,仅仅做了class
切换,用CSS禁止显示。
循环插值
<li v-for="item in items">
{{ item.message }}
</li>
<template v-for="item in items">
<li>
{{ item.message }}
</li>
</template>
<template v-for="item in items" :key="item.id">//根据item.id动态更新
<li>
{{ item.message }}
</li>
</template>
事件绑定
<button v-on:click="doThat('hello', $event)"></button>
<!-- shorthand -->
<button @click="doThis"></button>
<!-- shorthand dynamic event -->
<button @[event]="doThis"></button>
<!-- stop propagation -->
<button @click.stop="doThis"></button>
<!-- prevent default -->
<button @click.prevent="doThis"></button>
<!-- prevent default without expression -->
<form @submit.prevent></form>
<!-- chain modifiers -->
<button @click.stop.prevent="doThis"></button>
<!-- key modifier using keyAlias -->
<input @keyup.enter="onEnter" />
<!-- the click event will be triggered at most once -->
<button v-on:click.once="doThis"></button>
<!-- object syntax -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
表单内容绑定
<input v-model="text">//for has value
<div>Picked: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />//logic value bind
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
DOM引用
<script>
import Child from './Child.vue'
export default {
components: {
Child
},
mounted() {
// this.$refs.child 是 <Child /> 组件的实例
this.$refs.child.focus();
}
}
</script>
<template>
<Child ref="child" />
</template>