微信小程序 - 渲染HTML

个人博客:柚子青年。

微信小程序现在已经被广泛应用,开发方式类似 Vue。

阅读本文需要有小程序基础。

rich-text

在渲染 DOM 这一块,小程序没有 Vue 的 v-html 也没有 React 的 dangerouslySetInnerHTML,不过小程序提供了自己的渲染方式 rich-text,详情请看 官方文档。

不过在展示效果上个人觉得是不太满意的。在展示代码的时候,并不会有很好的换行和间隔。网上也有一些第三方组件帮你渲染的,我这边觉得还是不太行,于是就自己大致造了个轮子。

注:本文只提供解决思路不提供具体实现代码

渲染原理

首先要先了解小程序官方渲染方式的原理。

WXML
<rich-text nodes="{{nodes}}" bindtap="tap"></rich-text>
JavaScript
data: {
    nodes: [{
        name: 'div',
        attrs: {
            class: 'div_class',
            style: 'line-height: 60px; color: red;'
        },
        children: [{
            type: 'text',
            text: 'Hello&nbsp;World!'
        }]
    }]
}

大致就是 引入 rich-text 组件, 传入 nodes 格式的 json 然后进行渲染。

所以我们自己实现的时候也可以按照这种方式。

实现
WXML
<view className="content">
    <view wx:for="{{news.wxml}}" wx:key="name" className="{{item.className || ''}}">
        <view wx:if="{{item.name === 'view'}}">{{item.value}}</view>
        <view wx:if="{{item.name === 'image'}}">
            <image src="{{item.value}}" mode="widthFix"></image>
        </view>
        <text className="code" wx:if="{{item.name === 'text'}}">{{item.value}}</text>
    </view>
</view>
WXSS
.content > view { line-height: 48rpx;  margin-bottom: 30rpx; }
.content .h1 { font-weight: bold;  font-size: 2em; }
....
.content .blockquote { padding: 20rpx 30rpx; color: #777; border-left: 4px solid #ddd;  background: #fafafa; }
.content .code { display: block; font-size: 24rpx; color: #f8f8f2; padding: 32rpx; background-color: #282a36; border-radius: 6rpx; white-space: pre; word-wrap: normal; overflow: auto; }
JavaScript
data: {
    nodes: [{
        name: 'view',
        className: 'div_class',
        value: "Hello&nbsp;World!"
    }]
}
// name:  view  普通文本  image 图片  text 代码片段 
// className: 需要添加的 class
// value: 值 对应 name 类型 (保留空格换行,建议直接粘贴不用管格式)

后续可能会出具体实现方式,大概。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
插件地址:https://github.com/kevenfeng/html-to-wxml如果前端技术比较牛,可以直接看github上面的demo。可以更好的理解用法。使用方法:1.引用插件var R_htmlToWxml = require(‘../../util/htmlToWxml.js’);//引入公共方法2.将html内容转成json数据R_htmlToWxml.html2json(“html内容”);转换后的json格式类型大概如下:3.吐到页面中显示<block wx:for="{{content}}"  wx:for-index="idy"  wx:for-item="cellData">         <block  wx:if="{{cellData.type == 'view'}}">             <view class="p">                 <block  wx:for="{{cellData.child}}" wx:key="text">                     <block  wx:if="{{item.type == 'a'}}">                         <text class="a" data-seccode="{{item.attr['data-seccode']}}" data-secname="{{item.attr['data-secname']}}" bindtap="stockClick">{{item.text}}</text>                     </block>                     <block  wx:else>                         <text>{{item.text}}</text>                     </block>                 </block>             </view>         </block>         <block wx:if="{{cellData.type == 'img'}}">             <image class="img" data-index="{{idy}}" style="height: {{cellData.attr.height?cellData.attr.height:0}}px"  mode="aspectFit" src="{{cellData.attr.src}}" bindload="imageLoad"></image>         </block>     </block>demo效果:由于小程序图片的高度没法自适应,需要给图片设置高度,所以需要在图片加载完以后,获取图片高度,等比算出显示图片高度,赋值给对应图片通常我们抓取的内容是html页面,特别是像资讯这一类的,如果在小程序里面显示文章内容,此插件提供了一种解决方案,希望对大家有用。在客户端中用native显示html页面体验上面没有native的好,htmlToWxml插件给客户端中用native的方式显示html内容提供了一种解决方案
微信小程序中没有直接支持的v-html指令,但你可以通过使用rich-text组件来实现类似的效果。rich-text组件可以渲染带有HTML标记的文本内容。 首先,在你的小程序页面中引入rich-text组件: ```xml <rich-text nodes="{{content}}"></rich-text> ``` 然后,在对应的Page的JS文件中,将HTML内容转换为nodes数组: ```javascript Page({ data: { content: [], }, onLoad: function () { // 假设你的HTML内容存储在变量htmlContent中 const nodes = this.convertHtmlToNodes(htmlContent); this.setData({ content: nodes, }); }, convertHtmlToNodes: function (html) { // 使用正则表达式将HTML内容转换为nodes数组 // 这里可以自定义转换规则,根据需要进行处理 // 下面是一个简单示例,只处理了部分常用标签 const tagRegex = /<(\/?)(\w+)([^>]*)>/g; const attrRegex = /(\w+)=["']([^"']*)["']/g; const nodes = []; let match; let lastIndex = 0; while ((match = tagRegex.exec(html)) !== null) { const [fullMatch, isClosingTag, tagName, attrs] = match; const attributes = {}; let attrMatch; while ((attrMatch = attrRegex.exec(attrs)) !== null) { const [attrFullMatch, attrName, attrValue] = attrMatch; attributes[attrName] = attrValue; } const node = { type: isClosingTag ? 'node' : 'element', name: tagName, attrs: attributes, children: [], }; if (isClosingTag) { let parentIndex = nodes.length - 1; while (parentIndex >= 0) { const parent = nodes[parentIndex]; if (parent.type === 'element' && parent.name === tagName) { parentIndex--; break; } parentIndex--; } if (parentIndex >= 0) { nodes[parentIndex].children.push(node); } } else { if (lastIndex < match.index) { const textContent = html.slice(lastIndex, match.index); nodes.push({ type: 'text', text: textContent, }); } nodes.push(node); } lastIndex = match.index + fullMatch.length; } if (lastIndex < html.length) { const textContent = html.slice(lastIndex); nodes.push({ type: 'text', text: textContent, }); } return nodes; }, }); ``` 这样就可以在小程序渲染带有HTML标记的文本内容了。请注意,上述示例只是一个简单的转换方法,如果你的HTML内容比较复杂,可能需要进行更复杂的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值