- 作者:老汪软件技巧
- 发表时间:2024-12-02 21:06
- 浏览量:
简言
最近在做前端知识的复习和整理,有了一些自己新的体会。更多在于记录,通过反复的温习,写笔记消除自己以前学习知识点的误区
浏览器JS对象
JS在浏览器的运行环境中,一般由以下三部分组成
ECMAScript核心:作为JS的标准规范,描述了JS中的语法和基本对象BOM(Browser Object Model):浏览器对象模型,提供了用以控制浏览器行为的APIDOM(Document Object Model):浏览器对象模型,提供了用以编辑网页文档的接口ECMAScript核心
ECMAScript是一种由Ecma国际通过ECMA-262标准化的脚本语言规范。
ECMAScript 与 JavaScript有什么区别?名称定义规则拓展性
ECMAScript
ECMAScript是由ECMA国际标准化的脚本语言规范
ECMA提供了脚本语言必须遵守的规范,准则和细节
ECMAScript作为一种开放的,被国际广为接受的脚本语言规范,具有很大的灵活性
JavaScript
ECMAScript规范下的具体实现
JavaScript不仅具备ECMAScript的核心功能和特性,还具备与特定环境(浏览器)的交互能力
虽然JavaScript也是一种流行的脚本语言,但他基于ECMAScript的规范
BOM常见的BOM对象Navigator-浏览器系统导航信息集合判断浏览器并返回浏览器名称
以下两段代码引用于/post/706808…
const getCurrentBrower = () => {
const ua = navigator.userAgent;
let browser;
if (ua.indexOf("Firefox") > -1) {
browser = "Mozilla Firefox";
} else if (ua.indexOf("Opera") > -1 || ua.indexOf("OPR") > -1) {
browser = "Opera";
} else if (ua.indexOf("Trident") > -1) {
browser = "Microsoft Internet Explorer";
} else if (ua.indexOf("Edge") > -1) {
browser = "Microsoft Edge";
} else if (ua.indexOf("Chrome") > -1) {
browser = "Google Chrome or Chromium";
} else if (ua.indexOf("Safari") > -1) {
browser = "Apple Safari";
} else {
browser = "unknown";
}
return browser;
};
判断当前是否为移动端
const mobileFlags = [
/AppleWebKit.*Mobile.*/, // 移动终端
/\(i[^;]+;( U;)? CPU.+Mac OS X/, // ios终端
/Android/, // 安卓终端
/iPhone/, // iPhone
/iPad/, // iPad
];
const isMobile = () => {
const ua = navigator.userAgent;
for (let flag of mobileFlags) {
if (flag.test(ua)) {
return true;
}
}
return false;
};
由此我们就可以在实际开发中得知:
什么设备下,做什么设备的样式布局;什么环境下,针对当前环境进行浏览器兼容处理,统一浏览器默认行为等
经典剪切板问题
大家都知道剪切板功能可以通过以下步骤实现:
Dom获取Input对象obj.select()document.execCommand('Copy', false, null)
但是某些极端情况下(iPhone5 10.2),ios无法通过上述步骤实现剪切功能(第二步未生效),那么我们就需要针对这种特殊情况做处理
// 以下是伪代码
if(isIOSDevice){
selectRange()
try{
document.execCommand('Copy', false, null)
}
// ....
}
function selectRange() {
let obj = document.getElementById("textAreas");
// 获取元素内容是否可编辑或只读
let editable = obj.contentEditable;
let readOnly = obj.readOnly;
// 改变元素内容可编辑性和非只读
obj.contentEditable = true
obj.readOnly = false;
// 创建Range对象,Range对象表示文档的连续范围区域
let range = document.createRange()
// 获取obj作为用户选中范围
range.selectNodeContents(obj)
// 获取用户选中文本范围或光标当前位置
let selection = window.getSelection()
// 清除之前已选范围
selection.removeAllRanges()
// 添加当前已选范围
selection.addRange(range)
// 为文本元素设置文本中被选中的范围(起始位置,结束位置),这个方法用于input,textarea
obj.setSelctionRange(0, 999999)
}
经典键盘输入问题
微信小程序-iOS键盘弹出遮挡输入框
可以使用input的cursor-spacing属性
指定光标与键盘的距离,取 input 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离
location - 浏览器地址,提供获取浏览器地址信息的能力location常用方法location.replace和location.href的区别
location.href和location.replace本质上都是浏览器中的页面重定向当进行重定向的时候,浏览器会发起一个HTTP请求,通常会收到一个301或者302的状态码,这取决于服务器返回的类型,如果是返回301,表示之前资源的路径被销毁或永久移动,服务器返回了新的资源地址回来,在未来请求中会直接访问新的资源地址
而location.href在重定向完成之后会添加新的历史记录
而location.replace则是现将当前的历史记录移出,在将新的历史记录移入,完成历史记录替换
如果当前页面是C,页面是由A -> B -> C跳转的
若 B -> C用的replace,则从C返回上一个页面,则回到A
若 B -> C用的href,则从C返回上一个页面,则回到B
screen - 表示显示区域History - 网页的历史记录
window.history.pushState(stateObject, title, url)
与新历史记录关联的状态对象,title名称可以设置为null,新URL且必须与当前域名同域
window.history.replaceState(stateObject, title, url)
路由方向 history 和 hash模式的对比,不存在利弊,只存在区别展示形态不同,hash会在路径上总是展示一个#,用以描述当前的hash值,而history更贴近普通路由(给用户有一致性的感觉,因此感受更加)原理上的不同,hash改变的是锚点(使用hashChange监听),而history是改变的页面栈中栈顶的状态(使用onPopState监听)history使用时,需要后台指向一个标准的文件(匹配到了文件就读取,没有匹配到文件就回退)或者是api
// 在ngixn中
location / {
root /usr/share/nginx/html; # 静态文件目录
try_files $uri /index.html;
}
上述try_files会按照给定的文件顺序去检查文件是否存在,如果文件存在则返回文件,如果文件不存在则返回一个默认文件,上述代码$uri表示当前匹配到的pathname,/index.html表示如果pathname没有匹配到文件,则返回root路径下 /usr/share/nginx/html目录下的index.html文件,然后通过前端JS控制路由切换
如果页面白屏了,应该从哪些部分排查
打开浏览器控制台,查看日志
检查是否因为js代码语法错误导致,或是方法,变量类型不正确(一般是访问了undefined或null的属性),引用了未定义的变量或函数
网络请求
检查是否是因为请求pending或是响应404,5xx之类的错误,导致静态资源并未完全加载或加载错误
JS加载和执行
如果使用了异步加载,确认异步加载的资源都能够被正确的加载,并且需要确认JS加载的顺序是否正确,可能某些脚本并未加载完就被执行导致白屏
CSS问题
有时候白屏可能是因为设置了display: none,或者是被错误地定位到了页面外部,或者是CSS文件并未加载或者加载错误,导致白屏
构建工具
确保使用webpack等构建工具在构建输出时没有错误,或者因为意外导致文件压缩错误等
缓存问题
确保成功加载的文件都是最新的,尤其是SPA引用中,可能存在index文件更新了,但是引用的css文件以及其他脚本文件没有更新,导致白屏的错误
兼容性问题
检查是否在不同的浏览器中都出现了白屏问题,如果只是某个特定的浏览器出现白屏问题,则可能因为浏览器不支持某些Web新特性,或者是存在不兼容的特性
前端框架问题
确保路由配置是否都正确,是否存在重定向错误或者是路由路径的解析问题
后端问题
确认后端返回的是否有错误代码,或是接口调用超时,或是返回的数据不符合预期,导致前端渲染失败
Web服务器配置问题如果使用了Nginx,Apache等代理服务器,检查配置文件中是否存在问题,尤其是静态文件的路径等
总结一下就是:从三个方向查看前端与浏览器、构建与网络、后端与Web服务器
DOM事件模型
浏览器一般有三种绑定事件的方式
// 1.在HTML标签上定义
"handler">
// 2.js获取dom,将事件绑定在dom上
<div id="box1">div>
<script>
const box1 = document.getElementById("#box1")
box1.onclick = () => {
console.log('box1')
}
script>
// 3.js获取dom,并给dom添加事件监听
<div id="box2">div>
<script>
const box2 = document.getElementById("#box2")
box1.addEventListener('click', ()=>{}, false)
script>
其他用法
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Documenttitle>
head>
<style>
#divA {
width: 200px;
height: 200px;
border: 1px solid red;
}
#divB {
width: 100px;
height: 100px;
border: 1px solid green;
}
#divC {
width: 50px;
height: 50px;
border: 1px solid blue;
}
style>
<body>
<div id="divA">
<div id="divB">
<div id="divC">
<a href="https://www.baidu.com" id="aA">点我a>
div>
div>
div>
body>
<script>
const divA = document.getElementById("divA");
const divB = document.getElementById("divB");
const divC = document.getElementById("divC");
const aA = document.getElementById("aA");
divA.addEventListener(
"click",
() => {
console.log("divA");
},
false
);
divB.addEventListener(
"click",
() => {
console.log("divB");
},
false
);
divC.addEventListener(
"click",
() => {
console.log("divC");
},
false
);
aA.addEventListener(
"click",
(e) => {
// e.stopPropagation();
e.stopImmediatePropagation();
e.preventDefault();
console.log("aA-1");
},
false
);
aA.addEventListener(
"click",
() => {
console.log("aA-2");
},
false
);
script>
html>
阻止冒泡事件
e.stopPropagation()
阻止浏览器默认事件
e.precentDefault()a标签的默认事件是跳转,阻止a标签的默认点击事件后,就不会跳转了
如果相同节点上绑定了多个同类型事件Click2,Click3等,如果既要阻止事件冒泡,又要阻止除自身(Click1)外其他同类型事件(Click2, Click3)触发
e.stopImmediatePropagation()此时只触发Click1;Click2与Click3甚至上层父级节点的事件不触发