用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,登录网站

小程序社区 首页 教程 实战教程 查看内容

开发"小程序"中做的一些"转换"的工作:html 转换成 wxml,html 转换成 json ... ...

天下雪 2017-4-7 00:10

作者:nicksite,来自原文地址介绍“转换”意思是将"小程序"不支持的东西转换成它支持的东西。我在开发的小程序的过程中遇到了两种需要做“转换”的场景:html转换成wxmlsvg转换成canvas我将在下文详细介绍我是怎么 ...

作者:nicksite,来自原文地址

介绍

“转换” 意思是将"小程序"不支持的东西转换成它支持的东西。我在开发的小程序的过程中遇到了两种需要做“转换”的场景:

  • html 转换成 wxml

  • svg 转换成 canvas

我将在下文详细介绍我是怎么处理这两种情况的。

html 转换成 wxml

我们的产品在某些场景下,后端接口会直接传 html 字符串给前端。在 ReactJs 中,我们可以用 dangerouslySetInnerHTML 直接渲染 html 字符串(不一定安全),而 ”小程序“不支持 html ,因此必须对 html 进行处理。解决这个问题的步骤主要是:1. 将 html转换成 json ( 树结构) ;2. 将 json 转换成 wxml 。我在对问题做了调研后发现,现有一个库 wxParse 满足该转换的目的,但是在我看来,这个库做的事情太多,需要依赖文件过多,不满足只需要简单处理的需要,所以我决定自己写。

html 转换成 json

在参考了 html2json 与 himalaya 两个库的处理思路的基础上,我写了一个简单的解析库 htmlParser htmlParser 处理 html字符串分两步:

lexer: 生成标记(token

function lex(html) {
  let string = html
  let tokens = []

  while (string) {
    // 先处理以 "</" 开始的结束标签
    if (string.indexOf("</") === 0) {
      const match = string.match(REGEXP.endTag)
      if (!match) continue
      // 通过 substring 截断这个标签的字符串长度
      string = string.substring(match[0].length)
      tokens.push({
        tag: match[1],
        type: 'tag-end',
      })
      continue
    }
    // 处理以 "<" 开始的标签
    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
    }
    // 每个处理过程的其他部分字符串被当做 "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: 根据标记生成树
上面的 lexer 将 html 字符串分隔成了一个一个 token,然后,我们通过遍历所有的标识来构建树

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') {
      // 构建节点 
鲜花
鲜花 (1)
鸡蛋
鸡蛋

刚表态过的朋友 (1 人)

分享至 : QQ空间
收藏
原作者: nicksite 来自: 原文地址

相关阅读