### 可视化编辑网页
```http
document.body.contentEditable="true"
document.designMode = "on"
扩大文件
cmd copy 1.txt /b + 2.txt 3.txt
谷歌cookies跨域
chrome://flags/
搜索 SameSite
SameSite by default cookies和Schemeful Same-Site设置为disabled
html
快速创建文档标签
div.class$*3
div>p+span
span{$}*1000
IDEA插件
rem 自动转px插件(px2rem)
ALT+D单个替换
CTRL+ALT全局替换
谷歌相关
携带cookie配置
快捷方式->目标添加空格
--disable-features=SameSiteByDefaultCookies
插件
vue2.0
1.打开cmd,查看当前镜像地址:
npm get registry
**2.**切换为淘宝镜像:
npm config set registry http://registry.npm.taobao/
3.切换为原本的npm镜像:
npm config set registry https://registry.npmjs/
创建vuecli2.0项目
npm install --global vue-cli
vue init webpack "项目名"
npm install
创建vuecli3.0项目
卸载2.x
npm uninstall -g vue-cli
下载3.x
npm install -g @vue/cli
vue create "项目名"
npm i
npm i vuex --save
npm i axios
npm i element-ui --save
npm i vue-resource --save (通过XMLHttpRequest或JSONP发起请求并处理响应)
npm i vue-router --save
npm i --save babel-runtime(es6编译成es5运行,前端可以使用es6的语法来写最终浏览器上运行的是es5)
npm i --save-dev babel-polyfill(Babel 默认只转换新的 JavaScript 语法,而不转换新的 API)
npm i fastclick -D
(作用:处理移动端 click 事件 300 毫秒延迟。
说明: 为什么存在延迟?从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间。为什么这么设计呢? 因为它想看看你是不是要进行双击(double tap)操作。)
安装:npm i --save lodash(Lodash是一个具有一致接口、模块化、高性能等特性的 JavaScript 工具库)
原生js:
<script src="http://wechatfe.github.io/vconsole/lib/vconsole.min.js?v=3.2.0"></script>
<script>
// init vConsole
var vConsole = new VConsole();
console.log('Hello world');
</script>
npm 安装
npm install vconsole
设置浏览器图标
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
@change @input
@change当输入框失焦的时候触发
而且在elementUI中使用change时是这样的@visible-change
@input是输入框发生变化时触发,也就是说输入框一动就出触发了
slot插槽
子组件
<template>
<div class="hello">
<h1>{{ msghello }}</h1>
<slot name="headertest"></slot>
<slot name="headertest2"></slot>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msghello: String,
},
data(){
return{
user:{
lastName:'qiang',
firstName:'guo'
}
}
}
};
</script>
父组件
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png"/>
<HelloWorld msghello="我是HelloWorld组件">
<template v-slot:headertest>
{{headertest.user}}
</template>
<template v-slot:headertest2>
{{headertest.user2}}
</template>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</HelloWorld>
<glory :msg="msg" @syfunction="syfunction"></glory>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
data() {
return {
msg: 1111111111111111111,
headertest: {
user:'guo',
user2:"xin"
}
}
},
methods: {
syfunction(val) {
this.msg += val
}
}
};
</script>
directive自定义指令
<div id="app" v-demo:foo.a.b="message"></div>
<script>
Vue.directive('demo', {
bind: function (el, binding, vnode) {
console.log(el, binding, vnode);
var s = JSON.stringify
el.style.position = 'fixed' /*样式*/
el.innerHTML =
`指令名name:${s(binding.name)}demo<br>
绑定值value:${s(binding.value)}guo<br>
指令表达式expression:${s(binding.expression)}message<br>
指令参数argument:${s(binding.arg)}foo<br>
修饰符modifiers:${s(binding.modifiers)}}"a":true,"b":true<br>
虚拟节点vnode keys:${s(Object.keys((vnode)).join(', '))}"tag, data, children, text, elm, ns, context, functionalContext, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce"<br>`
}
})
new Vue({
el: '#app',
data: {
message: 'guo'
},
methods: {},
});
</script>
生命周期
Activated
- activated 生命周期在keep-alive 组件激活时调用
- 服务器端渲染期间不调用该生命周期
- 通常和 deactivated 周期一起使用
- 服务器端渲染期间不调用该生命周期
<script>
activated(){
//当从缓存中调取数据时触发该生命周期函数
},
deactivated(){}
</script>
mounted
组件传值
props 和 $emit()
provide 和 inject
- 父组件使用provide提供数据
- 子组件使用inject获取数据
- 默认不是响应式-----------可通过传递一个
ref
property 或reactive
对象给provide
来改变这种行为 - 跨级访问(祖<--------->孙)
- 注: 只可用于父传子
// 父组件中
<template>
<div id="app"></div>
</template>
<script>
export default {
data () {
return {
datas: [
{
id: 1,
label: '产品一'
},
{
id: 1,
label: '产品二'
}
]
}
},
// 发送数据
provide {
return {
datas: this.datas, // 非响应
datas:Vueputed(() => this.datas.length) //响应式
}
}
}
</script>
// 子组件中
<template>
<div>
<ul>
<li v-for="(item, index) in datas" :key="index">
{{ item.label }}
</li>
</ul>
</div>
</template>
<script>
export default {
// 接受数据
inject: ['datas']
}
</script>
p a r e n t 和 parent和 parent和children
- 可以访问组建中所有方法和数据
// 父组件中
<script>
export default {
mounted() {
console.log(this.$children[0].user.lastName);
}
}
</script>
// 子组件
<script>
export default {
mounted() {
console.log(this.$parent.msg);
}
}
</script>
b u s 和 bus和 bus和on
- 解决无关系组件之间的交互问题,当然父子组件我们可以通过自定义事件来交互(子传父
- 无关系组件间的交互响应,相当于父子组件的自定义事件
// main.js
Vue.prototype.$bus = new Vue() // event Bus 用于无关系组件间的通信。
// a组件 接受
mounted() {
this.$bus.$on('isCalled', this.isCalled)
this.$bus.$on('missCall', this.missCall)
}
// b组件 发送
handleEvent(messageList) {
if (xxxx) {
this.$bus.$emit('isCalled')
}
if (xxx) {
this.$bus.$emit('missCall')
}
}
//相当于又new了一个vue实例,Event中含有vue的全部方法;
var Event = new Vue();
//发送数据,第一个参数是发送数据的名称,接收时还用这个名字接收,第二个参数是这个数据现在的位置;
Event.$emit('msg',this.msg);
//接收数据,第一个参数是数据的名字,与发送时的名字对应,第二个参数是一个方法,要对数据的操作
Event.$on('msg',function(msg){
/这里是对数据的操作
})
Vuex
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新
- 不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation
store
vue 引入公共样式的三种方法
在入口js文件main.js中引入,一些公共的样式文件,可以在这里引入
import Vue from 'vue'
import App from './App' // 引入App这个组件
import router from './router' /* 引入路由配置 */
import axios from 'axios'
import '../static/css/global.css' /*引入公共样式*/
在index.html中引入
<link rel="stylesheet" href="./static/css/global.css"> /*引入公共样式*/
在app.vue中引入,但是这样引入有一个问题,就是在index.html的HEADH上会多出一个空的
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
@import './../static/css/global.css'; /*引入公共样式*/
</style>
this.$set()
对象,键,值
直接给student赋值操作,虽然可以新增属性,但是不会触发视图( 页面 )更新
原因是:vue.js的属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。这里就可以使用this.$set了
<script>
export default {
data () {
return {
student: {
name: '',
age: ''
}
}
},
mounted () {
this.student.age = 24
}
mounted () {
this.$set(this.student,"age", 24)
}
}
</script>
监听
子组件
监听方法的参数就是父组件传过来的值,监听变化因为数据变了所以调一下查看接口也就是刷新数据
watch: {
childId(newVal) {
this.childId = newVal;
this.getList(); //一定要刷新数据否则页面不刷新
console.log(newVal, "这里是监听"); //这个参数就是传来的所有值
}
},
在子组件props接收是number类型
props: {
childId: Number
}
传给后端
id:this.childId
deep: true //深度监听
$route.path 字符串,等于当前路由对象的路径,会被解析为绝对路径,如/home/ews
$route.params 对象,含路有种的动态片段和全匹配片段的键值对,不会拼接到路由的url后面
$route.query 对象,包含路由中查询参数的键值对。会拼接到路由url后面
$route.router 路由规则所属的路由器
$route.matchd 数组,包含当前匹配的路径中所包含的所有片段所对象的配置参数对象
$route.name 当前路由的名字,如果没有使用具体路径,则名字为空
组件库
cnpm install element-ui -S (pc端的)
cnpm install mint-ui -S (移动端的)
cnpm install vant -S (移动端的)
vue 移动端适配(rem布局)
https://blog.csdn/dlnu2015250622/article/details/105204478/
router.beforeEach()路由拦截
import store from '@/assets/store' //把这个userId获取过来
router.beforeEach((to,from,next)=>{
if(to.meta.requireAuth){
if(store.state.userId){
next()
}else{
next({path:'/b'})
}
}else{
next()
}
})
跨域
方式1:nginx代理
不过要知道在生产中,要么使用 CORS 、要么使用 Nginx 反向代理来解决跨域。在 Nginx 的配置文件中进行如下配置即可:
server {
listen 80;
server_name localhost; # 用户访问 localhost,反向代理到 http://webcanteen
location / {
proxy_pass http://webcanteen
}
}
方式2:vue.config.js文件中
proxy: {
'/api': {
target: 'https://you.163/', //接口域名
changeOrigin: true, //是否跨域
ws: true, //是否代理 websockets
secure: true, //是否https接口
pathRewrite: { //路径重置
'^/api': ''
}
}
}
axios接口封装
src下创建文件
config文件->http.js下
import axios from "axios";
//import store from "../store"
var instance = axios.create({
baseURL:'http://www.jiaju',
});
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
if (store.state.token) {
config.headers.token=store.state.token;
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
if (response.data.code==999){
window.location.href="/";
}else{
return response;
}
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
export default instance;
api文件->index.js下
import login from "./Login"
import carousel from "./carousel"
import category from "./category"
export default {
login,
carousel,
category,
}
其他接口页面->例如:good.js
import http from '../config/http.js';
export default {
post(data){
return http.post('/goods',data)
},
get(page,){
return http.get(`/goods?page=${page}`)
},
}
main.js文件下
Vue.prototype.$http=Axios;
页面中使用
import api from "../../api/index"
api.recom.get().then(res=>{
this.tableData = res.data.data;
}).catch(err=>{
this.$message({
type:'error',
message:'获取失败'
})
})
api.recom.post(this.formLabelAlign).then(res=>{
if (res.data.code == 200){
this.$message({
type:'success',
message:'添加成功'
});
this.dialogFormVisible = false;
this.gettpl();
this.formLabelAlign = {}
} else{
this.$message({
type:"error",
message:'添加失败'
})
}
}).catch(error=>{
this.$message({
type:"error",
message:'添加失败'
})
})
移动端禁止放大缩小
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
表格文字溢出省略
:show-overflow-tooltip="true"
正则表达式处理公司名称
var a = "天津市11111公司"
var c = a.replace(/(?<=市)(\S*)(?=公)/, "****")
console.log(c);
rules校验
{ pattern: /^1(3\d|47|5((?!4)\d)|7(0|1|[6-8])|8\d)\d{8,8}$/, // required: true, message: '请输入正确的手机号', // trigger: 'blur'},
{ pattern: /^[0-9]*$/,message: '只能输入数字'},
时间过滤
shijiantime(times) {
var timearr = times.replace(" ", ":").replace(/\:/g, "-").split("-");
var timestr = "" + timearr[0] + "-" + timearr[1] + "-" + timearr[2]
// var timestr = "" + timearr[1].split("")[1] + "月" + timearr[2] + "日\t" + timearr[3] + ":" + timearr[4] + ""
return timestr
},
JS获取指定字符的前/后值
str = "12345?789”
str.split("?")[0] 输出为 12345
str.split("?")[1] 输出为 789
强制重新渲染组件
//组件上增加
:key="math"
data:{
math:0
}
math +=1
vue3.0 + Vite
安装
npm init vite-app app
cd app
npm install
npm run dev
npm install vue@next
vue upgrade --next //升级cli版本
Api
生命周期
<script>
import {
onBeforeMount,
onBeforeUnmount,
onBeforeUpdate,
onErrorCaptured,
onMounted,
onRenderTracked,
onRenderTriggered,
onUnmounted,
onUpdated
} from 'vue'
</script>
响应式
<script>
import {
inject, //子孙组件注入数据
isProxy,
isReactive,
isReadonly,
markRaw,
reactive,
readonly,
ref,
toRefs,
watchEffect
} from 'vue'
</script>
setup()
- 执行 setup 时,组件实例尚未被创建。因此,你只能访问以下 property:props attrs slots emit
- context非响应式,可使用解构,{attrs, slots, emit}
- props是响应式,当传入新的 prop 时,它将被更新
- toRefs:批量创建ref类型数据, 并和以前数据关联(响应式)
- toRef:数据发生改变, 界面也不会自动更新(新响应式数据之后还不想更新UI)
<script>
export default {
setup(props,context){
//声明响应式变量
const count = ref(100)
let reactObj = reactive({cc: '强', dd: "啊"})
//emit传值
const fnd = () => emit('fnd', 111)
//inject注入数据
const userLocation = inject('location', 'The Universe')
const userGeolocation = inject('geolocation')
// readonly 返回只读的对象,不可直接改变深层次的值
// 变更original 会触发侦听器依赖副本,
// 变更副本将失败并导致警告
//copy.counts++ // 警告!
const original = reactive({counts: 222})
const copy = readonly(original)
// 适用于响应性追踪
watchEffect(() => {
console.log(copy.counts)
})
// 标记一个对象,使其永远不会转换为 proxy。返回对象本身
const foo = markRaw({})
console.log(isReactive(reactive(foo))) // false
// 嵌套在其他响应式对象中时也可以使用
const bar = reactive({foo})
console.log(isReactive(bar.foo)) // false
//isReactive 检查对象是否是 reactive创建的响应式 proxy
//isReadonly 检查对象是否是由readonly创建的只读 proxy
//isProxy 检查对象是否是由 reactive 或 readonly 创建的 proxy
console.log(isReactive(copy), isReadonly(copy), isProxy(copy)) // -> true
return {
fnd,
...toRefs(original),
count, fnCount,
...toRefs(reactObj),
...toRefs(obj),
userLocation,
...toRefs(userGeolocation)
}
}
}
</script>
watch
- 默认初始时不执行回调, 但可以通过配置
immediate
为true
, 来指定初始时立即执行第一次 - deep:true 深度监听
<script>
import { watch, ref } from 'vue';
watch(user,({ firstName, lastName }) => {},{ immediate: true, deep: true });
</script>
script setup
组件自动注册
<template>
<Child />
</template>
<script setup>
import Child from './Child.vue'
</script>
//如果使用 name
<script>
export default {
name: "homeBread",
}
</script>
defineProps
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
title: String,
})
console.log(props.title)
</script>
defineEmits
<script setup>
import { defineEmits } from 'vue'
const emit = defineEmits(['del', 'delete'])
//使用==删除
const deleteRow = (index, data) => {
emit('del', index, data)
}
</script>
defineExpose
- 如果需要对外暴露 setup 中的数据和方法,需要使用 defineExpose API
<script setup>
import { defineExpose } from 'vue'
const a = 1
const b = 2
defineExpose({
a
})
</script>
slots, attrs
// 新
<script setup>
import { useAttrs, useSlots } from 'vue'
const attrs = useAttrs()
const slots = useSlots()
</script>
路由
安装
npm install vue-router@4.0.0-beta.13
Propety
实例
- $data
- $props
- $el
- $options
- $parent
- $root
- $refs
- $attrs
方法
- $watch
- $emit
- $forceUpdate
- $nextTick
修改端口号
"dev": "vite --port 8085",
Vite
Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。
通过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目。
使用 npm:
$ npm init vite <project-name> -- --template vue
$ cd <project-name>
$ npm install
$ npm run dev
或者 yarn:
$ yarn create vite <project-name> --template vue
$ cd <project-name>
$ yarn
$ yarn dev
Webpack
webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle
-
入口(entry)
-
输出(output)
-
loader
-
插件(plugin)
-
模式(mode)
-
浏览器兼容性(browser compatibility)
-
环境(environment)
// webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装 const webpack = require('webpack'); // 用于访问内置插件 module.exports = { //入口 entry: './path/to/my/entry/file.js', // 输出 output: { path: path.resolve(__dirname, 'dist'), filename: 'my-first-webpack.bundle.js', }, // 模式 mode: 'production', // loader module: { rules: [{ test: /\.txt$/, use: 'raw-loader' }], }, // 插件 plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })], };
mint-ui
解决input问题
type=“number”
<mt-field
label="金额"
type="number"
placeholder="最高15位数"
:attr="{ oninput: 'if(value.length>15)value=value.slice(0,15)' }"
v-model="amount"
>
</mt-field>
<!DOCTYPE html>
<html lang="en" style="font-size:100px">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
function resetFontSize() {
var baseFontSize = 100
var designWidth = 750
var width = window.innerWidth
var currentFontSize = (width / designWidth) * baseFontSize
document.getElementsByTagName('html')[0].style.fontSize = currentFontSize + 'px'
}
window.onresize = function () {
resetFontSize()
};
resetFontSize()
</script>
<style>
*{
padding:0;
margin:0;
}
body{
overflow: auto;
font-size: .28rem;
}
.box{
width:7.5rem;
height: 1rem;
background: #000;
}
</style>
</head>
<body>
<div class="box"></div>
<p>42341</p>
</body>
</html>
缩放
transform: scale(1.05, 1.05);
-ms-transform: scale(1.05, 1.05);
/* IE 9 */
-webkit-transform: scale(1.05, 1.05);
/* Safari and Chrome */
transition: 0.3s;
正则匹配元素中的图片标签
const regex = new RegExp('<img', 'gi')
this.result.content.replace(regex, `<img style="max-width: 100%; height: auto"`);
String字符串截取操作
substr(start,length) 返回从start位置开始length长度的子串
substring(start,end) 返回从start位置开始到end位置的子串(不包含end)
//1 取字符串的前i个字符
str=str.substring(0,i);
//2 去掉字符串的前i个字符
str=str.substring(i);
//3 从右边开始取i个字符
str=str.substring(str.length()-i);
str=str.substring(str.length()-i,str.length());
//4 从右边开始去掉i个字符
str=str.substring(0,str.Length-i);
//5 如果字符串中有"abc"则替换成"ABC"
str=str.replace("abc","ABC");
Array数组截取操作
var heros=["李白",'蔡文姬','韩信','赵云','甄姬','阿珂','貂蝉','妲己'];
console.log(heros.slice(1,4))// [ "蔡文姬", "韩信", "赵云" ]开始索引为1 结束索引为4(不包括4)
console.log(heros)// 不改变原数组 [ "李白", "蔡文姬", "韩信", "赵云", "甄姬", "阿珂", "貂蝉", "妲己" ]
//若开始索引为负数,则将该值加上数组长度后作为开始索引,如果此时还是负数,开始索引为0。
var heros=["李白",'蔡文姬','韩信','赵云','甄姬','阿珂','貂蝉','妲己'];
console.log(heros.slice(-6,4))// [ "韩信", "赵云" ]开始索引为2 结束索引为4(不包括4)
console.log(heros.slice(-10,4))// [ "李白", "蔡文姬", "韩信", "赵云" ]开始索引为0 结束索引为4(不包括4)
//如果结束索引省略,截取到数组的末尾。如果为负,数组长度加上该值即为结束索引,如果此时还为负数,返回空数组
var heros=["李白",'蔡文姬','韩信','赵云','甄姬','阿珂','貂蝉','妲己'];
console.log(heros.slice(1))// [ "蔡文姬", "韩信", "赵云", "甄姬", "阿珂", "貂蝉", "妲己" ]
console.log(heros.slice(1,-4))// [ "蔡文姬", "韩信", "赵云" ] 开始索引1 结束索引8+(-4)=4
console.log(heros.slice(1,-10)) //[ ] 开始索引1 结束索引8+(-10)=-2
var heros=["李白",'蔡文姬','韩信','赵云','甄姬','阿珂','貂蝉','妲己'];
//当只有索引,从当前索引截取到最后
console.log(heros.splice(1))// [ "蔡文姬", "韩信", "赵云", "甄姬", "阿珂", "貂蝉", "妲己" ]
console.log(heros) //['李白']
//当第二个参数(删除数量)小于0视为0
var heros=["李白",'蔡文姬','韩信','赵云','甄姬','阿珂','貂蝉','妲己'];
console.log(heros.splice(1,-10))//[]
console.log(heros) // [ "李白", "蔡文姬", "韩信", "赵云", "甄姬", "阿珂", "貂蝉", "妲己" ]
//删除并添加
var heros=["李白",'蔡文姬','韩信','赵云','甄姬','阿珂','貂蝉','妲己'];
console.log(heros.splice(1,2,['扁鹊'],'孙膑'))//[ "蔡文姬", "韩信" ]
console.log(heros) //[ "李白", [扁鹊], "孙膑", "赵云", "甄姬", "阿珂", "貂蝉", "妲己" ]
可以输入数字和小数点
oninput =“value=value.replace(/[^\d]/g,'')” //只能输入数字
oninput =“value=value.replace(/[^0-9.]/g,’’)” //只能输入数字和小数
JavaScript
客户端脚本语言。
h5(css3 JS ):
1.语义化
2.表单标签
3.本地存储
4.表单属性
5.canvas 画布
6.audio video音频 视频
git svn:分布式版本控制系统;
作用:
-
完成页面交互效果;
-
数据验证
-
动态创建元素
-
动态操作元素的属性样式
-
ajax 100%
组成:
- ECMAscript基础语法:(es5、es6)
变量(命名规范、赋值)、数据类型(基本、引用)、运算符(算术运算符、关系、赋值、逻辑)、流程
控制(顺序、条件、循环)、数组(方法)、函数(定义、调用、参数、返回值、默认值)、对象(定义、原型、原型链、继承、this、this改变方式)、作用域(全局、局部、块级、作用域链、闭包)、字符串、日期、Math
- BOM(浏览器对象模型)
window对象、location对象、history对象、document对象
- DOM(文档对象模型)document对象
获取元素、操作元素的内容、属性、样式、节点、元素的尺寸与位置、事件(添加事件的方式、事件的分类、事件流、事件委派)
特征:
基于
对象
与事件驱动
与松散型
、解释型
语言。
单线型
、异步机制
引入方式:
-
外部引入方式
<script src="demo.js"></script>
- 嵌入式
在script标签对中写js代码
- 事件后
注意事项:
1.嵌入式的script标签上边不写src属性
2.外部引入方式中的js文件不写script标签对
3.几种js引入方式都是相互关联的,可以进行相互操作
调试工具:
- 输出到控制台
console.log(1)
- 弹出框
alert("a")
- 写入到页面中(识别标签对)
document.write("b")
document.write("<h1>识别标签对</h1>");
- 接收用户输入的一个数:
prompt("请输入一个数")
- 有确定与取消按钮的弹框
confirm("确定退出吗"); //true false
注释:
-
单行注释:// ctrl+/
-
块级注释:/**/ ctrl+shift+/
变量:
一个容器,用来存储数据;
利用var关键字声明变量。
命名规范:
数字、字母、下划线、$
- 不能以数字开头
- 区分大小写
- 变量要有意义
- 不能用关键字(js中已经用到的)命名
- 不能用保留字(js中未用到的)命名
- 首字母大写法 Object Array
- 驼峰命名 getElementByld
赋值:
1.先声明后赋值:`var a;a=12;
2.声明的同时赋值
3.一次性声明多个变量在赋值,用逗号隔开
4.一次性声明多个变量同时赋值
注意事项:
-
先声明后使用
-
变量的默认值为undefind
-
新值覆盖旧值
-
变量可以重复声明
-
不用
var
关键字声明变量,但是赋值了,不报错,这个变量是全局变量 -
不用
var
关键字声明变量,但是没有赋值,会报错 -
先使用后声明,会输出默认值,`undefined.预解析(var,function)与解析;
数据类型:
变量中存放的数据的类型,按照数据在内存中的存储位置,分为基本数据类型与引用数据类型;
基本数据类型:(栈区)
-
number(数字型):正数、负数、小数、二进制、八进制、十进制、十六进制、科学计数
NaN:特殊的number型(not a number).期望出现数字,但不会出现时,生成nan
-
string(字符串型):加单双引号
-
boolean(布尔型):true,false(真假)
-
undefined:变量声明但未赋值;变量直接赋值为undefined
-
null:直接赋值null,typeof的结果为object;
引用数据类型:(堆区)
-
object:对象
-
数组、对象的数据类型是object
-
函数的数据类型是function
-
typeof null的结果是object
-
typeof检测变量的数据类型
运算符:
算数运算符:
+
-
*
/
%
++var
var++
--var
var--
-
*
/
%
两个操作数是数字型,如果不是会隐式调用Number()函数,试图转换为数字型。true 1;false 0;
null 0;undefind NaN;数字型字符串转化为number,非数字型字符串转换为NaN;
-
+
- 加法:两个操作数都是number型;
- 拼接:有一个操作数是字符串时 ,做拼接;
- 拼接:(ES6)模板字符串
`${i}-${j}`
-
var++
++var
-
++在前,先做本条语句中的加法运算,再做其他运算;
-
++在后先做其他语句中的其他运算,在做加法运算;
-
关系运算符:
< > >= == === != !==
返回值为布尔值;
- 如果两个操作数都是数字,正常比较大小;
- 如果两个数都是字符串、数字型字符串(第一位数),转换为ASCII码值进行比较;
- 如果一个操作数是数字,另一个操作数是字符串,要将字符串转换为数字,转换成功,正常比较,转换不成功,返回false;
true
==1false
==0==
要求数值相等===
要求数据类型、数值相等;undefind==null
赋值运算符;
= += -= *= /= %=
var num=10;
num+=12;
console.log(num); 输出22
逻辑运算符:
测定值与变量之间的逻辑关系:
false、null、undefind、0、NaN、空字符串 -> false;
&&与
同真为真.返回第一个假值,如果没有假值,返回最后一个真值
|| 或
同假为假,返回第一个真值,如果没有真值,返回最后一个假值;
!非
取反
?? 空值合并操作符
//当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数
const nullValue = null;
const emptyText = ""; // 空字符串,是一个假值,Boolean("") === false
const someNumber = 42;
const valA = nullValue ?? "valA 的默认值";
const valB = emptyText ?? "valB 的默认值";
const valC = someNumber ?? 0;
let a;
let b = a ?? 5;
console.log(b); // 5
console.log(valA); // "valA 的默认值"
console.log(valB); // ""(空字符串虽然是假值,但不是 null 或者 undefined)
console.log(valC); // 42
?. 可选链操作符
//允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值
let customer = {
details: {
age: {
num: '999',
getsonme:function(){
return "有"
}
},
}
};
let customerCity = customer.details?.age?.nu ?? "无"
//age是否存在?存在则继续链式.nu<值为undefind,所以返回 无>
console.log(customerCity); //无
let yes = customer.details?.age?.getsonme() ?? "无"
console.log(yes) //有
&&= 逻辑赋值操作符
let x = null;
let y = 2;
x &&= y;
console.log(x); // 2
//如果x存在,则赋值,否则返回x
//等价于
x && (x = y)
//或者等价于
if(x) {
x = y
}
||= 逻辑赋值操作符
let x = 1;
let y = 2;
x ||= y;
console.log(x); // 1
??= 逻辑赋值操作符
let x;
let y = 2;
x ??= y;
console.log(x); // 2
逻辑运算真值表:
A | B | A&&B | A||B | !A |
---|---|---|---|---|
T | T | T | T | F |
F | F | F | T | F |
T | F | F | T | T |
F | T | F | T | T |
三元运算符:
条件?值1:值2;
判断条件的真假,如果条件为真,执行1;如果为假,执行2;
特殊运算符:
,
一次性声明多个变量()
提高优先级;
一元运算符:
- typeof:检测变量的数据类型
- new:实例化对象;
流程控制
代码的执行顺序
- 顺序结构
- 分支
- 循环
分支结构:
满足一定条件时;执行相应的代码;
单分支
if(条件){
满足条件执行的代码;
}
双分支:
if(条件){
满足条件时执行的代码;
}else{
不满足条件时执行的代码;
}
多分支:
if(条件){
满足条件1时执行的代码;
}else if{
不满足条件1,满足条件2时执行的代码;
}else if{
不满足条件1和2,满足条件3时执行的代码;
}
else{
以上条件都不满足时执行的代码
}
嵌套分支:
if(){
if(){}else{}
}else{
if(){}else{}
}
switch
switch(变量){
//值为变量能够取到的结果;值与变量的数据类型相同;
case"值1":语句1;break;(终止)
case"值2":语句2;break;
case"值3";语句3;break;
default:以上条件都不满足时执行此语句;
}
注意:
- if中的条件不能重复
- switch用在条件有限的情况下
循环结构:
满足一定条件时,重复执行一段代码;
for循环:
for(初始条件;终止条件;步行值){
循环体;
}
while循环:
while(条件){
循环体
}
do while循环:
do{
循环体
}while(条件)
跳出循环的语句:
- continue:跳出本次循环,后面的循环仍然会执行;
- break:终止循环,后面的循环不执行;
数组:
存储一系列相关信息;
声明:
// 使用数组字面量表示法
var arr=[];
// 使用array构造函数
var arr1 = new Array(); //创建一个空数组
var arr1 = new Array(20); //创建一个长度为20的空数组
// Array.of 方法创建数组(es6 新增)
let arr = Array.of(1, 2);
console.log(arr.length);//2
let arr1 = Array.of(3);
console.log(arr1.length);//1
console.log(arr1[0]);//3
let arr2 = Array.of( 2 );
console.log(arr2.length);//1
console.log(arr2[0]);// 2
// Array.from 方法创建数组(es6 新增)
function arga(...args) { //...args剩余参数数组,由传递给函数的实际参数提供
let arg = Array.from(args);
console.log(arg);
}
arga( arr1 , 26, from ); // [ arr1 ,26, from ]
赋值:
- 声明的同时赋值:
var arr=[1,2,3,4]
- 先声明后赋值:
var =[]
arr[0]=1,arr[1]=3; //通过下标赋值
访问:
通过下标去访问;
arr[下标]
,下标开始为0,结束为arr.length-1
长度:
arr.length
遍历:
全部访问每一个元素;
for(var i=0;i<arr.length;i++){
arr[i];
}
注意:
- 数组元素的数据类型可以是任意数据类型;
- 数组元素的默认值为undefind
- 数组可以越界访问;
二维数组:
数组的每一个元素数据类型还是数组;
- 访问:双重下标访问
arr[i][j] arr[0][0]
- 遍历:
var arr=[[1,2,3],[2,3,],[true]];
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr[i].length;j++){
arr[i][j];
}
}
赋值数组
浅拷贝:传址
var arr1=arr;
深拷贝:传值
var arr1=[];
for(var i=0;i<length;i++){
arr1.push(arr[i]);
}
定义函数;
- function关键字
function functionname(){
}
- 字面量
var variable=function(){
函数体
}
-
实例化构造函数
调用函数:
-
functionName()
-
variable()
-
参数:
使函数更加灵活;
- 参数可以是任意数据类型
形参:
定义函数里括号中的叫形参(目的是接受实参)
实参:
调用函数里括号里的叫实参,目的是给形参传值。
参数的传递:
- 形参=实参,–对应,从左向右传递;
- 形参>实参,多余的形参为undefind;
- 形参<实参:用arguments对象接受;
arguments:
- 接收函书中所有实参
- 定义函数时在函数内部自动生成的对象,在函数外部不能访问;
- 属性:length;长度; callee:返回函数;
for(var i=0;i<arguments.length;i++){
arguments[i];
}
剩余参数:
- 接收函书中剩余参数
- rest是一个数组,可以使用数组的方法;
function fn(a,b,...rest){
console.log(rest);
for(var i=0;i<rest.length;i++){
rest[i];
}
}
参数的默认值:
- 分支结构
- 三元运算符
- 逻辑或||
- ES6参数默认值;
返回值:
- return终止函数,后面的代码不执行;
- 函数的返回值可以是任意数据类型;
- 一个函数可以有多个return语句,最终只执行一个return语句;
- 函数没有返回值,则返回undefind
内置顶层函数:
进行数据类型转换;ECMAscript自带的函数,在全局都能访问的函数;
- escape():对字符串进行编码;
- unescape():对编码的字符串进行解码;
- Number():将任意数据类转换为number型;
- String():将任意数字类型转换为字符串型;
- Boolean():将任意数字类型转换为布尔型(6种假值);
0 null NaN undefind 空字符串 false
- parselnt():将字符串转换为整型;方法超过16位失真
识别数字开头(+、-、空格)的到数字结尾的字符串;其余返回NaN;
- parseFloat:将字符串转换为浮点型;
识别数字开头(+、-、空格)的到数字结尾的字符串,其余返回NaN;
- isNaN:判断一个数是否能转换为数字型,能返回false,不能返回true;
- eval():将字符串转换为js的命令执行;
数据类型转换:
-
隐式数据类型转换;
-
强制数据类型转换;
回调函数:
把一个函数传递给另一个函数,当做参数的这个函数调用时就叫做回调函数;
作用域:
变量起作用的范围;
全局作用域;
在函数外部用var关键字声明的变量;
不用var关键字声明但赋值的变量;
块级作用域:
{ } let const
let:
let 用来声明变量,可以识别块级作用域;
let不存在变量提升 (先访问后声明) ;
let不可以重复声明;
const
- const用来声明常量。声明的同时赋值;可以识别块级作用域;
- const不存在变量提升;
- const不可以重复声明;
作用域链:
为变量赋值时遵循的一条规则,从内到外进行访问,局部作用域优先于全局作用域;
局部作用域;
在函数内部用var关键字声明的变量
形参是局部变量;
立即执行函数 (匿名函数)
(function(){}());
apply()和call()
call() 方法分别接受参数。
apply() 方法接受数组形式的参数
// apply
let ob1 = {
namefunc: function (city, rural) {
return `${this.firstname},${city},${rural}`
}
}
let ob2 = {
firstname: '郭辛强'
}
let ob3 = ob1.namefunc.apply(ob2, ["万安镇", "兰家节村"])
console.log(ob3); /*郭辛强,万安镇,兰家节村*/
对象:
- 类:相同属性具有相同方法的对象的集合;
- 对象:属性与方法的集合;
- 属性:对象具有的特征;
- 方法:对象具有的功能;
声明对象:
- 利用构造函数实例化对象;
function Computer(color,size,price){
this.color=color;
this.size=size;
this.price=price;
this.code=function(){
"敲代码"
}
this.play=function(){
"玩游戏"
}
}
let apple=new computer("white",100,100000);
let asus=new computer("black",10,1000000);
console.log(apple);//访问对象;
console.log(asus);//访问对象;
apple.band="APPLE";//添加属性;
console.log(apple.color);//访问属性;0 b
console.log(apple.play);//访问方法;
delete apple.color;//删除属性;
apple.color="red";//修改属性(直接覆盖);
for(let i in apple){//访问;
console.log(i);//键 属性名;
console.log(apple[i]);//值 属性 方法;
}
console.log(apple.constructor);//显示构造函数
- json:
let apple={
color:"white",
size:15.6,
price:10000,
code:function(){
console.log(code)
},
play:function(){
console.log(play)
}
}
console.log(apple.color);
apple.code();
for(let i in apple){
console.log(apple[i])
},
for(let i in apple){
console.log(i);
}
console.log(apple.constructor);//显示构造函数
- 利用类实例化对象 es6
class computer{
constructor(color){
this.color=color;
this.size=size;
}
play(num){
console.log(num);
console.log(this.color);
}
}
let apple=new Computer("red");
- 实例化object:
var obj=new object();
增删改访问:
- 增:对象
- 删:
- 改:
- 访问:
遍历:(键值对)
for(let i in obj){
i;// 键 属性名
object[i];//值 属性 方法
}
constructor:
对象的属性,返回对象的构造函数; apple.constructor
instanceof:
console.log(对象 instanceof 构造函数),用来判断对象的构造函数,是true,否false;
prototype:
- 构造函数的属性;json;
- 存放公共属性和方法;解决构造函数不能共享属性和方法的问题造成资源浪费;
- 原型、原型对象;(格式)构造函数点.proyotype;
Person.prototype={
height:180,
code:function(){
}
}
--proto--
-
对象拥有的属性;
-
对象的–proto–属性。指向构造函数的原型对象;
-
--proto--
形成原型链,实现继承; -
继承顺序:找自己、找构造函数、找原型对象、Object.prototype、null;
原型链:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HIXt818i-1639533983784)(C:\Users\Administrator.USER-20190109DE\Desktop\JS\原型链继承.png)]
寻找对象属性与方法时遵循的规则;实现继承。
function Markey() {
this.color="brown";
this.height=180;
}
Markey.prototype.play=function(){
console.log("game");
};
function Parson() {
this.character="Extroversion";
this.gander="man";
}
Parson.prototype=new Markey();
Parson.prototype.play=function () {
console.log("wan");
}
Parson.prototype.height=110;
let student=new Parson();
console.log(student);
console.log(student.__proto__==Parson.prototype);
console.log(Parson.prototype.__proto__==Markey.prototype);
console.log(Markey.prototype.__proto__==Object.prototype);
console.log(Object.prototype.__proto__ == null);
数组对象:
属性:
- length:数组长度;
__proto__
:指向构造函数的原型对象;- constuctor:返回构造函数;
方法:
- concat:
arr.concat([1,2,3,4])
链接一个或多个数组,不会改变原数组; - every:
arr.every(function(ele,index,obj){return ele>0
}).当所有元素都满足条件是,返回true,否则返回false; - some:只要有一个元素满足条件,返回true;
- fill:
arr.fill("a",start,end)
用于将一个固定值替换数组的元素,会影响原数组; - *filter:
arr.filter(function(ele,index){return ele>2})
过滤,从一个集合到另一个更小的集合; - *map:映射,从一个集合到另一个集合;
arr.map(function(ele){return ele*2})
- find:
arr.find(function(ele){return ele>2})
返回满足条件的第一个元素,没有满足返回false; - findindex:
arr.findindex(function(ele){return ele>2})
返回满足条件的第一个元素的下标,否则返回-1; - ***forEach:
arr.forEach(function(ele,index){console.log(ele)})
遍历数组; - includes:
arr.includes(1)
判断是否包含指定元素,包含返回true,否则返回false; - indexOf:
arr.lastIndexOf(1)
返回包含指定元素的下标(从后往前找),不包含返回-1; - join:
arr.join("-")
将数组转换为字符串,默认用逗号拼接; - toString:
arr.toString()
将数组转换为字符串,只能用逗号拼接; - push:
arr.push("a")
向数组的后面添加一个元素或多个元素,返回新数组的长度,影响原数组; - pop:
arr.pop()
删除数组的最后一个元素,返回删除的元素,会影响原素组; - reduces:
arr.reduce(function(tot,ele){return tot+ele})
从·从前向后累加; - reduceRight:
arr.reduceRight(function(tot,ele){return tot+ele})
从后向前累加; - reverse:
arr.reverse()
反转,影响原数组; - unshift:
arr.unshit("a","b")
在数组的前面插入一个或多个元素,返回新数组的长度,影响原数组; - shift:
arr.shift()
删除数组的第一个元素,返回被删除的元素,影响原数组; - sort:
arr.sort(function(a,b){return a-b})
排序a-b从小到大,b-a从大到小; - slice:
arr.slice(start,end)
截取 从start位置开始到end位置,但不包含end在内; - splice:万能的增加删除
arr.splice(index,num);
arr.splice(index,0,item1,item2);
arr.splice(index.4,item1,item2);
Math:用于执行数学任务。
Math | 属性 | 方法 | |
---|---|---|---|
PI | 属性就是 π,即圆的周长和它的直径之比。 | Math.PI | document.write("PI: " + Math.PI); |
abs(x) | 返回数的绝对值。 | x 必需。必须是一个数值。 | document.write(Math.abs(7.25) + “ ”) |
ceil(x) | 可对一个数进行向上取舍 | ceil() 方法执行的是向上取整计算,它返回的是大于或等于函数参数,并且与之最接近的整数。 | document.write(Math.ceil(0.60) + “ ”) |
floor(x) | 可对一个数进行下舍入 | floor() 方法执行的是向下取整计算,它返回的是小于或等于函数参数,并且与之最接近的整数。 | document.write(Math.floor(0.60) + “ ”) |
log(x) | 可返回一个数的自然对数 | 参数 x 必须大于 0。 | document.write(Math.floor(0.60) + “ ”) |
max(x,y) | 返回 x 和 y 中的最高值。 | 参数中最大的值。如果没有参数,则返回 -Infinity。如果有某个参数为 NaN,或是不能转换成数字的非数字值,则返回 NaN。 | x: 0 或多个值。在 ECMASCript v3 之前,该方法只有两个参数。 |
min(x,y) | 返回 x 和 y 中的最低值。 | 参数中最小的值。如果没有参数,则返回 Infinity。如果有某个参数为 NaN,或是不能转换成数字的非数字值,则返回 NaN。 | document.write(Math.min(5,7) + “ ”) |
pow(x,y) | 返回 x 的 y 次幂。 | 如果结果是虚数或负数,则该方法将返回 NaN。如果由于指数过大而引起浮点溢出,则该方法将返回 Infinity。 | |
random() | 返回 0 ~ 1 之间的随机数。 | 0 到1之间的一个伪随机数。(不包括1) | |
round(x) | 把数四舍五入为最接近的整数。 | 与 x 最接近的整数。 | |
sqrt(x) | 返回数的平方根。 | 参数 x 的平方根。如果 x 小于 0,则返回 NaN。 | |
toSource() | 返回该对象的源代码。 | 该方法在 Internet Explorer 中无效。 | |
valueOf() | 返回 Math 对象的原始值。 | 该原始值由 Math 对象派生的所有对象继承。 valueOf() 方法通常由 JavaScript 在后台自动调用,并不显式地出现在代码中。 |
源代码:toSource的用法:
function employee(name,job,born)
{
this.name=name;
this.job=job;
this.born=born;
}
var bill=new employee("Bill Gates","Engineer",1985);
document.write(bill.toSource());
字符串:
属性:
- constructor
- proto
- length:字符串的长度;
方法:
- charAt(i):返回指定位置对应的字符;’
- charCodeAt(i):返回指定位置对应字符的ASCll码值;
- String.fromCharCode(99):将ASCll码值转换为指定的字符;
- indexOf(str1):返回指定字符串str1在字符串str中首次出现的位置;
- lastIndexOf(str1):返回指定字符串str1在字符串str中最后出现的位置,否则返回-1;
- includes(str1):判断字符串str中是否包含str1,是返回true,否则返回false;
替换:
- replace(str1,str2):利用str2替换str1首次出现的位置,不会对原字符串造成影响;
重复:
- repeat(num):字符串重复出现num次;
转换:
- toUpperCase():转换为大写
- toLowerCase():转换成小写;
- split(标志):按照指定的标识符将字符传转换为数组;
截取:
- slice(start,end):截取开始到结束的位置,不包含结束位置的字符;
- subString(start,end):不支持负数,
- substr(start,length):从指定位置开始截取指定长度的字符串;
1、indexOf()
var str = "123";console.log(str.indexOf("3") != -1 ); // true
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。如果要检索的字符串值没有出现,则该方法返回 -1。
lastIndexOf() 方法返回指定文本在字符串中最后一次出现的索引:
var str = "The full name of China is the People's Republic of China.";console.log(str.lastIndexOf("China"));//51,如果未找到,同indexOf一样返回-1
2、length(长度)
length 属性返回字符串的长度:
var txt = "webqdkf-web前端开发";var sln = txt.length;//15
3、search()
var str = "123";console.log(str.search("3") != -1 ); // true
search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。如果没有找到任何匹配的子串,则返回 -1。
你注意了吗?indexOf() 与 search()是相等的。这两种方法是不相等的。区别在于:
search() 方法无法设置第二个开始位置参数。
indexOf() 方法无法设置更强大的搜索值(正则表达式)。
4、slice()
slice() 提取字符串的某个部分并在新字符串中返回被提取的部分。该方法设置两个参数:起始索引(开始位置),终止索引(结束位置)。
这个例子裁剪字符串中位置 7 到位置 13 的片段:
var str = "Apple, Banana, Mango";var res = str.slice(7,13);//Banana
如果某个参数为负,则从字符串的结尾开始计数。这个例子裁剪字符串中位置 -12 到位置 -6 的片段:
var str = "Apple, Banana, Mango";var res = str.slice(-13,-7);
如果省略第二个参数,则该方法将裁剪字符串的剩余部分:
var res = str.slice(7);
或者从结尾计数:
var res = str.slice(-13);
5、substring()
substring() 类似于 slice()。不同之处在于 substring() 无法接受负的索引。
var str = "Apple, Banana, Mango";var res = str.substring(7,13);//res 的结果是:Banana
如果省略第二个参数,则该 substring() 将裁剪字符串的剩余部分。
6、substr()
substr() 类似于 slice()。不同之处在于第二个参数规定被提取部分的长度。
var str = "Apple, Banana, Mango";var res = str.substr(7,6);//res 的结果是:Banana
如果省略第二个参数,则该 substr() 将裁剪字符串的剩余部分。
var str = "Apple, Banana, Mango";var res = str.substr(7);//res 的结果是:Banana, Mango
如果首个参数为负,则从字符串的结尾计算位置。
var str = "Apple, Banana, Mango";var res = str.substr(-5);//res 的结果是:Mango
第二个参数不能为负,因为它定义的是长度。
7、replace()
replace() 方法用另一个值替换在字符串中指定的值:
str = "Please visit Microsoft!";var n = str.replace("Microsoft", "fly63");
replace() 方法不会改变调用它的字符串。它返回的是新字符串。默认地,replace() 只替换首个匹配:
str = "Please visit Microsoft and Microsoft!";var n = str.replace("Microsoft", "fly63");//'Please visit Microsoft and Microsoft!'
默认地,replace() 对大小写敏感,因此不对匹配 MICROSOFT。如需执行大小写不敏感的替换,请使用正则表达式 /i(大小写不敏感):
str = "Please visit Microsoft!";var n = str.replace(/MICROSOFT/i, "fly63");
请注意正则表达式不带引号。如需替换所有匹配,请使用正则表达式的 g 标志(用于全局搜索)
8、toUpperCase()
通过 toUpperCase() 把字符串转换为大写:
var text1 = "Hello World!"; // 字符串var text2 = text1.toUpperCase(); // text2 是被转换为大写的 text1
9、toLowerCase()
通过 toLowerCase() 把字符串转换为小写:
var text1 = "Hello World!"; // 字符串var text2 = text1.toLowerCase(); // text2 是被转换为小写的 text1
10、concat()
concat() 连接两个或多个字符串:
var text1 = "Hello";var text2 = "World";text3 = text1.concat(" ",text2);//Hello World
concat() 方法可用于代替加运算符。下面两行是等效的:
var text = "Hello" + " " + "World!";var text = "Hello".concat(" ","World!");
所有字符串方法都会返回新字符串。它们不会修改原始字符串。正式地说:字符串是不可变的:字符串不能更改,只能替换。
11、trim()
trim() 方法删除字符串两端的空白符:
var str = " Hello World! ";alert(str.trim());
警告:Internet Explorer 8 或更低版本不支持 trim() 方法。如需支持 IE 8,您可搭配正则表达式使用 replace() 方法代替:
var str = " Hello World! ";alert(str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''));
您还可以使用上面的 replace 方案把 trim 函数添加到 JavaScript String.prototype:
if (!String.prototype.trim) { String.prototype.trim = function () { return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');};var str = " Hello World! ";alert(str.trim());
12、charAt()
charAt() 方法返回字符串中指定下标(位置)的字符串:
var str = "HELLO WORLD";str.charAt(0); // 返回 H
13、charCodeAt()
charCodeAt() 方法返回字符串中指定索引的字符 unicode 编码:
var str = "HELLO WORLD";str.charCodeAt(0); // 返回 72
14、split()
可以通过 split() 将字符串转换为数组:
var txt = "a,b,c,d,e"; // 字符串txt.split(","); // 用逗号分隔txt.split(" "); // 用空格分隔txt.split("|"); // 用竖线分隔
如果省略分隔符,被返回的数组将包含 index [0] 中的整个字符串。
如果分隔符是 “”,被返回的数组将是间隔单个字符的数组:
var txt = "Hello"; // 字符串txt.split(""); // 分隔为字符
15、属性访问(Property Access)
ECMAScript 5 (2009) 允许对字符串的属性访问 [ ]:
var str = "HELLO WORLD";str[0]; // 返回 H
使用属性访问有点不太靠谱:
- 不适用 Internet Explorer 7 或更早的版本
- 它让字符串看起来像是数组(其实并不是)
- 如果找不到字符,[ ] 返回 undefined,而 charAt() 返回空字符串。
- 它是只读的。str[0] = “A” 不会产生错误(但也不会工作!)
var str = "HELLO WORLD";str[0] = "A"; // 不产生错误,但不会工作str[0]; // 返回 H
提示:如果您希望按照数组的方式处理字符串,可以先把它转换为数组。
16、match()
var str = "123";var reg = RegExp(/3/);if(str.match(reg)){ // 包含 }
match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
17、test()
var str = "123";var reg = RegExp(/3/);console.log(reg.test(str)); // true
test() 方法用于检索字符串中指定的值。返回 true 或 false。
18、exec( )
var str = "123";var reg = RegExp(/3/);if(reg.exec(str)){ // 包含 }
exec() 方法用于检索字符串中的正则表达式的匹配。返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。
BOM(浏览器对象模型):
负责窗口与窗口之间的通信;window对象是其核心对象;
window对象:
-
history
-
location
-
dom
-
screen(屏幕)
-
navigation(航行)
-
frames(框架)
-
closed 返回窗口是否已被关闭。 defaultStatus 设置或返回窗口状态栏中的默认文本。 document 对 Document 对象的只读引用。(请参阅对象) frames 返回窗口中所有命名的框架。该集合是 Window 对象的数组,每个 Window 对象在窗口中含有一个框架。 history 对 History 对象的只读引用。请参数 History 对象。 innerHeight 返回窗口的文档显示区的高度。 innerWidth 返回窗口的文档显示区的宽度。 localStorage 在浏览器中存储 key/value 对。没有过期时间。 length 设置或返回窗口中的框架数量。 location 用于窗口或框架的 Location 对象。请参阅 Location 对象。 name 设置或返回窗口的名称。 navigator 对 Navigator 对象的只读引用。请参数 Navigator 对象。 opener 返回对创建此窗口的窗口的引用。 outerHeight 返回窗口的外部高度,包含工具条与滚动条。 outerWidth 返回窗口的外部宽度,包含工具条与滚动条。 pageXOffset 设置或返回当前页面相对于窗口显示区左上角的 X 位置。 pageYOffset 设置或返回当前页面相对于窗口显示区左上角的 Y 位置。 parent 返回父窗口。 screen 对 Screen 对象的只读引用。请参数 Screen 对象。 screenLeft 返回相对于屏幕窗口的x坐标 screenTop 返回相对于屏幕窗口的y坐标 screenX 返回相对于屏幕窗口的x坐标 sessionStorage 在浏览器中存储 key/value 对。 在关闭窗口或标签页之后将会删除这些数据。 screenY 返回相对于屏幕窗口的y坐标 self 返回对当前窗口的引用。等价于 Window 属性。 status 设置窗口状态栏的文本。 top 返回最顶层的父窗口。
属性:
-
窗口的大小:
window.innerWidth(浏览器的宽度) ie8及以下的浏览器不支持;
window.innerHeight(浏览器的高度)
document.documentElement.clientWidth 浏览器的高度 ie8及以下的浏览器支持 document.documentElement.clientHeight 浏览器的高度
window.screenLeft 浏览器距离窗口左边的距离
window.screenTop 浏览器距离窗口顶部的距离
方法:
- alert();
- prompt();
- confirm();
- open(url):打开新窗口
- close():关闭窗口
- setlnterval(fn,1000)在一定时间间隔重复不断地执行一段代码
- clearInal(t):清除时间函数;
- setTimeout(fn,1000):在一定时间间隔后只执行一段代码
- clearTimeout(t):清除时间函数;
history:
- 历史纪录对象
属性;
- length 历史记录的长度
方法:
history.forword() 前进
history.back() 后退
history.go() 刷新
location对象:地址对象
属性:
- href:获取或设置地址
方法:
- reload():重新加载;
DOM(文档对象模型):
获取元素:
- id(一个)
document.getElementById("box"); //id名
- 类名(HTML集合)下标访问
document.getElementsByClassName("类名");
- 标签名(HTML集合)下标
document.getElementByTagName("标签名");
- 获取第一个元素
document.querySelector("选择器");
- 获取节点列表 forEach (集合) 下标
document.querySelectorAll("选择器");
操作内容:
- innerHTML 识别标签对
- innerText 不识别标签对
操作样式:
设置:
-
行内
obj.style.color="#fff"
- 批量操作类
obj.classList.add("box")
添加类 obj.classList.remove("box")
移出类obj.classList.toggle("box")
切换类
- 批量操作类
-
操作id
obj.id="box"
添加id
obj.id=""
删除id
获取:
- 行内:
obj.style.background
- 通用:
getComputedStyle(obj,null).width
操作属性:
标准属性:
- 获取:
obj.src
- 设置:
obj.src=属性值
非标准属性:
- 设置:
obj.setAttribute(属性名,属性值)
- 获取:
obj.getAttribute(属性名)
- 获取:
元素的尺寸与位置:
- offsetWidth:元素的真实宽度 width+padding+border;
- offsetHeight:元素的真实高度
- offsetLeft:获取具有定位属性的父元素左边的距离;如果没有定位属性,
- offsetTop:获取具定位属性的父元素的上边的距离;
- scrollTop:获取具有滚动条元素滚动时距离窗口顶部的距离;
- scrollLeft:获取具有滚动条元素滚动时距离窗口左边的距离;
window.onscroll=function(){
let top=document.body.scrollTop=document.documentElement.scrollTOP;
let top=document.body.scrollLeft=document.documentElement.scrollLeft;
}
节点类型:
- 整个文档叫做文档节点
- 文本内容叫做文本节点;
- 元素属性叫做属性节点;
- 注释标签叫做注释节点;
- 标签叫做元素节点;
节点的详细信息:
nodeType节点类型 | nodeName节点名称 | nodeValue节点值 | |
---|---|---|---|
文档节点 | 9 | #document | null |
元素节点 | 1 | 大写的标签名 | null |
属性节点 | 2 | 属性名 | 属性值 |
注释节点 | 8 | #comment | 注释的内容 |
文本几点 | 3 | #text | 文本内容 |
属性:
- childNodes获取所有子节点;
- firstChild获取第一个子节点;
- lastChild获取最后一个子节点;
- nextSibling获取下一个兄弟节点;
- previousSibling获取上一个兄弟节点;
- parentNode获取父节点
- children获取所有的子元素;
- firstElementChild获取第一个子元素;
- lastElementChild获取最后一个子元素;
- previousElementSibling获取上一个兄弟元素;
- nextElementSibling获取下一个兄弟元素;
方法:
-
创建:document.createElement(标签名);
-
插入:父节点 . appendChild(新节点); 插入父节点的末尾
父节点 . insertBefore(新节点,被插入的节点)
-
删除:父节点 . removeChild(要删除的节点);
-
替换:父节点 . replaceChild(新节点,旧节点);
-
克隆:节点 . cloneNode() false:只克隆本节点,默认值; true:包括子节点内的内容;
事件:
-
鼠标:click,dblclick,mouseleave,mouseover,mouseout,mousemove,mouseenter;
-
键盘:keydown,keyup,keypress
-
window:load,scroll,resize
-
表单:focus,blur,submit,reset,input(表单输入事件),change(改变内容并失去焦点),
添加事件的方式:
- 行内:
- on+type
- addEventLisenter(type,callback,boolean)事件监听
同一个事件源的同一个事件,可以添加多个事件处理函数;
obj.addEventLisenter(type,fn,false);
obj.addEventLisenter(type,function(){},false);
- removeEventListener(type,callback)
obj.removeEventListener("click",fn1);
事件对象:
记录事件发生时的详细信息;
属性:
键盘:
-
key:键盘码;
-
keycode:键盘码对应的ASCll码;
-
alt 18 ctrl 17 shift 16
-
上(38)右(39)下(40)左(37)
鼠标:
-
offsetX,offsetY:获取距事件源左上角的水平、垂直方向距离;
-
clientX,clientY:获取距浏览器左上角的水平、垂直方向距离;
方法:
- e.preventDefault(): 阻止浏览器的默认行为;
<a href="#"></a>
<a href="javascript:;"></a>
<a href="javascript:void(0);"></a>
事件流:
事件发生时会在元素节点与跟节点指尖按照特定顺序传播,路径经过的所有节点都会收到该事件,这个传播过程叫做DOM事件流
事件流类型:
- 冒泡事件流:事件传播从最确定的元素到最不确定的元素;addEventListener(false),on+type;
- 捕获型事件流:事件传播从最不确定的元素到最确定的元素;addEventListener(true)
事件流三阶段:
- 捕获阶段
- 目标阶段
- 冒泡阶段
事件委派:
把原来加给子元素的事件绑定到父元素身上;
应用场景:
- 大量元素
- 异步加载的元素
e.target:获得当前元素
本地存储:(h5)
- localStorage:
存:localStorage.setltem(key,value);
取:localStorage.getltem(key)
删:localStorage.removeItem(key)
- sessionStorage:
JSON.stringify():将对象转换为字符串;
JSON.parse():将字符串转换为对象;
localStorage\sessionStorage\cookis的区别:
cookis是网站为了标识用户身份而存储在用户本地终端(Client Side)上的数据(通常经过加密);
cookie数据始终在同源的http请求中携带(即使不需要),即会在浏览器和服务器间来回传递;
localStorage\sessionStorage不会自动把数据发给服务器,仅在本地保存;
存储大小:
cookie数据大小不能超过4k;
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 - 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。
`localStorage、sessionStorage、cookie的区别:
- 共同点:都是保存在浏览器端,且同源的。
- 区别: - cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递;cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。 - 而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 - 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。
ES12
- 数字分隔符
- String.prototype.replaceAll
- Promise.any() 和 AggregateError
- 逻辑赋值运算符
- 私有类方法和访问器
数字分隔符
//数字分隔符允许您在文字数字的数字之间添加下划线,这使它们更具可读性。当文件被解析时,这些下划线将被自动去除
let n1 = 1_000_000_000;
console.log(n1); // This will print: 1000000000
let n2 = 1_000_000_000.150_200
console.log(n2); // This will print: 1000000000.1502
String.prototype.replaceAll
// String 原型上的 replaceAll() 函数允许替换子字符串的所有实例,而无需使用正则表达式。如果在字符串上使用了 thereplace(),它只会替换该值的第一个实例。
// 另一方面,replaceAll() 提供替换该值的所有实例的功能
const orgStr = 'JavaScript, often abbreviated as JS, o the ECMAScript specification. JavaScript is h';
let newStr = orgStr.replace('JavaScript', 'TypeScript');
console.log(newStr);
// To replace all instances, use replaceAll().
let newStr2 = orgStr.replaceAll('JavaScript', 'TypeScript');
console.log(newStr2);
Promise.any 与 AggregateError
// Promise.any 与 Promise.all() 正好相反。如果任何承诺得到解决, Promise.any() 将被触发。
// 另一方面, Promise.all() 将等到所有承诺都得到解决。以下是 any()、all() 和 allSettled() 的区别。
// any() — 如果至少有一个承诺被解决,这将执行,如果所有承诺都被拒绝,则将拒绝。
// all() — 如果所有承诺都得到解决,这将执行,如果至少一个承诺被拒绝,则将拒绝。
// allSettled() — 如果所有承诺都已解决或被拒绝,这将执行
// Create a Promise.
const promise1 = new Promise((resolve, reject) => {
// After 2 seconds resolve the first promise.
setTimeout(() => resolve("The first promise has been resolved."), 2000);
});
// Create a Promise.
const promise2 = new Promise((resolve, reject) => {
// After 1 second resolve the second promise.
setTimeout(() => resolve("The second promise has been resolved."), 1000);
});
// Create a Promise.
const promise3 = new Promise((resolve, reject) => {
// After 3 seconds resolve the third promise.
setTimeout(() => resolve("The third promise has been resolved."), 3000);
});
(async function () {
const data = await Promise.any([promise1, promise2, promise3]);
// Print the data returned from the first resolved Promise.
console.log(data);
// The above will print: The second promise has been resolved.
})();
- 如果所有 Promise 都被拒绝,则会抛出 AggregateError 异常
const promise1 = new Promise((resolve, reject) => {
// After 1 second reject the first promise.
setTimeout(() => reject("The first promise has been rejected."), 1000);
});
const promise2 = new Promise((resolve, reject) => {
// After 500 miliseconds reject the second promise.
setTimeout(() => reject("The second promise has been rejected."), 500);
});
(async function () {
try {
const data = await Promise.any([promise1, promise2]);
console.log(data);
} catch (error) {
// If all Promises gets rejected, then this try-catch block will handle
// the aggregate errors.
console.log("Error: ", error);
}
})();
逻辑赋值运算符
- 逻辑 OR 赋值运算符 ||=
- 逻辑与赋值运算符 &&=
- 空合并赋值运算符 ??=
逻辑 OR 赋值运算符
// 逻辑 OR 赋值运算符 ||= 接受两个操作数,如果左操作数为假,则将右操作数分配给左操作数
// In the example, the ||= will check if the songsCount is false (0).
// If false, then the right value will be assigned to the left variable.
let myPlaylist = {songsCount: 0, songs:[]};
myPlaylist.songsCount ||= 100;
console.log(myPlaylist); // This will print: {songsCount: 100, songs: Array(0)}
a || (a = b)
逻辑 AND 赋值运算符
// 如果左操作数为真,逻辑 AND 赋值运算符 &&= 仅将右操作数分配给左操作数
let myFiles = {filesCount: 100, files:[]};
myFiles.filesCount &&= 5;
console.log(myFiles); // This will print: {filesCount: 5, files: Array(0)}
a && (a = b)
空合并赋值运算符
// 如果左操作数为空或未定义,则空合并赋值运算符 ??= 仅将右操作数分配给左操作数。
let userDetails = {firstname: 'Katina', age: 24}
userDetails.lastname ??= 'Dawson';
console.log(userDetails); // This will print: {firstname: 'Katina', age: 24, lastname: 'Dawson'}
a ?? (a = b)
私有类方法和访问器
//默认情况下,类方法和属性是公共的,但可以使用哈希 # 前缀创建私有方法和属性。ECMAScript 2021 更新已强制执行隐私封装
class User {
constructor() {}
// The private methods can be created by prepending '#' before
// the method name.
#generateAPIKey() {
return "1111111111111";
}
getAPIKey() {
// The private methods can be accessed by using '#' before
// the method name.
return this.#generateAPIKey();
}
}
const user = new User();
const userAPIKey = user.getAPIKey();
console.log(userAPIKey); // This will print: 1111111111111
- 如何使用私有 Getter 和 Setter
class Str {
#uniqueStr;
constructor() {}
set #generateUniqueStringByCustomLength(length = 24) {
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let randomStr = "";
for (let i = 0; i < length; i++) {
const randomNum = Math.floor(Math.random() * characters.length);
randomStr += characters[randomNum];
}
this.#uniqueStr = randomStr;
}
set setRandomString(length) {
this.#generateUniqueStringByCustomLength = length;
}
get #fetchUniqueString() {
return this.#uniqueStr;
}
get getRandomString() {
return this.#fetchUniqueString;
}
}
const str = new Str();
str.setRandomString = 20;
const uniqueStr = str.getRandomString;
console.log(uniqueStr); // This will print a random string everytime you execute the Getter after the Setter.
mise((resolve, reject) => {
// After 500 miliseconds reject the second promise.
setTimeout(() => reject(“The second promise has been rejected.”), 500);
});
(async function () {
try {
const data = await Promise.any([promise1, promise2]);
console.log(data);
} catch (error) {
// If all Promises gets rejected, then this try-catch block will handle
// the aggregate errors.
console.log("Error: ", error);
}
})();
### **逻辑赋值运算符**
- 逻辑 OR 赋值运算符 ||=
- 逻辑与赋值运算符 &&=
- 空合并赋值运算符 ??=
#### **逻辑 OR 赋值运算符**
```js
// 逻辑 OR 赋值运算符 ||= 接受两个操作数,如果左操作数为假,则将右操作数分配给左操作数
// In the example, the ||= will check if the songsCount is false (0).
// If false, then the right value will be assigned to the left variable.
let myPlaylist = {songsCount: 0, songs:[]};
myPlaylist.songsCount ||= 100;
console.log(myPlaylist); // This will print: {songsCount: 100, songs: Array(0)}
a || (a = b)
逻辑 AND 赋值运算符
// 如果左操作数为真,逻辑 AND 赋值运算符 &&= 仅将右操作数分配给左操作数
let myFiles = {filesCount: 100, files:[]};
myFiles.filesCount &&= 5;
console.log(myFiles); // This will print: {filesCount: 5, files: Array(0)}
a && (a = b)
空合并赋值运算符
// 如果左操作数为空或未定义,则空合并赋值运算符 ??= 仅将右操作数分配给左操作数。
let userDetails = {firstname: 'Katina', age: 24}
userDetails.lastname ??= 'Dawson';
console.log(userDetails); // This will print: {firstname: 'Katina', age: 24, lastname: 'Dawson'}
a ?? (a = b)
私有类方法和访问器
//默认情况下,类方法和属性是公共的,但可以使用哈希 # 前缀创建私有方法和属性。ECMAScript 2021 更新已强制执行隐私封装
class User {
constructor() {}
// The private methods can be created by prepending '#' before
// the method name.
#generateAPIKey() {
return "1111111111111";
}
getAPIKey() {
// The private methods can be accessed by using '#' before
// the method name.
return this.#generateAPIKey();
}
}
const user = new User();
const userAPIKey = user.getAPIKey();
console.log(userAPIKey); // This will print: 1111111111111
- 如何使用私有 Getter 和 Setter
class Str {
#uniqueStr;
constructor() {}
set #generateUniqueStringByCustomLength(length = 24) {
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let randomStr = "";
for (let i = 0; i < length; i++) {
const randomNum = Math.floor(Math.random() * characters.length);
randomStr += characters[randomNum];
}
this.#uniqueStr = randomStr;
}
set setRandomString(length) {
this.#generateUniqueStringByCustomLength = length;
}
get #fetchUniqueString() {
return this.#uniqueStr;
}
get getRandomString() {
return this.#fetchUniqueString;
}
}
const str = new Str();
str.setRandomString = 20;
const uniqueStr = str.getRandomString;
console.log(uniqueStr); // This will print a random string everytime you execute the Getter after the Setter.
更多推荐
前端基础(不定期更新)
发布评论