样式问题
1、滚动条不能拖动
- 设置
touch-action
auto
:默认值。浏览器允许一些手势(touch)操作在设置了此属性的元素上,例如:对视口(viewport)平移、缩放等操作。
none
:禁止触发默认的手势操作。
pan-x
:可以在父级元素(the nearest ancestor)内进行水平移动的手势操作。
pan-y
:可以在父级元素内进行垂直移动的手势操作。
manipulation
:允许手势水平/垂直平移或持续的缩放。任何auto属性支持的额外操作都不支持
- 能滚动说明外层是有滚动条直接外层加上
over-flow: hidden;
2、父组件修改子组件样式失败: 因为有 scoped
属性, 所以在子组件的 class
类名前添加 ::v-deep
。
3、animation
动画效果:
@keyframes name { 0% {background-position: 0 0;}100% {background-position: 0 -542px; }
.class { animation: name 20s linear infinite }
。
4、a标签跳转锚点问题 (prerender-spa-plugin
优化情况下)
- 监听
locatian.href
是否包含 #
, 再动态创建 a 标签模拟点击失效, 原因未知。最后还是使用了 a 标签跳转。
a
标签的不跳转实现的方式
href='#';
不跳转到新页面但是会回到顶部,不推荐使用。
href='javascript:;'
|| href='javascript: void(0);'
当前位置不跳转。
onclick='return false'
阻止默认事件发生。
- 使用
window.scrollTo({ left: '', top: '' })
;
5、div
自身偏移: 使用相对定位。
- 使用
position: relative; top: -20px;
6、过渡动画 transition: all .5s ease-in .1s
;
- 需要注意
display: none;
是不会被监听到,所以没有过渡效果。
- 可以使用
opacity: 0;
来代替。
7、iphone13 pro 底部黑线遮挡问题
- 判断分辨率后:重新设置DOM高度,使用
100vh - 黑条部分高度
。
- 也有可能是设置了固定宽度,导致字体显示失败。
8、1px和0.5px的问题(现代手机一般不会有这个问题)
- 查询手机端的设备像素比值
window.devicePixelRatio = 设备物理像素 / css像素。
如果设备物理像素为 2 , 那么 1px 渲染就为 2 倍,因为最小为2px
。
- 使用媒体查询 设置缩放比。
9、animation 逐帧动画最后一帧闪烁?
- 百分比缩放问题???。
- 背景图默认 不要设置
center no-repeat
。
- 图片尺寸要和设计图一致? 或者使用 step-star
10、display: flex; 设置宽高生效需要添加两个属性
flex-grow:0;
flex-shrink:0;
- 这种方式也可行
flex-wrap: wrap;
11、iphone 使用a标签锚点不会跳转
- 只能使用 JS 事件实现
window.scrollTo({left: '', top: ''})
。
11、position: fixed; top: 0;竟然跟顶部还有距离,上下滚动的时候图直接穿透了
- 第一种方法
*{margin:0px;padding:0px;}
,没点用。
- 第二种 样式修改
position: fixed; top: 0;
=> position: fixed; top: -5px; padding-top: 5px
。完美解决。
12、苹果手机字体粗细设置失败(需要设置苹果字体)
- 加上属性就可以???
font-family: PingFangSC-Regular, PingFang SC;
13、粘性布局 position: sticky; top:50px
;
- 有点像
position:fiexd
; 但它是基于父容器的定位。
- 如果它的父容器不在滚动视图里了,那么也会消失。
14、requestAnimationFrame(function(){});
- 使用requestAnimationFrame代替setTimeout,减少了重排的次数,极大提高了性能,建议大家在渲染方面多使用requestAnimationFrame
- 浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。比如,通过requestAnimationFrame(),JS动画能够和CSS动画/变换或SVG SMIL动画同步发生。
- 另外,如果在一个浏览器标签页里运行一个动画,当这个标签页不可见时,浏览器会暂停它,这会减少CPU,内存的压力,节省电池电量。
- 用过setTimeout实现js动画的人一定知道,在显示器的刷新频率为60Hz的时候,如果将动画的刷新频率设置为每秒刷新60次以上,会出现掉帧的问题,导致动画不连贯。
- 简单一点理解requestAnimationFrame,它会按照你设置的刷新频率和显示器支持的最大刷新频率之间,取较小的那个值。
vue
1、插件安装。更改页签头部内容。
2、安装插件等比例放大(rem)。
3、使用vantUI,插件嵌套使用方式。
4、首屏优化 SEO 优化,白屏优化。
5、package.json
{
"name": "hello-world",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:dev": "vue-cli-service build --mode development",
"lint": "vue-cli-service lint"
},
"dependencies": {
"amfe-flexible": "^2.2.1",
"axios": "^0.27.2",
"babel-plugin-import": "^1.13.0",
"core-js": "^3.6.5",
"fastclick": "^1.0.6",
"less": "^3.12.2",
"less-loader": "^6.2.0",
"postcss-pxtorem": "^5.1.1",
"prerender-spa-plugin": "^3.4.0",
"puppeteer": "^5.2.1",
"shortid": "^2.2.15",
"vant": "^2.9.3",
"vue": "^2.6.11",
"vue-router": "^3.3.4",
"vue-wechat-title": "^2.0.7"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
"@vue/cli-service": "~4.4.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"svg-sprite-loader": "^5.0.0",
"vite-plugin-style-import": "^1.4.1",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
6、vue.config.js
const PrerenderSPAPlugin = require("prerender-spa-plugin");
// eslint-disable-next-line no-unused-vars
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require("path");
// 将传入的相对路径转换为绝对路径
function resolvePath(dir) {
return path.join(__dirname, dir);
}
const autoprefixer = require("autoprefixer");
const pxtorem = require("postcss-pxtorem");
module.exports = {
outputDir: "dist",
publicPath: "/",
// publicPath: "/official-h5/",
// outputDir: 'dist/official-h5/',
configureWebpack: () => {
if (process.env.NODE_ENV !== "production") return;
let plugins = [];
plugins.push(
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
// 下面这句话非常重要!!!
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname, "dist"),
// indexPath: path.join(__dirname, 'dist/official-h5/index.html'),
// outputDir: path.join(__dirname, './'),
// 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
// routes: [
// "/official-h5",
// "/official-h5/about",
// "/official-h5/wisdom-city-solution",
// "/official-h5/wisdom-env-solution",
// "/official-h5/wisdom-water-solution",
// "/official-h5/wisdom-park-solution",
// "/official-h5/wisdom-env-product",
// "/official-h5/wisdom-water-product",
// "/official-h5/wisdom-park-product",
// "/official-h5/careers"
// ],
// 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
routes: [
"/",
"/about",
"/news-content",
"/productSmartWater",
"/productSmartZeroCarbon"
],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
// inject: {
// foo: "bar"
// },
// headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: "render-event",
// headless: true,
// inject: {}
}),
// postProcess(renderedRoute) {
// renderedRoute.html = renderedRoute.html
// .replace(
// /(<script[^<>]*src=\")(?!http|https|\/{2})\/([^<>\"]*)(\"[^<>]*>[^<>]*<\/script>)/gi,
// `$1/official-h5/$2$3`
// )
// .replace(
// /(<link[^<>]*href=\")(?!http|https|\/{2})\/([^<>\"]*)(\"[^<>]*>)/gi,
// `$1/official-h5/$2$3`
// )
// .replace(
// /(<img[^<>]* src=\")(?!http|https|\/{2})\/([^<>\"]*)(\"[^<>]*>)/gi,
// `$1/official-h5/$2$3`
// )
// .replace(
// /(:url\()(?!http|https|\/{2})\/([^\)]*)(\))/gi, // 样式内联,格式必须是":url(/xxx)",其他格式都不行【用来剔除js代码中类似的字段】
// `$1/official-h5/$2$3`
// );
// return renderedRoute;
// },
})
);
return { plugins };
},
css: {
loaderOptions: {
postcss: {
plugins: [
autoprefixer(),
pxtorem({
// 把px单位换算成rem单位 : 换算的基数(设计图375除以十 37.5)
rootValue({ file }) {
// 判断是否是vant ui(375),不是用其他的换算基数。我这里设计图是375所以还是37.5
return file.indexOf("vant") !== -1 ? 37.5 : 37.5;
},
// 需要做转化处理的属性,如`hight`、`width`、`margin`等,`*`表示全部
propList: ["*"]
})
]
}
}
},
chainWebpack(config) {
// 配置应用的标题
config.plugin("html").tap(args => {
const HTMLWebapackPluginArgs = args;
/* new args to pass to html-webpack-plugin's constructor */
return HTMLWebapackPluginArgs;
});
// console.log("mark",config)
// 找到svg对应的规则
config.module
.rule("svg")
// 排除指定的目录
.exclude.add(resolvePath("src/icons"));
// 添加svg-sprite-loader
// 查找icons规则 如果没有则新建这条规则 vue inspect --rules 查看操作结果
config.module
.rule("icons")
// 测试所有的.svg后缀的文件
.test(/\.svg$/)
// 包含指定指定目录 include.add操作会进入其上下文环境include数组
.include.add(resolvePath("src/icons"))
// 回退
.end()
// 添加loader
.use("svg-sprite-loader")
// 切换到当前loader的上下文环境
.loader("svg-sprite-loader")
// 指定loader选项
.options({ symbolId: "icon-[name]" });
}
};
7、各种插件安装冲突问题:例如 gzip
优化