前言:
现在大家对“parsehtml”大致比较重视,小伙伴们都想要剖析一些“parsehtml”的相关知识。那么小编在网上收集了一些对于“parsehtml””的相关文章,希望兄弟们能喜欢,小伙伴们一起来学习一下吧!由于parseHTML函数代码实在过于庞大,我这里就不一次性贴出源代码了,大家可以前往()查看源代码。
我们来总结一下该函数的主要功能:
1、匹配标签的 "<" 字符
匹配的标签名称不能是:script、style、textarea
有如下情况:
1、注释标签 /^<!\--/
2、条件注释 /^<!\[/
3、html文档头部 /^<!DOCTYPE [^>]+>/i
4、标签结束 /^<\/ 开头
5、标签开始 /^</ 开头
然后开始匹配标签的属性包括w3的标准属性(id、class)或者自定义的任何属性,以及vue的指令(v-、:、@)等,直到匹配到 "/>" 标签的结尾。然后把已匹配的从字符串中删除,一直 while 循环匹配。
解析开始标签函数代码:
function parseStartTag () { // 标签的开始 如<div const start = html.match(startTagOpen) if (start) { const match = { tagName: start[1], // 标签名称 attrs: [], // 标签属性 start: index // 开始位置 } // 减去已匹配的长度 advance(start[0].length) let end, attr while (!(end = html.match(startTagClose)) && (attr = html.match(dynamicArgAttribute) || html.match(attribute))) { attr.start = index v advance(attr[0].length) attr.end = index match.attrs.push(attr) // 把匹配到的属性添加到attrs数组 } if (end) { // 标签的结束符 ">" match.unarySlash = end[1] advance(end[0].length) // 减去已匹配的长度 match.end = index // 结束位置 return match } } }
处理过后结构如下:
接下来就是处理组合属性,调用 “handleStartTag” 函数
function handleStartTag (match) { const tagName = match.tagName // 标签名称 const unarySlash = match.unarySlash // 一元标签 if (expectHTML) { if (lastTag === 'p' && isNonPhrasingTag(tagName)) { // 解析标签结束 parseEndTag(lastTag) } if (canBeLeftOpenTag(tagName) && lastTag === tagName) { parseEndTag(tagName) } } // 是否为一元标签 const unary = isUnaryTag(tagName) || !!unarySlash const l = match.attrs.length // 标签属性集合 const attrs = new Array(l) for (let i = 0; i < l; i++) { const args = match.attrs[i] const value = args[3] || args[4] || args[5] || '' const shouldDecodeNewlines = tagName === 'a' && args[1] === 'href' ? options.shouldDecodeNewlinesForHref : options.shouldDecodeNewlines attrs[i] = { name: args[1], // 属性名称 value: decodeAttr(value, shouldDecodeNewlines) // 属性值 } if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) { // 开始位置 attrs[i].start = args.start + args[0].match(/^\s*/).length // 结束位置 attrs[i].end = args.end } } if (!unary) { stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs, start: match.start, end: match.end }) lastTag = tagName } // 调用start函数 if (options.start) { options.start(tagName, attrs, unary, match.start, match.end) } }
我们简单说一下最后调用的start函数的作用:
1、判断是否为svg标签,并处理svg在ie下的兼容性问题
2、遍历标签属性,验证其名称是否有效
3、标签名是否为 style 或者 script ,如果在服务端会提示warn警告
4、检查属性是否存在 v-for、v-if、v-once指令
5、如果是更元素就验证其合法性,不能是 slot 和 template 标签,不能存在 v-for指令
以上就是界面html模板的开始标签的分析,接下来我们来分析如何匹配结束标签。
请看:Vue源码全面解析三十 parseHTML函数(解析html(二)结束标签)
如有错误,欢迎指正,谢谢。
标签: #parsehtml