# H5 的实践记录
# 打开微信
function goWeixin() {
window.location = 'weixin://'
// 如果没有拉起 app 跳转应用网站
setTimeout(() => {
if (document.visibilityState !== 'hidden') {
window.location.href = '//weixin.qq.com/'
}
}, 3000)
}
# 拨打电话
<a href="tel:18360523057">18360523057</a>
将网页内容中的手机号码不显示为拨号的超链接
<meta name="format-detection" content="telephone=no" />
# 微信分享
微信 JS-SDK 说明文档 (opens new window)
- 安装依赖包
yarn add weixin-js-sdk -D - 在微信公众平台绑定安全域名
- 后端接口实现 JS-SDK 配置需要的参数
- 页面实现 JS-SDk 中 config 的注入配置,并实现对成功和失败的处理
- 微信分享如果没有图标和标题,可使用微信开发者工具查看分析 sdk 是否加载成功(和绑定的域名有关)
import wx from 'weixin-js-sdk'
async function shareByWeiXin(params) {
const { title, content: desc, url: link, image: imgUrl, success, fail, complete } = params
const url = encodeURIComponent(location.href)
const { data: result } = await axios.get(`/weixin/getconfig?url=${url}`)
if (result.status !== 1) return
wx.config({
appId: result.data.appId, // 必填,公众号的唯一标识
timestamp: result.data.timestamp, // 必填,生成签名的时间戳
nonceStr: result.data.nonceStr, // 必填,生成签名的随机串
signature: result.data.signature, // 必填,签名
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'updateAppMessageShareData',
'updateTimelineShareData',
'onMenuShareQQ',
'onMenuShareQZone'
],
debug: process.env.NODE_ENV === 'development'
})
// 分享成功回调
const success = v => {
typeof success === 'function' && success(v)
}
// 分享失败回调
const fail = err => {
typeof fail === 'function' && fail(err)
}
// 分享完成回调
const complete = v => {
typeof complete === 'function' && complete(v)
}
wx.ready(() => {
const timelineOpt = {
title,
link,
imgUrl,
success,
fail,
complete
}
const messageOpt = {
title, // 分享标题
link, // 分享链接
imgUrl, // 分享图片
desc: desc && desc.substr(0, 50), // 分享描述
success,
fail,
complete
}
if (wx.onMenuShareAppMessage) {
// QQ
wx.onMenuShareQQ(messageOpt)
// 朋友圈
wx.onMenuShareTimeline(timelineOpt)
// 个人或群
wx.onMenuShareAppMessage(messageOpt)
} else {
wx.updateAppMessageShareData(messageOpt)
wx.updateTimelineShareData(timelineOpt)
}
})
wx.error(err => {
console.log(err)
})
}
# 样式篇章
- 常用样式封装
// 设置输入框的提示符样式
@mixin setPlaceholder($color) {
&::-webkit-input-placeholder {
color: $color;
}
&::-moz-placeholder {
color: $color;
}
&::-moz-placeholder {
color: $color;
}
&:-ms-input-placeholder {
color: $color;
}
}
// 多行文字省略号
@mixin clamp($num) {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: $num;
-webkit-box-orient: vertical;
}
- 常用样式兼容
body {
-webkit-tap-highlight-color: transparent; // 去掉元素被点击的时候会被高亮显示(针对ios)
-webkit-font-smoothing: antialiased; // 让页面里的字体变清晰,抗锯齿很好
-webkit-overflow-scrolling: touch; // 让滚动条产生滚动回弹的效果
-webkit-text-size-adjust: none; // 禁止字体大小自动调节
}
# 刘海屏适配
# 微信环境
// 判断是否为微信
export function isWeixin() {
const ua = navigator.userAgent.toLowerCase()
return /MicroMessenger/i.test(ua)
}
// 小程序环境
export function isMiniProgram() {
const ua = navigator.userAgent.toLowerCase()
return (
(ua.match(/micromessenger/i) && ua.match(/miniprogram/i)) ||
win.__wxjs_environment === 'miniprogram'
)
}
# 兼容性篇章
van-datetime-picker在 iOS 上显示一片空白
问题:使用 vant 的 van-datetime-picker 在 iOS 上显示显示一片空白
方案:2020-04-10 格式改成 2020/04/10 格式
原因:ios 初始化 Date 时不支持 2020-04-10 格式,正确写法是 2020/04/10
# 自定义高度输入框
场景:聊天输入信息框,根据内容撑起高度
问题:使用 input/textarea 输入框,没法根据文字撑起高度
方案:使用 div 元素,设置其属性 contenteditable 为 true,使其内容可编辑。(contenteditable 属性指定元素内容是否可编辑)
<template>
<div class="reply">
<div class="txt-box">
<div class="textarea" ref="textarea" contenteditable="true" @input="change" @click.stop></div>
<span class="tip" v-if="!value">回复Ta:</span>
</div>
<van-button>发送</van-button>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
},
methods: {
focus() {
this.value = ''
this.$refs.textarea.focus()
},
change(e) {
this.value = e.target.innerText
}
}
}
</script>
# 防止用 v-html 时 xss 攻击
// main.js中
import xss from 'xss'
Vue.prototype.$xss = xss
// vue.config.js中
module.exports = {
chainWebpack: config => {
// 覆写html指令,防止xss攻击
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.directives = {
html(node, directiveMeta) {
;(node.props || (node.props = [])).push({
name: 'innerHTML',
value: `$xss(_s(${directiveMeta.value}))`
})
}
}
return options
})
}
}
# 关键词高亮显示
const list = res.data || []
for (const val of list) {
val.name_str = val.name.replace(
new RegExp(this.keyword, 'g'),
`<span style="color:#3A72E4">${this.keyword}</span>`
)
}
this.searchList = list
<ul class="search-list">
<li v-for="item in searchList" :key="item.id">
<i class="icon-search"></i>
<div class="name" v-html="item.name_str"></div>
</li>
</ul>
← 环境变量在html中应用 代码review →