1、什么是同源策略
同源策略是一种用于网页安全的基本原则,它定义了浏览器如何限制一个文档或脚本如何与
另一个源的文档或脚本进行交互的规则。
所谓“同源”是指,两个网页具有相同的协议(即http或https)、域名和端口号。
这意味着,如果一个页面加载了来自其他源的文档、脚本或其他资源,
浏览器将会根据同源策略去限制这些资源对当前页面的访问权限。
同源策略的目的是防止恶意攻击者利用跨站点脚本攻击(XSS)等技术,
从其他网站窃取用户数据或执行恶意代码。同时,同源策略也保障了用户隐私和数据安全。
2、你要如何处理同源策略,后端又该怎么做
-
跨域代理:前端发送跨域请求到自己的服务器端,然后服务器端将请求转发到目标服务器,
拿到数据后返回给前端。这样前端和后端都可以通过服务器中间层来实现跨域请求,
从而避免浏览器的同源策略限制。 -
JSONP:前端可以使用JSONP来实现跨域请求。在前端页面中定义一个回调函数,
携带着回调函数的名称,发出跨域请求。目标服务器在返回数据时,将数据包装成回调函数的调用,
并把数据当做参数传入。前端页面获取到该响应后,通过回调函数对返回数据进行处理。 -
CORS:后端服务器通过设置响应头(Access-Control-Allow-Origin)来允许跨域请求,
但是,使用CORS也存在安全风险。攻击者通过设置Access-Control-Allow-Origin字段,
可以窃取用户的敏感数据。因此,开发人员需要谨慎使用CORS,仅允许来自受信任的域名发送请求;
以上方法均可在前后端配合下实现绕过同源策略限制,这要求前端和后端工作效率的整合,达到相应的服务设计和开发目的。
3、什么是闭包,它的好处和坏处是什么,举例说明
闭包(Closure)是指函数可以访问外部函数(包含嵌套函数)的变量,即使外部函数已经返回,该变量仍然存在于内存中。
闭包的好处:
-
保护私有变量:闭包允许我们在函数内部创建一个闭合的作用域,可以保存一些外部无法访问的变量,从而保护这些私有变量。
-
实现高阶函数:闭包可以作为高阶函数的参数和返回值,从而实现比较灵活的编程方式。
-
缓存值:利用闭包可以缓存函数的结果,可以提升函数的执行效率,减少代码的冗余。
闭包的坏处:
-
占用内存:闭包保存了外部函数的作用域,包括变量和函数对象,如果不及时释放内存,会导致内存泄漏。
-
可能造成变量污染:如果不小心在内部函数中重复定义外部函数的变量名,会导致变量污染,影响代码可读性和维护性。
-
容易造成性能问题:因为闭包会创建多个嵌套作用域,所以会增加函数的执行时间和内存使用量。
以下是一个使用闭包的例子,用于实现计数器功能:
function counter() {
let count = 0;
return function () {
return ++count;
};
}
const c = counter();
console.log(c()); // 输出1
console.log(c()); // 输出2
console.log(c()); // 输出3
在上面的代码中,函数counter返回了一个内部匿名函数,这个匿名函数引用了外部函数的变量count,
形成一个闭包,每次执行匿名函数都会使count加1,实现了计数器的功能。由于闭包的存在,
即使函数counter已经执行完毕,变量count仍然可以在内存中保存下来,并且可用。
4、基本的两列自适应布局
基本的两列自适应布局可以使用CSS中的float布局或Flexbox布局来实现。
- Float布局:
HTML代码:
<div class="main">
<div class="sidebar">
<!-- 侧边栏内容 -->
</div>
<div class="content">
<!-- 主要内容 -->
</div>
</div>
CSS代码:
.main {
width: 100%;
height: auto;
margin: 0;
padding: 0;
}
.sidebar {
width: 25%;
float: left;
}
.content {
width: 75%;
float: left;
}
以上代码中,将容器宽度设置为100%,侧边栏占25%宽度,主要内容占75%宽度。
通过float:left使侧边栏和主要内容在同一行上,且主要内容会占据剩余的空间。
- Flexbox布局:
HTML代码:
<div class="main">
<div class="sidebar">
<!-- 侧边栏内容 -->
</div>
<div class="content">
<!-- 主要内容 -->
</div>
</div>
CSS代码:
.main {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
}
.sidebar {
width: 25%;
}
.content {
width: 75%;
}
以上代码中,将容器设置为flex布局,并指定了主轴和交叉轴方向为横向,侧边栏占25%宽度,主要内容占75%宽度。
flex默认为左对齐,所以主要内容会占据剩余的空间。
5、什么是递归,好处是啥,坏处是啥?
递归指一个函数调用自身的过程。
递归的好处在于可以简化程序逻辑,让代码更加简明易懂,同时也能解决一些传统方法难以处理的问题,比如树的遍历和排序等。
递归的坏处在于可能导致运行效率低下,同时也有栈溢出等风险。
例如,下面是一个递归函数用于求阶乘:
function fact(num) {
if (num <= 1) {
return 1;
} else {
return num * fact(num - 1);
}
}
这个函数通过不断调用自身来计算n的阶乘。虽然简便易行,但当输入的数字很大时,将会引起栈溢出的问题,
需要优化算法来避免此类问题的发生。
如果这样使用,会出错
var anotherFact = fact;
fact = null;
alert(antherFact(4)); //出错
由于fact已经不是函数了,所以出错
用arguments.callee
可解决问题,这是一个指向正在执行的函数的指针,arguments.callee
返回正在被执行的对现象。
新的函数为:
function fact(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1); //此处更改了。
}
}
var anotherFact = fact;
fact = null;
alert(antherFact(4)); //结果为24.
arguments.callee
是一个指向当前正在执行的函数的指针。它可以用来实现匿名递归函数,
或者在一个函数内部定义一个可以递归调用本身的函数。
在这个例子中,我们使用了一个匿名函数来计算阶乘,并在函数内部使用 arguments.callee
参数来递归调用本身来计算结果。
这个方法可以避免给函数指定一个固定的名称,从而使代码更加简洁。
但是需要注意的是,严格模式下,使用 arguments.callee
是不被允许的。
6、对前端路由的理解?前后端路由的区别?
前端路由(即客户端路由)是指利用浏览器提供的 History API 或 Hash(URL 中的 # 符号)
来实现单页应用(SPA)的页面切换和 URL 路由机制。通过实现前端路由,
SPA 应用可以动态地根据 URL 变化切换不同的页面,无需发送新的 HTTP 请求到服务器。
这种方式可以提高用户体验,避免了因为页面间的跳转导致的页面刷新时的白屏、闪屏等问题。
与前端路由不同,后端路由(即服务端路由)是指请求经过服务器端的路由控制器进行分发处理。
在传统的多页应用(MPA)中,每个页面对应一个特定的 URL 地址,页面之间的转换需要向服务器发送请求,
以获取新的页面内容。每个请求由服务器端的路由控制器来分配对应的处理函数,
然后处理函数返回 HTML 页面等资源,最终呈现给用户。
前后端路由最大的区别在于处理请求的位置不同。前端路由的请求处理在客户端本地完成,
而后端路由的请求处理则是通过向服务器发送请求并在服务器端进行处理。
这意味着使用前端路由的应用可以在保持与服务器连接的同时,在本地频繁切换页面。
相反,对于后端路由,页面的内容要从服务器端获取,因此会产生相对较长的请求处理和响应时间,给用户带来较为明显的延迟。
7、介绍一下webpack和gulp,以及项目中具体的使用
Webpack
和 Gulp
都是前端构建工具,用于自动化拉取、合并、压缩和优化资源文件等操作。
它们都可以帮助前端开发者提高开发效率和项目质量。
Webpack
是一款现代化的构建工具,它通过配置文件定义了一个模块的依赖图,将文件转化为模块,
并进行合并,压缩,优化等操作。它最显著的特点就是支持模块化开发、代码分割,并支持各种预编译工具,
比如 Babel、TypeScript、Less、Sass
等。在项目中,
我们可以使用 Webpack
将所有的 JavaScript、CSS 和图片
等资源打包,然后通过打包后的文件交付给服务器进行加载。
Gulp
是一款基于流的自动化构建工具,它和 Webpack
一样也可以将不同的文件资源进行合并、压缩、优化等操作。
但不同的是,Gulp
的一个任务(task)就像“流水线”一样,将文件源流经过一系列的处理管道(pipe)最终转换为目标文件。
它的特点是快速、流程化,对于一些纯粹的构建工作非常适用。
在项目中,我们可以利用 Gulp
用来压缩和优化图片、CSS、JavaScript
等资源文件,并根据需求来定制相应的任务。
在实际项目中,Webpack
和 Gulp
都是可以同时使用的。
常见的前端工程化框架比如 Vue、React、Angular
都是基于 Webpack
进行构建,而像一些纯粹的页面开发项目,
我们可以使用 Gulp
来自动编译处理 Sass/Less 和 JavaScript
文件等。
此外,我们可以使用 Webpack
的外部工具(externals)、Gulp 的文件流和插件处理等技术手段,
将二者有机地结合在一起,以确保项目的高效、可维护性和可用性。
8、使用css实现一个三角形
可以使用CSS的border属性来制作三角形。以下是一个例子:
HTML:
<div class="triangle"></div>
CSS:
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid blue;
}
在这个例子中,我们将一个div元素的宽度和高度都设置为0,并使用border属性来设置三角形的形状和颜色。
具体来说,我们将左边框和右边框设置为透明,并将右边框设置为50px的蓝色,形成了一个向上的三角形。
你可以根据自己的需要调整这些值来制作不同形状和颜色的三角形。
9、用promise手写ajax
下面是一个用Promise手写的基本的AJAX请求:
function ajax(url, method, data) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function() {
if(xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(`Request failed with status ${xhr.status}`);
}
}
xhr.onerror = function() {
reject('Request failed');
}
xhr.send(data);
});
}
这个函数的参数是请求的URL,请求的方法和要发送的数据(可选)。
它返回一个Promise对象,在响应成功时将解析为响应文本,否则将拒绝并提供失败信息。
10、手写深浅拷贝
浅拷贝
JSON 对象:
JSON.parse(JSON.stringify(a)) // a 只能是扁平对象
//不能拷贝 function,会直接丢弃
//如果只有一级属性,则就是深拷贝
//如果一级属性里面有引用数据类型,则这个只是浅拷贝了
参数:target--->目标对象
source--->源对象
返回值:target,即目标对象
Object.assign(target,source)
例: Object.assign({},a)
/* for in 递归拷贝会将 原型上的属性方法全部拷贝过来 */
for in 递归拷贝:
function clone(source) {
let target = source instanceof Array ? [] : {}
for (let key in source) {
if (typeof source[key] === 'object') {
target[key] = clone(source[key])
} else {
target[key] = source[key]
}
}
return target
}
/**
* 深拷贝
* @param {Object} obj 目标对象
* @returns {Object} 深拷贝后的对象
*/
export function deepClone(obj) {
if (!obj || typeof obj !== 'object') {
return obj;
}
if (obj instanceof RegExp) {
return obj;
}
const result = Array.isArray(obj) ? [] : {};
Object.keys(obj).forEach((key) => {
if (obj[key] && typeof obj[key] === 'object') {
result[key] = deepClone(obj[key]);
} else {
result[key] = obj[key];
}
});
return result;
}
11、jquery绑定click的方法有几种
jquery绑定click的方法有3种:
- .click() 方法:直接将一个函数作为参数传递给.click()方法。
例:
$("#myButton").click(function(){
alert("按钮被点击了");
});
- .on() 方法:使用.on()方法,可以绑定多个事件处理函数。并且可以动态添加事件。例如,可以在文档加载后添加一个新的元素,并为它绑定事件。
例:
$("#myButton").on("click", function(event){
alert("按钮被点击了");
});
- .bind() 方法:.bind()方法可以绑定多个事件处理函数。但是,.bind()方法已经废弃,不再被新版本的jquery支持,建议使用.on()方法代替。
例:
$("#myButton").bind("click", function(event){
alert("按钮被点击了");
});
12、移动端适配问题
移动端适配是指将网站或应用程序设计成适合在移动设备上浏览的界面大小和外观。为了解决移动端适配问题,可以采用以下方法:
-
使用响应式设计:网站能够基于设备大小和分辨率,自动调整其布局和元素的大小。
-
使用流式布局:页面布局能够适应不同屏幕尺寸的需求,防止滚动条出现。
-
使用百分比或rem等单位:针对不同分辨率,不同的屏幕大小等,设置百分比或者rem作为单位,使元素大小与屏幕大小保持一定比例。
-
限制字号:在设计页面时,应该限制文字字号的大小,以确保字体在较小的屏幕上可读。
-
优化图片大小:图片文件应该被压缩到较小的文件大小,以确保在较慢的网络下加载速度快。
-
去除闪烁问题:尽量去除在移动端设备下出现的页面闪烁的问题。
综上所述,移动端适配问题的解决可以通过使用响应式设计、流式布局、百分比或rem等单位、限制字号、优化图片大小等方法来实现。
13、如何优化网站
网站优化是指通过各种技术手段和策略,提高网站的用户体验、流量、转化率等各方面的表现。以下是一些优化网站的方法:
-
提高网站速度:优化页面加载速度是提高用户体验的关键。可以通过压缩图片和代码、优化CSS/JS、缓存静态文件、使用CDN等方式来加速网站加载速度。
-
优化网站结构:良好的页面结构和代码架构可以提高页面的渲染效率和搜索引擎的可读性,从而带来更好的用户体验和更高的排名。
-
加强安全性:为网站安装 HTTPS 证书和应用其他安全措施,例如程序过滤、多重身份验证、定期备份等,可以提高网站的安全性。
-
提高网站内容质量:一个高质量的网站需要有有用的、有深度的内容,内容应该是针对受众群体进行研究和编写的。
-
优化用户体验:优化网站的交互设计,提高用户友好性,提供用户自定义体验,以及交互式和富媒体内容,可以增强用户的参与感和满意度。
-
实施SEO策略:优化网站SEO,提高网站排名,可以通过关键字研究、优化Meta标签、URL规范等方式来扩大您的受众群体。
-
应用分析:使用结构化数据、Google Analytics、A/B测试等,来了解受众行为和网站效果,优化网站体验和品牌拓展。
综上所述,网站优化是一个长期的、持续性的过程,需要进行不断的技术和策略更新,以确保提高网站的用户体验、流量和转化率等各方面表现。
14、问做过啥项目,用到什么技术,遇到什么困难,怎么解决
做过的项目非常多,以下是我举几个例子:
好的,我愿意详细回答你的问题。以下是我参与的一些项目,涉及到的技术和解决问题的方法:
-
社交平台:我们在一个社交平台上开发了许多功能,我主要使用了React、Redux、Bootstrap和Sass技术。在该项目中我们最大的挑战是性能的问题,网站加载速度较慢。为了解决这个问题,我首先使用webpack进行了优化,并且使用了代码分割来加快页面加载速度。另外,我们使用了React的PureComponent来减少不必要的组件渲染,并且在Redux中将常用的数据存储在内存中。
-
资讯平台:我们也开发了一个资讯平台,使用了Vue.js、Element UI和Axios技术。在这个项目中,我们遇到了一些REST API设计和响应式布局的问题。为了解决后者,我们使用了Flexbox和MediaQueries进行响应式布局,并且使用了一些钩子来优化Vue.js的性能。解决前者的问题,我们遵循RESTful API的规范,并使用Axios提供的拦截器来处理请求和响应。
-
电商平台:该项目使用了React、React Router、Redux、Ant Design和Webpack技术,我们在解决这个项目中的问题时,遇到了一些复杂的组件的设计和状态管理的问题,其中最大的挑战是购物车模块的开发。为了解决这个问题,我们使用了Redux来存储购物车的相关数据,并在组件中使用了Redux的connect方法来处理数据。使用这种设计模式,我们可以方便地将state和actions分离,并且可以管理多个状态。
总体来说,我在这些项目中得到了很多经验,提高了代码编写能力和问题处理能力。我相信在未来的工作中,我可以更好地利用所学知识为公司的项目做出更大的贡献。
15、盒子模型
盒子模型是CSS布局中的基本概念,用于描述HTML元素在页面上的尺寸计算方式。
每个HTML元素都被视为一个矩形盒子,由四个部分组成:内容区(content)、内边距区(padding)、边框区(border)和外边距区(margin)。如下所示:
+---------------+
| margin |
| +-----------+|
| | border ||
| | +-------+||
| | | padding|||
| | | |||
| | +-------+||
| +-----------+|
| content |
+---------------+
其中,content指的是元素内部的内容区域,它的大小由元素本身的width和height属性决定。
padding指的是内容和边界区之间的空白区域,它的大小可以通过padding属性来设置。
border指的是盒子的边界,它的大小可以通过border属性来设置。
margin指的是边框和外部元素之间的空白区域,它的大小可以通过margin属性来设置。
在CSS中,box-sizing属性指定了盒模型的计算方式,主要有两种计算方式:
-
content-box(默认值):元素的width和height属性只包含内容区域的大小,不包含内边距、边框和外边距。
-
border-box:元素的width和height属性包含内容区域、内边距、边框的大小,不包含外边距。
例如,如果一个元素的宽度为100px,内边距为10px,边框为2px,外边距为5px,那么在content-box计算方式下,该元素的实际宽度为100+10+2=112px,在border-box计算方式下,该元素的实际宽度为100px。
16、Array的unshift() method的作用是什么?如何连接两个Array?如何在Array里移除一个元素?
Array的unshift()方法的作用是将一个或多个元素添加到数组的开头,并返回修改后数组的新长度。
连接两个Array可以使用concat()方法。该方法将两个或多个数组连接起来,并返回一个包含所有元素的新数组。
例如:
let arr1 = [1, 2, 3]; let arr2 = [4, 5, 6];
let arr3 = arr1.concat(arr2); // [1, 2, 3, 4, 5, 6]
移除一个元素的方法有多种。可以使用splice()方法来删除元素。
例如:
let arr = [1, 2, 3, 4, 5];
arr.splice(2, 1); // [1, 2, 4, 5]
这将删除数组arr中索引为2的元素(即数字3)。splice()方法接受两个参数,第一个参数表示要删除元素的起始位置,第二个参数表示要删除的元素个数。也可以使用filter()方法来创建一个不包含指定元素的新数组。
例如:
let arr = [1, 2, 3, 4, 5];
arr = arr.filter(elem => elem !== 3); // [1, 2, 4, 5]
这将创建一个不包含数字3的新数组。
17、前端安全方面有没有了解?XSS和CSRF如何攻防?
前端安全是一个重要的话题,其中包括诸如XSS(跨站脚本攻击)和CSRF(跨站请求伪造)等安全问题。
XSS攻击是指攻击者将恶意脚本注入到Web页面中,使得用户在进行常规操作时执行该脚本,从而达到攻击的目的。为防范XSS攻击,可以采用以下策略:
-
对用户输入做必要的转义。例如,HTML中的特殊字符(例如<、>)应该使用对应的HTML实体(例如<、>)来表示。
-
使用CSP(内容安全策略)来限制页面中可执行的脚本和资源。CSP允许您指定哪些域名可以加载脚本、样式表和图像等资源,有助于防止恶意注入脚本攻击。
-
使用HttpOnly属性来禁止JavaScript访问cookie,从而防止cookie被窃取。
CSRF攻击是指攻击者利用用户在已登录的网站上执行操作时,使用已认证的账户来执行非意愿的恶意活动。为防范CSRF攻击,可以采用以下策略:
-
在执行敏感操作(例如更改密码、删除用户)时使用附加码。附加码是一种随机生成的令牌,用于验证该请求是用户发出的仍然有效。
-
在cookie中设置SameSite属性,这可以帮助防止某些类型的CSRF攻击。将该属性设置为"strict",可以防止针对所有请求的CSRF攻击,而将其设置为"lax",则只防止非安全HTTP请求。
-
在服务器端采用验证操作的机制,例如检查引用头等,以确保请求来自有效的来源。
总之,在前端安全方面,需要对输入数据进行处理,限制代码的执行,以及谨慎处理cookie和跨站点请求。
18、做一个两栏布局,左边fixed width,右边responsive(自适应网页)
提供一个示例代码。你可以在这个基础上进行修改和优化:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Left fixed, right responsive layout</title>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
.container {
display: flex;
}
.left {
width: 250px;
background-color: #f1f1f1;
padding: 10px;
}
.right {
flex: 1;
padding: 10px;
}
@media screen and (max-width: 640px) {
.container {
flex-wrap: wrap;
}
.left {
width: 100%;
order: 2;
}
.right {
width: 100%;
order: 1;
margin-bottom: 20px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="left">
<h2>Left column</h2>
<p>This column has a fixed width of 250px.</p>
</div>
<div class="right">
<h2>Right column</h2>
<p>This column is responsive and will take up the remaining space.</p>
</div>
</div>
</body>
</html>
注:在这个例子中,我们使用 Flexbox 和媒体查询来对左边的元素设置固定宽度,并对右边的元素设置自适应宽度。在视口宽度小于或等于 640px 时,我们将左边的元素的宽度设置为 100% 并调整元素的顺序,使其出现在右边的元素下面。
解读CSS的@media与@media screen 点我
19、css:两个块状元素上下的margin-top和margin-bottom会重叠。啥原因?怎么解决?
两个块状元素上下的margin-top和margin-bottom会重叠的原因是由于margin折叠的特性。
margin折叠是指当相邻的两个元素都设置了margin-top或margin-bottom时,这些margin将会合并(或折叠)成一个margin。具体来说,当相邻的两个元素中间没有任何的内容(例如空格、换行、行盒等)或padding、border、inline元素等隔断时,它们的上下margin将会重叠。
避免margin重叠的方法可以归纳为以下方法:
-
为相邻的元素之间添加间隔,例如添加一个空格或者换行符,或者在相邻元素间添加一个空白的元素,如果缺少可插入的元素,则可以使用 “:before” 或 “:after” 伪元素;
-
为其中一个元素添加一个padding或者border,这样就可以阻止margin重叠;
-
为其中一个元素添加一个额外的空的块级元素,并为这个块级元素添加padding或者border,同样可以阻止margin重叠;
-
为其中一个元素添加一个固定高度的空的块级元素,可以保证margin不会重叠,但是需要考虑高度的自适应问题;
-
对于父元素和子元素之间的margin重叠,可以将margin改为padding,或者将父元素设置为inline-block或者table元素,子元素则是block元素;
-
根据不同的布局特点、需求、兼容性和可维护性,采用不同的方法来避免margin重叠,比如使用flexbox或者grid布局,或者使用定位或者浮动等方法。
总之,避免margin重叠的方法很多,我们需要根据具体情况综合考虑,选择最合适的解决方案。
20、Cookie 是否会被覆盖,localStorage是否会被覆盖
Cookie和localStorage都是浏览器存储数据的方式,它们存储在客户端(浏览器)中,不会被服务器覆盖。
Cookie可以设置过期时间,当过期后,浏览器会自动删除它们。但是,应注意浏览器及用户可以手动删除Cookie。
而localStorage没有过期时间,除非用户手动删除,否则数据就一直存在浏览器中。在使用localStorage时,如果存储的键名或键值与已有的重复,会覆盖原来的值。
21、输入URL后发生了什么?
在输入URL后,通常会发生以下操作:
-
DNS解析:将URL主机名转换为IP地址。如果域名不在DNS缓存中,则将查找DNS服务器,并将结果缓存以供以后使用
-
TCP连接:浏览器通过TCP连接向服务器请求资源。这通常涉及与服务器三次握手以建立连接
-
发送HTTP请求:浏览器向服务器发送HTTP请求,该请求包括请求方法(例如GET,POST),请求的URL,HTTP版本以及请求头部信息等
-
服务器处理请求并返回HTTP响应:服务器收到请求后,将根据请求方法等来处理并读取要返回的资源。服务器将响应头部信息与有用的内容(如HTML,CSS,JavaScript文件,图像和视频等)一起返回
-
浏览器处理响应并加载页面:浏览器收到服务器返回的HTTP响应后,将根据响应头部信息和内容类型来处理响应。如果响应是HTML,则浏览器将解析HTML并构建DOM树;如果响应包含CSS和JavaScript文件,则浏览器将会加载和解析这些文件
-
断开TCP连接:一旦浏览器完成了页面加载,它将通过TCP连接通知并关闭与服务器的连接。
总体来说,浏览器向服务器发送请求获取资源,服务器响应请求并返回资源,浏览器接收响应并解析内容。
22、浮动的原理以及如何清除浮动
浮动是CSS中一种常见的布局技术,在元素浮动后,其周围的其他元素会围绕其进行布局。浮动元素不再占据父元素的空间,因此可能会覆盖父元素的其他内容。浮动元素的原理是将元素的布局漂浮在其周围的其他内容之上,从而使元素的位置发生变化。
以下是一个被浮动元素影响的例子:
HTML代码:
<div class="container">
<div class="box"></div>
<div class="content">这是一段文字内容,浮动元素对我造成了一定影响。</div>
</div>
CSS代码:
.container {
width: 800px;
margin: 0 auto;
}
.box {
float: left;
width: 200px;
height: 200px;
background-color: #eee;
}
.content {
margin-left: 220px;
background-color: #f5f5f5;
padding: 10px;
}
上述代码中,一个带有块级元素.box和文本内容.content的容器被放置在浮动元素.box的左侧。由于.box元素设置了float:left,.content元素会产生文本环绕的效果,但同时也受到了浮动元素的影响。由于.box元素脱离了正常的文档流并浮动在文本之上,.content元素的左侧margin不再受到.box元素的影响。因此,需要在.content元素后面添加一个.clearfix元素,清除浮动所带来的影响。可以通过使用以下CSS代码来解决这个问题:
.clearfix::after {
content: "";
display: table;
clear: both;
}
并将其添加到HTML代码中的末尾,如下:
<div class="container">
<div class="box"></div>
<div class="content">这是一段文字内容,浮动元素对我造成了一定影响。</div>
<div class="clearfix"></div>
</div>
这样做可以清除浮动带来的影响,.content元素就能够正常地显示了。
在前端中,浮动是CSS中的一种常见的布局方式,通常使用float属性实现。当一个元素设置了float属性时,该元素就会脱离普通文档流并漂浮在其他内容之上,其他内容会围绕其布局。一些常见情况下使用浮动的场景有:
-
实现多栏布局:通过将多列元素设置为浮动,使得它们排列在同一行或同一列,实现页面布局的目的。
-
实现文字环绕图片效果:将图片设置为浮动,使得文字可以环绕图像周围而不被覆盖。
-
实现导航菜单:通过将导航链接元素设置为浮动,实现导航菜单的排列。
需要注意的是,在使用浮动布局时,常常会产生与预期不同的效果,例如元素的高度塌陷等问题,因此需要仔细调试和测试。同时,随着CSS布局技术的发展,浮动布局在一些情况下已经被flexbox和grid等更先进的布局方法所取代。
23、单向链表怎么查找有没有环?
在前端中,同样可以使用快慢指针的方法来判断单向链表是否存在环。我们可以定义两个指针slow和fast,slow每次向前遍历一个节点,而fast每次向前遍历两个节点,如果链表存在环,那么它们最终会相遇。具体实现如下:
function hasCycle(head) {
if (!head || !head.next) {
return false;
}
let slow = head;
let fast = head.next;
while (slow !== fast) {
if (!fast || !fast.next) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
和Python中的实现类似,我们同样需要判断链表是否为空或只有一个节点。接着,我们定义slow和fast指针,并在while循环中移动它们。当链表存在环时,fast指针最终一定会追上slow指针,此时程序返回True。当链表不存在环时,fast指针会提前到达链表末尾,程序返回False。
总的来说,使用快慢指针法可以很便捷地判断单向链表中是否存在环,在时间和空间的复杂度上都比较优秀。
24、rem是什么?em是什么?如果上一层就是根root了,em和rem等价么?
EM和REM都是用于在CSS中指定尺寸的单位。二者的区别在于相对于不同的参考对象进行计算。
-
EM是相对于父元素的字体大小来计算的。例如,如果某个父元素的字体大小为14px,那么子元素使用1em作为单位时,相当于14px(这里默认浏览器的默认字体大小是16px)。
-
REM是相对于根元素(即html元素)的字体大小来计算的。例如,如果根元素的字体大小为16px,那么使用1rem作为单位时,相当于16px。
如果上一层就是根root了,那么使用EM和REM是等价的,都是相对于根元素来计算的。
需要注意的是,使用EM和REM时需要考虑字体大小容易被继承和叠加,这可能导致样式不可预测。建议在设计时提前考虑好字体大小和样式继承的关系,并在开发中严格限制使用EM和REM来控制尺寸。
25、怎么在页面里放置一个很简单的图标,不能用img和background-img?
可以使用CSS的伪元素来实现一个简单的图标。具体来说,我们可以通过设置元素的 ::before
或 ::after
伪元素的 content
属性,同时通过 display
、position
、width
、height
、border
、border-radius
等属性来模拟出一个图标的效果。
以下是一个示例代码片段,使用伪元素实现一个简单的图标效果:
<div class="icon"></div>
.icon::before {
content: "";
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
border: 1px solid gray;
border-radius: 50%;
}
代码中的 .icon::before
选择器选中了 .icon
元素的伪元素 ::before
,并通过 content
属性设置了元素的内容为空。接着,我们使用 display
属性将其变为块级元素,使用 position
属性将其相对于其父元素定位为绝对位置,使用 top
和 left
属性将其水平和垂直方向都居中对齐,最后使用 width
、height
、border
、border-radius
等属性将其样式设置为一个圆形的图标。
需要注意的是,以上代码只是演示通过伪元素实现图标的基本方法,并不是一种完美的实现方式。在实际开发中,我们需要结合设计需求和具体的场景来选择最合适的图标实现方式。
还可以用css画出一些简单的图标