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>&nbsp;</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">

更多1:MDN<input>

CSS

HTML和CSS的联系

HTML只涉及到文本图片逻辑等元素的树状逻辑表示,即HTML只是一个结构化的文本,最终会形成一个DOM树,和JSON、YAML这些结构化文本格式并无不同。

CSS怎么计算的

一个元素的样式属性是这样计算的

  1. 计算各个选择器的优先级,优先级高的选择器描述的属性覆盖掉优先级低的选择器的属性

    • 选择器的优先级由一个四元组组成(x,y,z,w)

      1. 如果是在HTML内style声明的属性,令x=1否则x=0

      2. y为选择器中id选择器的数量

      3. z为选择器中类选择器、属性选择器或者伪类的数量

      4. w为元素、伪元素选择器的数量

    • 通用选择器 (*),组合符 (+, >, ~, ' '),和否定伪类 (:not) 不会影响优先级。

  2. 在DOM树上的父亲应用继承,所有含有inherit的属性顺延父亲的属性,如果父亲该属性也是inherit继续顺延。

盒子模型

一个盒子由margin-border-padding-(子级内容)组成。不同元素的margin可重合复用区域。

每个元素均有heightwidth属性,默认为子级内容的大小,设置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属性为0
  • flex-shrink属性为1
  • flex-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

如果messageundefinednull整体返回undefined

  • Null判断运算符
message?.text ?? "no text"

如果message?.text返回nullundefined时,返回"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++的结构化绑定的语法写数组绑定和对象绑定。

constlet,但是因为没有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应用到页面上。被卸载时将对应的HTMLcss代码去除。

<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

:idv-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>

w3school/HTML DOM Events

表单内容绑定
<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>

vue.js/form

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>