|
作者:nicksite,來自原文地址
介紹“轉(zhuǎn)換” 意思是將"小程序"不支持的東西轉(zhuǎn)換成它支持的東西。我在開發(fā)的小程序的過程中遇到了兩種需要做“轉(zhuǎn)換”的場景:
我將在下文詳細(xì)介紹我是怎么處理這兩種情況的。 html 轉(zhuǎn)換成 wxml我們的產(chǎn)品在某些場景下,后端接口會直接傳 html 字符串給前端。在 ReactJs 中,我們可以用 dangerouslySetInnerHTML 直接渲染 html 字符串(不一定安全),而 ”小程序“不支持 html ,因此必須對 html 進(jìn)行處理。解決這個問題的步驟主要是:1. 將 html轉(zhuǎn)換成 json ( 樹結(jié)構(gòu)) ;2. 將 json 轉(zhuǎn)換成 wxml 。我在對問題做了調(diào)研后發(fā)現(xiàn),現(xiàn)有一個庫 wxParse 滿足該轉(zhuǎn)換的目的,但是在我看來,這個庫做的事情太多,需要依賴文件過多,不滿足只需要簡單處理的需要,所以我決定自己寫。 html 轉(zhuǎn)換成 json在參考了 html2json 與 himalaya 兩個庫的處理思路的基礎(chǔ)上,我寫了一個簡單的解析庫 htmlParser 。htmlParser 處理 html字符串分兩步: lexer: 生成標(biāo)記(token)
function lex(html) {
let string = html
let tokens = []
while (string) {
// 先處理以 "</" 開始的結(jié)束標(biāo)簽
if (string.indexOf("</") === 0) {
const match = string.match(REGEXP.endTag)
if (!match) continue
// 通過 substring 截斷這個標(biāo)簽的字符串長度
string = string.substring(match[0].length)
tokens.push({
tag: match[1],
type: 'tag-end',
})
continue
}
// 處理以 "<" 開始的標(biāo)簽
if (string.indexOf("<") === 0) {
const match = string.match(REGEXP.startTag)
if (!match) continue
string = string.substring(match[0].length)
const tag = match[1]
const isEmpty = !!MAKER.empty[tag]
const type = isEmpty ? 'tag-empty' : 'tag-start'
const attributes = getAttributes(match[2])
tokens.push({
tag,
type,
attributes
})
continue
}
// 每個處理過程的其他部分字符串被當(dāng)做 "text" 文本處理(暫時不處理其他情況)
const index = string.indexOf('<')
const text = index < 0 ? string : string.substring(0, index)
string = index < 0 ? "" : string.substring(index)
tokens.push({
type: "text",
text
})
}
return tokens
}
parser: 根據(jù)標(biāo)記生成樹
function parse(tokens) {
let root = {
tag: "root",
children: []
}
let tagArray = [root]
tagArray.last = () => tagArray[tagArray.length - 1]
for (var i = 0; i < tokens.length; i++) {
const token = tokens[i]
if (token.type === 'tag-start') {
// 構(gòu)建節(jié)點
|