23. CSS 如何清除浮动?
这里简单举几个例子。
使用 clear 属性,可以在浮动元素下方插入一个空元素来清除浮动。例如:
.clearfix:after {
content: "";
display: table;
clear: both;
}
使用 overflow 属性,将父元素设置为 overflow: hidden 或 overflow: auto,可以清除浮动。例如:
.parent {
overflow: hidden;
}
使用 clearfix 类,通过添加类名 .clearfix 来清除浮动。例如:
.clearfix::after {
content: "";
clear: both;
display: block;
}
.clearfix {
*zoom: 1;
}
24. Vue 的生命周期及理解?
这里不多赘述了,可以直接参考我的文章,或者官网继续查询学习。文章地址: 前端开发面试题—Vue的生命周期
25. jsp 和 js 的区别?
26. Vue 中 computed 和 watch 区别?
27. Vue 第一次加载页面时会触发哪几个钩子?
28. CSS 的盒子模型由哪几部分组成?
29. v-if 和 v-show 的区别?
30. js 数据类型有哪些?
31. CSS 中水平垂直居中的方法?
在 CSS 中,实现元素的水平垂直居中通常有以下几种方法:
内容已知时使用 position 和 transform 实现居中。
.center {
position: absolute; /* 使父元素变成定位元素 */
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 将元素向上和左移动自身宽度和高度的一半 */
}
只设置宽高时使用 flex 实现居中。
.center {
display: flex; /* 给父元素加上 flex 属性 */
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
不使用 flex 时,通过设置行高、文字对齐方式和 text-align 实现居中。
.center {
height: 100px;
line-height: 100px; /* 设置行高等于元素高度 */
text-align: center; /* 文字居中 */
vertical-align: middle; /* 垂直居中 */
}
使用绝对定位使得 top、bottom、left、right 值相等来实现居中。
.center {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto; /* 需要将 margin 值设置为 auto */
}
32. CSS 的定位方式?
33.前端的存储方式有哪些?
34. Vue 中的通信方式?
35.行内元素、块级元素有哪些?有什么不同?
块级元素:
行内元素:
区别:
在页面布局中,通常采用块级元素和行内元素相结合的方式来实现各种效果。需要注意的是,在选择使用块级元素或行内元素时,要考虑到元素本身的特点以及最终的显示效果。
36. HTML 页面加载完成后,会触发哪个事件?
在 HTML 页面加载完成后,会触发 DOMContentLoaded 事件。这个事件表示文档已经解析完成,但是资源文件可能仍在加载中,例如页面中引入的外部样式表、脚本文件、图片等资源。
DOMContentLoaded 事件是一个非常常用的事件,它可以帮助我们在页面加载完成后执行一些操作,例如初始化页面数据、绑定事件、执行一些函数等等。对于一些简单的页面,我们可以直接在 JavaScript 文件中监听 DOMContentLoaded 事件,进行一些简单的操作。
javascript
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM 已经加载完成');
// 执行一些操作
});
除了 DOMContentLoaded 事件之外,还有其他的事件也可以表示页面的加载状态,例如 window.onload 事件。window.onload 事件在页面所有资源文件都加载完成后才会触发,包括图片、脚本、样式表、视频等等所有资源文件。因此,在一些需要等待所有资源文件加载完成后再执行的操作,可以使用 window.onload 事件来实现。
37. newDate() 获取的是哪里的时间?
38.两个盒子分别放到父盒子的最左和最右,怎么做?
<style>
.parent {
position: relative; /* 确保子盒子相对于父元素进行定位 */
height: 200px; /* 父盒子的高度 */
border: 1px solid black; /* 方便查看 */
}
.left-box {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
left: 0; /* 相对于父元素的左边界 */
}
.right-box {
position: absolute;
width: 100px;
height: 100px;
background-color: blue;
right: 0; /* 相对于父元素的右边界 */
}
style>
<div class="parent">
<div class="left-box">div>
<div class="right-box">div>
div>
在上面的代码中,父盒子的类名为 parent,左侧盒子的类名为 left-box,右侧盒子的类名为 right-box。通过设置左侧盒子的 left: 0; 和右侧盒子的 right: 0;,它们就分别处于父盒子的最左和最右位置了。运行结果如下。
机试题 1️⃣第一题
通过第一张图片我们可以看到相关的题目,图二为第一题的效果图,这里第一题的素材和数据没有,使用就不演示第一题了,而且第一题也是很简单的布局和写样式。
2️⃣第二题
一个简单的注册页面,需要实现简单的数据验证、以及模拟注册和注册成功和失败相对应的操作。接下来看具体代码如下:
代码目录
html、css代码
定义了一个表单,包含用户名、密码、确认密码和注册按钮。每个输入框后面都有一个空的 span 元素用于显示错误提示信息。此外,还定义了一个隐藏的 div 元素,用于在注册成功后显示提示信息。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<style>
/* 表单元素样式 */
input[type="text"],
input[type="password"] {
display: block;
width: 100%;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
font-size: 16px;
}
/* 错误提示信息样式 */
.error-message {
display: block;
margin-bottom: 10px;
color: red;
font-size: 12px;
}
.error {
border-color: red;
}
/* 注册按钮样式 */
button[type="submit"] {
background-color: #4CAF50;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button[type="submit"]:hover {
background-color: #45a049;
}
/* 成功提示信息样式 */
.hidden {
display: none;
}
style>
<body>
<form id="register-form" onsubmit="submitForm(event)">
<label>用户名:<input type="text" name="username" required>label>
<span class="error-message" id="username-error">span><br>
<label>密码:<input type="password" name="password" required>label>
<span class="error-message" id="password-error">span><br>
<label>确认密码:<input type="password" name="password-confirm" required>label>
<span class="error-message" id="password-confirm-error">span><br>
<button type="submit">注册button>
form>
<div id="success-message" class="hidden">
注册成功!
div>
body>
<script src="./index.js">script>
html>
登录页面代码
<h1>欢迎来到登陆页面h1>
js代码
首先获取到表单元素和各个输入框、错误提示信息、成功提示信息的 DOM 元素。然后,在 submitForm 函数中,阻止表单的默认提交行为,获取输入框的值,并进行数据校验。如果校验未通过,则在每个输入框后面的错误提示信息中显示相应的错误信息。如果校验通过,则调用 simulateRegister 函数模拟注册过程。
在 showError 和 hideError 函数中,分别显示和隐藏错误提示信息,并在元素上添加或删除 error 类名来改变样式。
在 simulateRegister 函数中,可以编写具体的注册逻辑,并在注册成功后显示成功提示信息,并在 5 秒后跳转至登录页面。可以使用 setTimeout 方法来延时执行跳转操作。
var registerForm = document.getElementById('register-form');
var usernameInput = document.getElementsByName('username')[0];
var passwordInput = document.getElementsByName('password')[0];
var passwordConfirmInput = document.getElementsByName('password-confirm')[0];
var usernameError = document.getElementById('username-error');
var passwordError = document.getElementById('password-error');
var passwordConfirmError = document.getElementById('password-confirm-error');
var successMessage = document.getElementById('success-message');
// 定义 submitForm 函数
function submitForm(event) {
event.preventDefault(); // 阻止表单提交
// 进行数据校验
var username = usernameInput.value.trim();
var password = passwordInput.value.trim();
var passwordConfirm = passwordConfirmInput.value.trim();
var isValid = true;
if (!username) {
showError(usernameError, '请输入用户名');
isValid = false;
} else if (!/^[a-zA-Z0-9_-]{4,16}$/.test(username)) {
showError(usernameError, '用户名格式不正确');
isValid = false;
} else {
hideError(usernameError);
}
if (!password) {
showError(passwordError, '请输入密码');
isValid = false;
} else if (password.length < 6) {
showError(passwordError, '密码长度不能少于6个字符');
isValid = false;
} else if (!/\d/.test(password) || !/[a-z]/i.test(password)) {
showError(passwordError, '密码必须包含数字和字母');
isValid = false;
} else {
hideError(passwordError);
}
if (!passwordConfirm) {
showError(passwordConfirmError, '请确认密码');
isValid = false;
} else if (passwordConfirm !== password) {
showError(passwordConfirmError, '两次输入的密码不一致');
isValid = false;
} else {
hideError(passwordConfirmError);
}
// 如果校验通过,则模拟注册
if (isValid) {
simulateRegister(username, password);
}
}
// 定义 showError 和 hideError 函数
function showError(element, message) {
element.innerText = message;
element.classList.add('error');
}
function hideError(element) {
element.innerText = '';
element.classList.remove('error');
}
// 定义 simulateRegister 函数
function simulateRegister(username, password) {
// 模拟注册过程
// ...
// 注册成功,显示提示信息并跳转
successMessage.classList.remove('hidden');
setTimeout(function() {
window.location.href = 'login.html';
}, 5000);
}
运行效果如下:
首先提前输入好用户名、密码。
然后点击注册,注册成功五秒后,跳转到登录页面。
3️⃣第三题
使用原生拖动 api 完成,商品拖动加入购入车的功能。接下来看具体代码如下:
代码目录
html、css代码
HTML 代码中,我们定义了三个商品和一个购物车。每个商品都定义了 draggable 属性为 true,表示它是可拖动的。购物车定义了 droppable 属性为 true,表示它可以接受拖动的物品。
CSS 样式代码中,我们定义了商品列表和每个商品的样式,购物车和购物车商品列表的样式,以及总价的样式。在 .product-list 中,我们使用 flex 布局来实现商品列表的对齐方式。每个商品使用了圆角边框、内边距、居中对齐以及拖动光标的样式。
在 .cart 中,我们将购物车和购物车商品列表的边框设置为了圆角边框,并且添加了一些内边距来使其更美观。购物车商品列表被设置为最大高度为 200px,并且超出部分使用滚动条来显示。总价文本的字号被增大并且加粗,突出显示。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<style>
.product-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: space-between;
}
.product {
width: 30%;
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
text-align: center;
cursor: move;
}
.product img {
max-width: 50%;
height: auto;
margin-bottom: 10px;
}
.cart {
position: fixed;
right: 20px;
top: 50%;
width: 320px;
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
background-color: #fff;
box-shadow: rgba(0, 0, 0, 0.15) 0px 2px 8px;
z-index: 100;
}
.cart h2 {
margin-top: 0;
margin-bottom: 16px;
font-size: 24px;
font-weight: bold;
text-align: center;
}
.cart-items {
list-style: none;
margin: 0;
padding: 0;
overflow-y: auto;
max-height: 240px;
}
.cart-items li {
border-bottom: 1px solid #ccc;
margin-bottom: 12px;
padding: 12px;
}
.cart-items img {
width: 50px;
height: 50px;
object-fit: contain;
margin-right: 12px;
}
.cart-items h3 {
margin: 0;
font-size: 16px;
font-weight: bold;
color: #333;
line-height: 1.4;
}
.cart-items p {
margin: 0;
font-size: 14px;
font-weight: bold;
color: #999;
}
.total-price {
margin-top: 16px;
font-size: 20px;
font-weight: bold;
text-align: right;
}
style>
<body>
<ul class="product-list">
<li class="product" draggable="true">
<img src="https://img.yzcdn.cn/vant/apple-1.jpg" alt="Product 1">
<h3>商品1h3>
<p>价格:$10p>
li>
<li class="product" draggable="true">
<img src="https://img.yzcdn.cn/vant/apple-2.jpg" alt="Product 2">
<h3>商品2h3>
<p>价格:$20p>
li>
<li class="product" draggable="true">
<img src="https://img.yzcdn.cn/vant/apple-3.jpg" alt="Product 3">
<h3>商品3h3>
<p>价格:$30p>
li>
ul>
<div class="cart" droppable="true">
<h2>购物车h2>
<ul class="cart-items">ul>
<p>合计:<span class="total-price">$0span>p>
div>
body>
<script src="./index.js">script>
html>
js代码
在 JavaScript 代码中,我们首先获取到三个商品和一个购物车的 DOM 元素,然后监听每个商品的 dragstart 事件,将被拖动的元素保存到数据传输对象中。接着,监听购物车的 dragover 和 drop 事件,在购物车放置拖动的元素时,将被拖动的商品加入购物车中,并更新总价。
在 updateTotalPrice 函数中,我们根据操作符 operator 来更新当前的总价。如果操作符为 add,则增加当前价格;如果操作符为 remove,则减少当前价格。
在 getPriceFromHtml 函数中,我们使用正则表达式从 HTML 数据中提取价格信息,并将它转换为数字类型。我们假设每个商品的价格信息都包含在一个 p 元素中,格式为 价格:$X,其中 X 表示价格数字。
var products = document.querySelectorAll('.product');
var cart = document.querySelector('.cart');
var cartItems = document.querySelector('.cart-items');
var totalPrice = document.querySelector('.total-price');
var currentPrice = 0;
// 监听每个商品的拖动事件
for (var i = 0; i < products.length; i++) {
products[i].addEventListener('dragstart', function(event) {
// 将被拖动的元素保存到数据传输对象中
event.dataTransfer.setData('text/plain', event.target.outerHTML);
});
}
// 监听购物车的放置事件
cart.addEventListener('dragover', function(event) {
event.preventDefault(); // 阻止默认行为,否则无法放置物品
});
cart.addEventListener('drop', function(event) {
event.preventDefault();
var htmlData = event.dataTransfer.getData('text/plain');
var item = document.createElement('li');
item.innerHTML = htmlData;
cartItems.appendChild(item);
updateTotalPrice(htmlData, 'add');
});
// 更新总价
function updateTotalPrice(htmlData, operator) {
var price = getPriceFromHtml(htmlData);
if (operator === 'add') {
currentPrice += price;
} else if (operator === 'remove') {
currentPrice -= price;
}
totalPrice.innerText = '$' + currentPrice;
}
// 从 HTML 数据中获取价格
function getPriceFromHtml(htmlData) {
var regex = /价格:\$(\d+)<\/p>
/i;
var match = htmlData.match(regex);
return match ? parseInt(match[1]) : 0;
}
运行效果如下:
总结
这套面试题适用于前端开发初级的岗位,适合准备面试或者没有面试经验的同学进行练习和阅读,这套面试题涉及的内容也很多,包括了非常经典的前端三件套、Vue、数据结构、网络传输协议等等知识点。总体来说这套面试题不算很难、都是很基础的内容,但是也是非常重要的知识点和技术。其中也有经常出现在面试中的技术点、比如 Vue 生命周期、computed 和 watch 等等。如果这套题的可以做到9成以上的正确率,说明你的基础很扎实了,继续努力、加油。
点赞收藏,防止迷路 ✅感谢观看,下期再会 @CSDN | 黛琳ghz