记录总结供以后查询使用。
作者:cuifancastle
文章链接:https://blog.csdn.net/cuifancastle/article/details/107731155
遇到的问题
img图裂如何处理
这里介绍两种方法:
方法一 text-indent & opacity
img {
border: 0;
vertical-align: bottom;
text-indent: -10000px;
}
img[src=""],img:not([src]){
opacity:0;
}
方法二 使用背景图,不会出现图裂, background: url();
图片懒加载
浏览器原生支持
<img src="a.png" loading="lazy">
兼容旧浏览器思路:
监听scroll事件,获取图片距离顶部高度(offsetTop 或 getBoundingClientRect),即将进入时视窗时,进行加载,设置图片真实src。
一种“单页应用”首屏优化方案尝试
- 首屏用到的图,写在css之前,与css并行加载
<head>
<script>new Image().src="a.md5.png";</script>
<link href=js.md5.js rel=preload as=script>
<link href=css.md5.css rel=stylesheet>
</head>
- dom渲染首屏,vue加载后渲染
<body>
<div id="app">
<p>浏览器加载完css后,渲染body,在加载js之前,可以看到些静态资源。</p>
<p>js加载完后,会重新渲染这部分。</p>
</div>
</body>
在做这点之前,想过静态布局,放在最底层,动态渲染放在上层,可能比较麻烦。如:
<body>
<div id="static">静态布局,作为背景层。 z-index=-1</div>
<div id="app"></div>
</body>
如何实现 跑马灯(轮播文字,控制滚动动画时间和间隔时间)
DOM:
<div :class="{'animate-up': animateUp}">
<p v-for="(item, index) in list" :key="index">{{item}}</p>
</div>
.animate-up {
/*动画间隔*/
transition: all 0.5s ease-in-out;
/* 配合list 首个移动到末尾实现循环*/
transform: translateY(-20px);
}
scrollAnimate() {
this.isAnimate = true
setTimeout(() => {
this.list.push(this.msgList[0])
this.list.shift()
this.isAnimate = false
}, 500) // 动画间隔
}
setInterval(this.scrollAnimate, 1500); // 间隔+动画总时间
如何实现回到顶部按钮首屏不显示,非首屏显示,淡入淡出动画
判断是否为首屏
backTopShowHide() {
this.isShowBackTop =document.body.getBoundingClientRect().y < -150
}
监听滚动
// throttle为节流函数
window.addEventListener('scroll', throttle(this.backTopShowHide, 300, 800));
/**
* 节流函数
* @param fun 要执行的函数
* @param delay 延迟
* @param time 在time时间内必须执行一次
* @returns {Function}
* @example window.addEventListener('scroll', throttle(lazyload, 500, 1000));
*/
export function throttle(fun, delay, time) {
let timeout,
startTime = new Date();
return function () {
let context = this,
args = arguments,
curTime = new Date();
clearTimeout(timeout);
// 如果达到了规定的触发时间间隔,触发 handler
if (curTime - startTime >= time) {
fun.apply(context, args);
startTime = curTime;
// 没达到触发间隔,重新设定定时器
} else {
timeout = setTimeout(function () {
fun.apply(context, args);
}, delay);
}
};
}
css使用opacity和transition很方便。
p {
transition: 0.5s;
opacity: 1;
}
transition很好用,一般鼠标hover效果不那么突兀,变色,变位置等。
button {
color: black;
transition: 0.5s;
}
button:hover {
color: #fff;
}
如何实现平滑滚动到固定位置
原生浏览器支持
window.scrollTo({
top: 100,
behavior: 'smooth'
})
滚动到哪个id的dom,有时该dom定位,位置需要微调下,封装下工具函数
/**
* 滚动
* @param domId
* @param num -3 100 微调 单位px
*/
export const scrollTo = (domId, num = 0) => {
let top = 0
if (domId) {
const dom = document.getElementById(domId)
if (!dom) return
top = dom.offsetTop + num
}
window.scrollTo({
top,
behavior: 'smooth'
})
}
复制功能函数
- clipboard.js库
- 原生方法:document.execCommand()
这种工具函数方式比较简单。
/**
* 复制字符串到剪贴板
* @param value
*/
export function clip (value) {
const input = document.createElement('input');
input.setAttribute('readonly', 'readonly');
input.setAttribute('value', value);
document.body.appendChild(input);
input.select();
const isOk = document.execCommand('copy');
document.body.removeChild(input);
return isOk
}
如何实现单行省略,多行省略号
这个太常用了,定宽,定高,溢出省略,设置title(鼠标hover上去有个tips),一套操作下来解决大多数问题
/* 单行省略号 */
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
多行省略有点麻烦,
- line-clamp,浏览器原生支持,不是规范,chrome支持。
- css处理 ,利用:after伪类…挡在结尾的,需要处理可能挡住半个文字,或没溢出却显示…了的情况。
- js处理,计算文字长度(多数字体中英文宽度不一样)
可选择性开启的禁止右键菜单
主要是contextmenu事件处理
- 全部禁用
window.oncontextmenu=function(e){
//取消默认的浏览器自带右键 很重要!!
e.preventDefault();
}
- 自定义右键菜单内容
思路,先取消默认右键,再找到鼠标位置,插入自定义右键菜单(html),参考js设置或禁用鼠标右键菜单 - 全部禁用,选择性开启
这样图片,文字很奇怪的右键就被禁用掉了,需要单独开启的(比如,可复制的文字)也可单独开启了。
window.addEventListener('contextmenu', function (event) {
if (!event.target.getAttribute('allowcontextmenu')) {
event.preventDefault();
}
})
<p allowcontextmenu="true">http://fuzhiwoba.com</p>
<img src="https://sdd.com/a.png"></img>
禁止选中,拖拽
user-drag:auto | element | none
body {
-webkit-user-drag: none;
-webkit-user-select: none;
}
计算字节长度,汉子2字节英文1字节
/**
* 字符串长度,字节数
* @param str
* @returns {number}
*/
export function strlen(str) {
let len = 0;
for (let i = 0; i < str.length; i++) {
let c = str.charCodeAt(i);
//单字节加1
if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
len++;
}
else {
len += 2;
}
}
return len;
}
jsonp实现
function generateJsonpCallback() {
return `jsonpcallback_${Date.now()}_${Math.floor(Math.random() * 100000)}`;
}
function removeScript(id) {
document.body.removeChild(document.getElementById(id));
}
function removeFunc(name) {
delete global[name];
}
export function jsonp(url, options = {timeout: 10000, cb: 'cb'}, query = {}) {
const timeout = options.timeout || 10000;
const cbName = options.cb || 'cb'
const querystring = Object.keys(query).reduce((total, key) => {
return `${total }&${key}=${query[key]}`
}, '')
let timeId;
return new Promise((resolve, reject) => {
const funcName = generateJsonpCallback();
global[funcName] = (res) => {
resolve(res);
timeId = setTimeout(() => {
removeScript(funcName);
removeFunc(funcName);
}, timeout)
};
const script = document.createElement('script');
script.src = `${url}?${cbName}=${funcName}${querystring}`;
script.id = funcName;
script.type = 'text/javascript';
document.body.appendChild(script);
script.onerror = () => {
reject(new Error(`fetch ${url} failed`));
removeScript(funcName);
removeFunc(funcName);
if (timeId) clearTimeout(timeId);
}
})
}
关于jsonp安全问题
后端要严格限制referer
参考jsonp介绍及其安全风险
预防CSRF(Cross Site Request Forgery, 跨站请求伪造攻击)
过滤callback函数名以及JSON数据输出,预防xss(Cross Site Scripting)
滚动条样式
PC端默认的滚动条样式很丑,可通过scrollbar相关css进行配置。
参考css scrollbar样式设置
/* 滚动条 */
.scrollbar--default::-webkit-scrollbar {
width: 6px;
}
.scrollbar--default::-webkit-scrollbar-thumb {
height: 0px;
border-radius: 4px;
background: rgba(119, 119, 119, 0.5);
}
.scrollbar--light::-webkit-scrollbar {
}
<div class="scrollbar--light">溢出的文本</div>
打点实现
export function dd(url) {
let i = new Image()
i.onload = i.onerror = i.onabort = () => {
i.onload = i.onerror = i.onabort = null
i = null
}
i.src = url
}
export function tt(query, BASE_URL) {
const queryStr = Object.keys(query).reduce((total, key) => {
return `${total}&${key}=${query[key]}`
}, '')
const url = `${BASE_URL}?t=${+new Date()}${queryStr}`
dd(url)
}
- 图片打点,使用gift打点
- 减少请求,不影响业务,合并打点与延迟打点。
- 防止图片请求被终止(垃圾回收),使用变量
- 防止相同url图片请求不会发起-url随机值
在实际开发中,注意兼容性。