前端开发中遇到的问题数不胜数,其中有一些问题比较通用,掌握其解决办法可以提高开发效率,减少出错率。本文将介绍10个有趣的通用问题及其解决办法。
1. 元素居中
居中是前端开发中经常需要处理的问题,可以通过 CSS 的 flex、position、transform 等实现。
- 使用 flexbox 居中:
.container {
display: flex;
justify-content: center;
align-items: center;
}- 使用 position 居中:
// www.javascriptcn.com code example
.container {
position: relative;
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}- 使用 transform 居中:
// www.javascriptcn.com code example
.container {
position: relative;
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}2. 元素溢出处理
元素溢出是指在父元素中的子元素超出了父元素的范围。
- 使用 overflow 属性处理溢出:
.parent {
overflow: hidden;
}- 使用 text-overflow 属性处理文本溢出:
.text {
white-space: nowrap; // 强制一行显示
overflow: hidden;
text-overflow: ellipsis; // 使用省略号表示溢出部分
}- 使用 calc 函数处理宽度溢出:
.child {
width: calc(100% + 20px); // 借助 calc 函数来处理宽度溢出
}3. 图片懒加载
图片懒加载是一种前端性能优化的方式,即在用户滚动到需要查看图片的位置时,再加载图片。
- 使用 Intersection Observer API 实现图片懒加载:
// www.javascriptcn.com code example
let observer = new IntersectionObserver(entries => {
// entries 是可见性变化的元素的集合,可以通过判断 intersectionRatio 是否大于 0 来确定元素是否在可见区域内
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
let img = entry.target;
img.src = img.dataset.src; // 将 data-src 的值赋给 src,实现懒加载
observer.unobserve(img); // 停止观察这个元素
}
});
});
document.querySelectorAll('.lazy').forEach(img => {
observer.observe(img);
});4. 防抖和节流
防抖和节流是前端开发中常见的处理事件性能问题的方式。
- 防抖:
即当事件触发时,在执行回调函数前等待一段时间,如果这段时间内没有再次触发该事件,就执行回调函数;否则,重新计时。
// www.javascriptcn.com code example
function debounce(fn, delay) {
let timer = null;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
}
}- 节流:
即当事件触发时,只执行一次回调函数,同时设置下次执行回调函数的时间间隔。
// www.javascriptcn.com code example
function throttle(fn, delay) {
let lastTime = 0;
return function() {
let now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, arguments);
lastTime = now;
}
}
}5. Cookie、localStorage 和 sessionStorage 的使用
Cookie、localStorage 和 sessionStorage 都是前端存储数据的方式,但它们之间有着不同的使用场景和区别。
- 使用 Cookie:
document.cookie = 'name=value; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/';
- 使用 localStorage:
let obj = { name: '张三', age: 18};
localStorage.setItem('person', JSON.stringify(obj));
let person = JSON.parse(localStorage.getItem('person'));- 使用 sessionStorage:
sessionStorage.setItem('token', '123456');
let token = sessionStorage.getItem('token');6. 跨域问题
跨域是指当一个请求的域名、协议、端口与当前网页不一致时,就产生了跨域问题。通常可以通过 JSONP、CORS、代理、postMessage 等方式进行解决。
- JSONP:
// www.javascriptcn.com code example
function jsonp(url, params, callback) {
let script = document.createElement('script');
let paramsString = '';
// 将参数拼接到请求地址上
for (let key in params) {
paramsString += `${key}=${params[key]}&`;
}
url = `${url}?${paramsString}callback=${callback}`;
script.setAttribute('src', url);
document.head.appendChild(script);
setTimeout(() => {
document.head.removeChild(script);
}, 5000); // 超时处理
}
jsonp('https://api.xxx.com', { name: '张三' }, 'callback');- CORS:
后端需要设置响应头信息。
res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有来源访问- 代理:
// www.javascriptcn.com code example
const httpProxy = require('http-proxy');
const apiProxy = httpProxy.createProxyServer();
const host = 'xxx.com';
const port = 80;
const proxyOptions = {
target: `http://${host}:${port}`,
};
app.use('/api', (req, res) => {
apiProxy.web(req, res, proxyOptions);
});7. 模板引擎
模板引擎是前端开发中常用的渲染模板的方式,可以使用 ejs、handlebars、pug 等模板引擎。
- 使用 ejs:
let ejs = require('ejs');
let template = '<h1><%= title %></h1>';
let data = { title: 'Hello, world!' };
let result = ejs.render(template, data);- 使用 handlebars:
let handlebars = require('handlebars');
let source = '<h1>{{title}}</h1>';
let template = handlebars.compile(source);
let data = { title: 'Hello, world!' };
let result = template(data);- 使用 pug:
let pug = require('pug');
let template = 'h1= title';
let data = { title: 'Hello, world!' };
let result = pug.render(template, data);8. 打包和部署
打包和部署是前端开发中必不可少的工作。通常可以使用 webpack、gulp 等工具进行打包,使用 Git、FTP 等工具进行部署。
- 使用 webpack:
// www.javascriptcn.com code example
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' })
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: { presets: ['@babel/preset-env'] }
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};- 使用 Git:
git add . git commit -m "commit message" git push origin master
- 使用 FTP:
npm i gulp gulp-zip gulp-ftp -D
// www.javascriptcn.com code example
let gulp = require('gulp');
let zip = require('gulp-zip');
let ftp = require('gulp-ftp');
let targetDir = './dist';
let pattern = '**/*';
let zipFilename = 'dist.zip';
gulp.task('zip', () => {
return gulp.src(`${targetDir}/${pattern}`)
.pipe(zip(zipFilename))
.pipe(gulp.dest(targetDir));
});
gulp.task('upload', () => {
return gulp.src(`${targetDir}/${zipFilename}`)
.pipe(ftp({
host: 'xxx.com',
user: 'username',
pass: 'password',
remotePath: 'remotePath'
}));
});
gulp.task('deploy', gulp.series('zip', 'upload'));9. 动态导入
动态导入是指在运行时动态加载模块的方式,可以提高代码的执行效率。
- 使用 import():
let btn = document.querySelector('#btn');
btn.onclick = async function() {
let myModule = await import('./myModule.js');
myModule.doSomething();
};10. 路由实现
路由是前端开发中常见的页面路由,可以使用 history API、hashchange 事件、第三方库等方式进行实现。
- 使用 history API:
// www.javascriptcn.com code example
let router = {
'/home': function() {
console.log('home page');
},
'/about': function() {
console.log('about page');
},
'/contact': function() {
console.log('contact page');
},
'*': function() {
console.log('404 page');
}
};
let defaultRoute = '*';
window.addEventListener('load', () => {
let path = window.location.pathname;
path = path === '/' ? defaultRoute : path;
(router[path] || router['*'])();
});
window.addEventListener('popstate', () => {
let path = window.location.pathname;
path = path === '/' ? defaultRoute : path;
(router[path] || router['*'])();
});本文介绍了 10 个有趣的通用问题及其解决办法,在实际开发中可以根据需求选择不同的解决方案。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d652e9a941bf7134c08ce7