案例(面试题)
/*
1. 买卖股票的最佳时机, 给定一个数组, 他的第 I 个元素是一只股票第 I 天的价格,
如果你最多只允许完成一次交易 (也就是买入和卖出一只股票一次), 请你设计一个算法来计算你能获取到的最大的利益
注意: 你不能在购买股票前卖出股票
示例: 输入 [7, 1, 5, 3, 6, 4,]; 输出: 5
解释: 在第 2 天(当天的股票价格等于1)的时候买入, 在第5天的时候卖出(当天股票的价格等于6,
所以你最大的利润为 6 - 1 === 5
注意: 利润不能是 7 - 1 === 6, 因为第二天的价格为 1, 第一天的价格为 7,
你是不可能在第二天买入股票然后等到第一天的时候卖出)
*/
方法一
/* for(var i= 0 ){}
[7, 1, 5, 3, 6, 4,] 天数为 i
天数 1 2 3 4 5 6
i 0 1 2 3 4 5
不能 利润不能是 7 - 1 === 6, 因为第二天的价格为 1, 第一天的价格为 7,
你是不可能在第二天买入股票然后等到第一天的时候卖出)
说明 执行 只能从开始索引到末尾索引 顺序
i 买入(天数) 卖出(天数) j 利润
0 1 2 i+1 1 1(第2天)-7(第1天) ===-1
3 2 -5 -4
4 3 -3 -2
5 4 -6 -5
6 5 -4 -3
1 2 3
4
5
6
2 3 4
5
6
3 4 5
6
4 5 6
*/
/*
准备一个容器用于储存最大值
使用双重for循环
第一层循环表示 买入的天数
第二层循环表示 卖出的天数
使用if循环 变量 求 交换最大利润(最大值) = 卖出-买入
执行顺序为从开始索引到结束索引
*/
var max = 0;
// 准备一个容器用于储存最大值
// 使用双重for循环
var arr = [7, 1, 5, 3, 6, 4,];
for (var i = 0; i < arr.length - 1; i++) {
// 第一层循环表示 买入的天数
// console.log(i);
for (var j = i + 1; j < arr.length; j++) {
// 第二层循环表示 卖出的天数
// console.log('买入'+i,'卖出'+j);
if (arr[j] - arr[i] > max) {
// 使用if循环 变量 求 交换最大利润(最大值) = 卖出-买入
max = arr[j] - arr[i]
// arr[1]-arr[0] >arr[2]-arr[0]
// 2 1 3 1
}
}
}
console.log(max);
方法二
/**
* 逻辑:
* 1. 一个 for 循环, 拿到数组的每一项
* 2. 第二个 for 循环, 拿到外循环后边的所有数组的每一项
* 3. 计算后边的数据和前边的数据的最大差值
*/
var arr = [1000, 7, 1, 5, 3, 6, 4, 100]
var max = 0
// 1. 一个 for 循环, 拿到数组的每一项
for (var k = 0; k < arr.length - 1; k++) {
// 2. 第二个 for 循环, 拿到外循环后边的所有数组的每一项
for (var i = k + 1; i < arr.length; i++) {
if (arr[i] - arr[k] > max) {
max = arr[i] - arr[k]
}
}
}
console.log(max)
BOM本地存储
- storage
- localStorage
- 浏览器本地存储持久存储,一旦存储永久存在
- 只能存储基本数据类型(一般就是字符串),如果其他数据类型存储必须转换为字符串能够跨页面通讯
- 例如:我在A页面存储,但是在网页面能够获取到,那么就是跨页面通讯
- sessionStorage
- 浏览器本地存储,临时存储,关闭浏览器以后,在储内容自动消失
- 如果要跨页面通讯,必须是从本次页面跳转的才可以打开
- 增; 删; 清除; 获取; 和 localStorage 一样
- 新增一个本地存储
- window.LocalStorage.setItem(key,vaLue)
- key 相当于变量名,vaLue 你真正要存储的值
- 删除一个本地存储
- window.localStorage.removeItem(key)
- 你要删除哪一个本地存储,就把这个key写成哪一个
- 清空一个本地存储
- window.localStorage.clear()
- 查询一个本地存储的值 返回值: 查询到: 把这个key对应的value返回出来 没有查询到: 返回一个null
- 存储引用数据类型(数组---对象)
- localStorage
错误存储方式:
错误存储数组
var arr = [1, 2, 3, 4, 5]
window.localStorage.setItem('arr', arr)
var res = window.localStorage.getItem('arr')
console.log(res)
错误存储对象
var obj = {
name: 'QF001',
age: 18
}
window.localStorage.setItem('obj', obj)
var res = window.localStorage.getItem('obj')
console.log(res)
window.localStorage.setItem('wx', '12345');
window.localStorage.setItem('qq', '123156');
window.localStorage.getItem();
JSON
- 在 JS 中 有一个对象叫做 JSON, 她提供了两个方法
- JSON.stringify(传入要转换的数据) 能够将其它类型的数据, 转换为 JSON 格式的字符串
- JSON.parse(传入要转换的数据) 能够将 JSON 格式的字符串, 转换为 原本的数据类型
var obj = {
name: 'QF001',
age: 18
}
var newObj = JSON.stringify(obj)
var arr = [1, 2, 3, 4, 5]
var newArr = JSON.stringify(arr)
// console.log(obj)
// console.log(newObj)
// console.log(arr)
// console.log(newArr)
window.localStorage.setItem('arr', newArr)
window.localStorage.setItem('obj', newObj)
var arr1 = JSON.parse(window.localStorage.getItem('arr'))
var obj1 = JSON.parse(window.localStorage.getItem('obj'))
console.log(arr1)
console.log(obj1)
<h1>我当前页面没有做任何本地存储, 但是我能够获取到其他的本地存储</h1>
<script>
// 1. 获取本地存储的内容
var res1 = window.localStorage.getItem('arr')
var res2 = window.localStorage.getItem('obj')
console.log(res1);
console.log(res2);
var res3 = window.sessionStorage.getItem('QQ')
console.log(res3);
</script>
cookie
注意事项
1. 只能存储字符串,并且有固定的格式 key==value a==100 qq=888
2. 存储大小有限制 4kb左右
3. 操作 cookie 必须依赖服务器(本地启动文件不能运行cookie)
目前可以借助vscode 的插件 live server
4. 跟随前后端交互,自动携带
将来我们前端向后端发送请求的时候, 如果 cookie 内有数据, 那么会自动携带
5. 前后端操作
前端: JS; 后端: 任何一个后端语言都可以操作cookie
6. 存储依赖域名
哪一个域名存储, 哪一个域名能够使用, 不能跨页面通讯
- cookie 的有效期
- 默认是会话级别(浏览器关闭, 自动删除), 我们也可以手动的添加一个过期时间
- 我们在设置时间的时候 是按照世界标准时间走的
- 但是我们的时间是东八区时间, 所以在处理的时候, 应该先将这个时间往后调整 8 小时
cookie 和 storage 的区别(面试题)
- 出现时间: cookie 有js的时候就存在了 storage H5出现以后才出来
- 存储大小: cookie 4kb storage 20MB/5MB
- 前后端交互 cookie 请求时自动携带 storage 请求时不会自动携带,可以手动携带
- 前后端操作 cookie 前端后端都可以操作 storage 只有前端 JS 能操作
- 过期时间 cookie 默认会话级别, 但是可以手动设置过期时间 storage 不能手动设置过期时间
localStorage和sessionStorage的区别(面试题)
- 过期时间 localStorage: 永久存储 sessionStorage: 临时存储
- 跨页面通讯 localStorage: 直接跨页面通讯 sessionStorage: 只能是从当前窗口跳转过去的页面才可以通讯
- 共同点 => 只能存储字符串, 不能存储复杂数据类型 => 直接存储其他数据类型, 获取回来的也是字符串类型
cookie代码解析
// 设置一条 cookie
// document.cookie = 'QQ=12345'
// document.cookie = 'WX=15619'
// // 获取cookie
// console.log(document.cookie);
// 设置一条过期的cookie
var timer = new Date()
document.cookie = 'QQ=12345;expires=' + timer
console.log(document.cookie);
// expires 有效期为
// 设置一条 30S 后过期的 cookie
var time1 = new Date();
// 当前时间的毫秒数 - 8小时的毫秒数 + 指定过期时间的毫秒数
// === timer.getTime() - 1000 * 60 * 60 * 8 + 30 * 1000
time1.setTime(time1.getTime - 8 * 60 * 60 * 1000 + 2 * 1000)
// time1.setTime 设置当前毫秒数
document.cookie = 'QQ=12345;expires=' + time1
setTimeout(function () {
console.log(document.cookie)
}, 4000)
// 当2秒结束后到4s结束后打印内容
DOM
- 获取页面的常规元素
- DOM 文档对象模型 其实就是一些操作HTML节点
- 获取一个元素(标签/节点/DOM节点)移除一个元数
- 创建一个元素
- 给页面中添加一个元素
- 给元素绑定一下事件(单击事件,双击事件。键盘按下事件....)获取元系的一些属性
- 获取元系的Css样式
- 给一个元素添加cSs样式
- DOM的核心就是document对象
- document对象是浏览器内置的一个对象,里面存储着专门用来操作元素的各种方法
// 1.打印整个html里面的内容
console.log(document);
var htmlEle = document.documentElement
console.log(htmlEle);
//2.打印整个head内容
var headEle = document.head
console.log(headEle);
//3.打印整个body标签里面的内容
var bodyEle = document.body
console.log(bodyEle);
// 获取 id 标签内容
var idEle = document.getElementById('test');
console.log(idEle);
// 获取id名为'test'的标签内容
// console.log(id_box);// 这是一个错误写法,不允许使用
// 1. 通过元素的 ID 名获取标签
// 在 JS 中有一个不规范的写法, 这是一种错误写法
// 一个标签的 ID 名, 在 JS 中, 可以直接当作一个变量使用
//通过元素的class名获取 class 标签内容
var classELe = document.getElementsByClassName('box1')
console.log(classELe); // 打印的是伪数组
console.log(classELe[1]);//<div class="box1"></div>
注意:
1. getElelemt s ByClassName
2. 获取到的元素, 放在了一个长得很像数组的数据结构内
我们可以通过下标去获取到准确的 DOM节点, 也可以通 length 知道获取了多少个元素
但是数组的一些方法不能使用, 比如 forEach, map....
我们给这个数组起了个名字叫做 伪数组
//通过元素标签获取 标签/元素内容 (tag)
var tag = document.getElementsByTagName('div');
console.log(tag);// 打印的是伪数组
// 没有返回 HTMLCollection []
// 返回 打印其内容
// name
var nameEle = document.getElementsByName('box2');
console.log(name);//伪数组
// querySelector
/* 4. 类似 css 选择器的方式获取标签
获取到的是页面中第一个符合要求的标签
*/
var new_div_box = document.querySelector('div')
var new_div_box = document.querySelector('.box1')
console.log(new_div_box)// 注意这是返回的是标签,不是内容
/*
* 5. 获取到页面中所有符合要求的 标签
*
* 也是一个伪数组的形式, 但是能使用 forEach
*
* 个人建议, 使用伪数组的时候, 不要使用数组的方法
* 最好的方式将这个伪书组转换成真实数组
*
* var arr = [...伪数组]
*/
var new_div_box = document.querySelectorAll('div')
var new_div_box = [...document.querySelectorAll('div')]
console.log(new_div_box)
操作元素
获取到DOM 节点 之后可以直接操作,节点的属性,并直接渲染的页面
*/
// 0. 获取元素
var box0 = document.querySelector('.box1');
var id_b = document.getElementById('id_box');
// 1.innerhtml 获取标签内部的结构
console.log(box0.innerHTML);
//设置的时候能够解析字符串中的 html 标签
id_b.innerHTML = '<p>26615159</p>';
//26615159
// 2. innerText 获取元素内部的文本 (也就是说获取不到 html 标签)
// console.log(boxO.innerText)
console.log(id_b.innerText);//26615159
// 设置的时候会将字符串的所有内容添加到标签的文本区, 字符串中哪怕是写了标签, 他也不认识
id_b.innerText = '<p>26615159</p>'
// <p>26615159</p>
// 3. 获取元素的某个属性 (包括自定义属性)
console.log(id_b.getAttribute('a')) //1316
// getAttribute 获取到当前标签的这个属性对应的值
console.log(id_b.getAttribute('id'))//id_box
// getAttribute 获取到当前标签的这个属性对应的值
// 4. 设置元素的某个属性
id_b.setAttribute('my_box', 'QF001') // 新加一个属性
id_b.setAttribute('a', 'QF666') // 修改原有的属性
// 5. 删除元素的某一个属性
boxT.removeAttribute('a') // 将这个标签的属性a, 删除
获取标签
<body>
<div class="box box_t" num="100" data-id="QF001" data-xbox="QF002">
这里展示的是一个商品
</div>
<script>
var bo_x = document.getElementsByClassName('box')[0];
//获取标签
/*
1. H5 自定义属性
属性名是 data- 后边的内容
如果一个 H5 自定义属性写为: data-id="QF001"
属性名: id
属性值: 'QF001'
data- 的作用仅仅表示这是一个 H5的自定义属性
*/
// 1. 增加 节点.dataset.要新增的属性名 = '对应的属性值'
console.log(bo_x);
// 在打印的时候 也打印出来 name='张三'
bo_x.dataset.name = '张三';
console.log(bo_x); //会增加 name = '张三'
// // 2. 删除
delete bo_x.dataset.id
// // 3.获取
console.log(bo_x.dataset.xbox);// QF002 // 为字符串
// /**
// * 2. style
// * 专门用来给某个元素添加 css 样式
// * 添加的样式是行内样式
// */
bo_x.style.width = '100px'
bo_x.style.height = '100px'
bo_x.style.backgroundColor = 'blue'
/**
* 3. className
*
* 专门用于操作元素类名; 设置类名的时候, 不管之前有多少个, 直接全部覆盖
*
* classList
* 也是用于操作元素类名的, 具有一些方法, 如下所示
*/
bo_x.className = 'new_box'
console.log(bo_x.className)
// 新增一个类名
bo_x.classList.add('new_box')
console.log(bo_x.classList)
// 删除一个
bo_x.classList.remove('new_box')
console.log(bo_x.classList)
</script>