123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- 'use strict'
- // 等待初始化完毕
- document.addEventListener('UniAppJSBridgeReady', () => {
- document.body.onclick = function () {
- return uni.postMessage({
- data: {
- action: 'onClick'
- }
- })
- }
- uni.postMessage({
- data: {
- action: 'onJSBridgeReady'
- }
- })
- })
- let options
- let medias = []
- /**
- * @description 获取标签的所有属性
- * @param {Element} ele
- */
- function getAttrs(ele) {
- const attrs = Object.create(null)
- for (let i = ele.attributes.length; i--;) {
- attrs[ele.attributes[i].name] = ele.attributes[i].value
- }
- return attrs
- }
- /**
- * @description 图片加载出错
- */
- function onImgError() {
- if (options[1]) {
- this.src = options[1]
- this.onerror = null
- } // 取消监听点击
- this.onclick = null
- this.ontouchstart = null
- uni.postMessage({
- data: {
- action: 'onError',
- source: 'img',
- attrs: getAttrs(this)
- }
- })
- }
- /**
- * @description 创建 dom 结构
- * @param {object[]} nodes 节点数组
- * @param {Element} parent 父节点
- * @param {string} namespace 命名空间
- */
- function createDom(nodes, parent, namespace) {
- const _loop = function _loop(i) {
- const node = nodes[i]
- let ele = void 0
- if (!node.type || node.type == 'node') {
- let { name } = node // svg 需要设置 namespace
- if (name == 'svg') namespace = 'http://www.w3.org/2000/svg'
- if (name == 'html' || name == 'body') name = 'div' // 创建标签
- if (!namespace) ele = document.createElement(name); else ele = document.createElementNS(namespace, name) // 设置属性
- for (const item in node.attrs) {
- ele.setAttribute(item, node.attrs[item])
- } // 递归创建子节点
- if (node.children) createDom(node.children, ele, namespace) // 处理图片
- if (name == 'img') {
- if (!ele.src && ele.getAttribute('data-src')) ele.src = ele.getAttribute('data-src')
- if (!node.attrs.ignore) {
- // 监听图片点击事件
- ele.onclick = function (e) {
- e.stopPropagation()
- uni.postMessage({
- data: {
- action: 'onImgTap',
- attrs: getAttrs(this)
- }
- })
- }
- }
- if (options[2]) {
- image = new Image()
- image.src = ele.src
- ele.src = options[2]
- image.onload = function () {
- ele.src = this.src
- }
- image.onerror = function () {
- ele.onerror()
- }
- }
- ele.onerror = onImgError
- } // 处理链接
- else if (name == 'a') {
- ele.addEventListener('click', function (e) {
- e.stopPropagation()
- e.preventDefault() // 阻止默认跳转
- const href = this.getAttribute('href')
- let offset
- if (href && href[0] == '#') offset = (document.getElementById(href.substr(1)) || {}).offsetTop
- uni.postMessage({
- data: {
- action: 'onLinkTap',
- attrs: getAttrs(this),
- offset
- }
- })
- }, true)
- } // 处理音视频
- else if (name == 'video' || name == 'audio') {
- medias.push(ele)
- if (!node.attrs.autoplay) {
- if (!node.attrs.controls) ele.setAttribute('controls', 'true') // 空白图占位
- if (!node.attrs.poster) ele.setAttribute('poster', "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'/>")
- }
- if (options[3]) {
- ele.onplay = function () {
- for (let _i = 0; _i < medias.length; _i++) {
- if (medias[_i] != this) medias[_i].pause()
- }
- }
- }
- ele.onerror = function () {
- uni.postMessage({
- data: {
- action: 'onError',
- source: name,
- attrs: getAttrs(this)
- }
- })
- }
- } // 处理表格
- else if (name == 'table' && options[4] && !ele.style.cssText.includes('inline')) {
- const div = document.createElement('div')
- div.style.overflow = 'auto'
- div.appendChild(ele)
- ele = div
- } else if (name == 'svg') namespace = void 0
- } else ele = document.createTextNode(node.text.replace(/&/g, '&'))
- parent.appendChild(ele)
- }
- for (let i = 0; i < nodes.length; i++) {
- var image
- _loop(i)
- }
- } // 设置 html 内容
- window.setContent = function (nodes, opts, append) {
- const ele = document.getElementById('content') // 背景颜色
- if (opts[0]) document.body.bgColor = opts[0] // 长按复制
- if (!opts[5]) ele.style.userSelect = 'none'
- if (!append) {
- ele.innerHTML = '' // 不追加则先清空
- medias = []
- }
- options = opts
- const fragment = document.createDocumentFragment()
- createDom(nodes, fragment)
- ele.appendChild(fragment) // 触发事件
- let height = ele.scrollHeight
- uni.postMessage({
- data: {
- action: 'onLoad',
- height
- }
- })
- clearInterval(window.timer)
- let ready = false
- window.timer = setInterval(() => {
- if (ele.scrollHeight != height) {
- height = ele.scrollHeight
- uni.postMessage({
- data: {
- action: 'onHeightChange',
- height
- }
- })
- } else if (!ready) {
- ready = true
- uni.postMessage({
- data: {
- action: 'onReady'
- }
- })
- }
- }, 350)
- } // 回收计时器
- window.onunload = function () {
- clearInterval(window.timer)
- }
|