Demand background
The h5 page in the WebView needs to modify the current share page after some operations, but the link of the H5 page does not change. There needs to be a mechanism for notifying applet pages that share parameters need to be changed.
Technology to solve
According to applets documentation, support webView pages to communicate with applets in the form of postMessage (only triggered during special operations such as sharing, returning, etc.)
Key points:
- Using wx. MiniProgram. PostMessage to small program communication, when a user forward can listen to the news page
- The page listens to historical messages and does not clear them. You need to handle them by yourself
- Applets page set onShareAppMessage can support sharing, the default share is the current page
- After the user clicks forward, onMessage of webView will be triggered first, and then onShareAppMessage will be called to set the sharing configuration
PostMessage message format as agreed by H5 and applets:
{
type:'Message type', / /setShareOption ... RestData // Other parameters}Copy the code
H5 Page sharing parameters:
/** * Set "postMessage" * @param option * @examplesetWeappShareOption({title:"Share title",path:"Share links",imageUrl:'Share picture may be empty'}) * /export function setWeappShareOption(option:{title:string,path:string,imageUrl:string}){
if(window['wx'] && window['wx'].miniProgram && window['wx'].miniProgram.postMessage){
window['wx'].miniProgram.postMessage({
data:{
type:'setShareOption', title:option.title, path:option.path, imageUrl:option.imageUrl } }); }}Copy the code
Applet pages support sharing:
The source address
import Taro from '@tarojs/taro'
import { WebView } from '@tarojs/components'
import {
getCurrentChannelEventHash,
resetChannelHash,
} from './WebViewHashChannelData'
import { unpackUrl,packUrl } from '.. /.. /src/core/UrlHelper'
const DEFAULT_WEB_PATH = 'https://xxx.x.com/xxx'// To default domain name prefix /** * applet Page * @param to ADDRESS of THE H5 Page to be moved to :/ XXX/XXX or full address https://xxx.... * @param title Title of h5 page to jump to */export default class H5WebView extends Taro.Component {
config = {
navigationBarTitleText: ' ',
}
state = {
url: ' '// THE URL does not support Hashhash: ' ',
}
isBack = false
shareOption = {
title: null,
path: null,
}
componentWillMount() {
this.isBack = false
const to = decodeURIComponent(this.$router.params.to || ' ')
const urlObj = unpackUrl(to)
let url = urlObj.pathWithSearch
let hash = urlObj.hash
let title = this.$router.params.title
if (title) {
title = decodeURIComponent(title)
Taro.setNavigationBarTitle({ title: title })
}
this.setState({
url,
hash,
})
console.log('[H5WebView] mount', url, hash)}componentDidShow() {
// onShow
if(this.isback) {// Applet page falls back, notifying H5let channelEventHash = getCurrentChannelEventHash()
// if(! ChannelEventHash) {// TODO only whitelist pages to add backPush via postMessage?? // channelEventHash = getBackEventHash(); } this.setState({this.setState({this.setState);}hash: channelEventHash,}) // Reset resetChannelHash() console.log('[H5WebView] show set hash', channelEventHash, this.state.url)
} else {
console.log('[H5WebView] show first')
}
this.isBack = true
}
_getLastData(itemList, type) {
if(! itemList || itemList.length === 0) {return null
}
let lastIdx = itemList.length - 1
while (lastIdx >= 0) {
let item = itemList[lastIdx]
if (item && item.type === type) {
return item
}
}
}
handleMessage(e) {
let{data} = e.datail // Set the last sharelet shareOption = this._getLastData(data, 'setShareOption')
if (shareOption) {
this.shareOption = {
title: shareOption.title,
imageUrl: shareOption.imageUrl,
path: shareOption.path,
}
}
console.log('withWV handleMessage', data)} /** * supports message sharing */onShareAppMessage() {
if (this.shareOption) {
let path = null
if (this.shareOption.path) {
path = packUrl(this.$router.path, {
to: this.shareOption.path,
title: this.shareOption.title,
})
}
return {
title: this.shareOption.title,
path,
imageUrl: this.shareOption.imageUrl,
}
}
}
onWebViewLoad(e) {
console.log('withWV onWebViewLoad'SRC, this.state.hash) this.shareoption. path = e.daail. SRC // Default share page is the current page}_normalizeTo() {
let to = this.state.url
if(! to) {return null
}
if(to.substr(0, 4) ! = ='http') {
to = DEFAULT_WEB_PATH + to
}
if (this.state.hash) {
to += The '#' + this.state.hash
}
return to
}
render() {
let to = this._normalizeTo()
if(! to) {return null
}
return (
<WebView
src={to}
onMessage={this.handleMessage}
onLoad={this.onWebViewLoad}
/>
)
}
}
Copy the code
TODO
You can add a field ID to postMessage, and after each processing, record the ID of the last message that was processed last time. The next processing will be processed after that message