Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * 将字符串编译为 DOM 结构
- * @deprecated 请注意,不要用该函数,因为 compile('<div></div><p></p>') 会编译成嵌套结构:<p><div></div></p>
- * @public
- * @param {String} domString
- * @return {HTMLElement}
- * @throws {Error} 如果输入不是合法的 DOM 字符串
- *
- * @example
- * compile('<div><p><a><em></em></a></p></div>')
- * // =>
- * <div>
- * <p>
- * <a>
- * <em></em>
- * </a>
- * </p>
- * </div>
- *
- * @example
- * compile('<div></p>')
- * // => Uncaught Error: DOM string invalid
- */
- function compile(domString) {
- var validated = validate(domString);
- if (!validated) {
- throw new Error('DOM string invalid');
- }
- const compiled = assemble(validated);
- return compiled;
- }
- /**
- * 检测是否是合法的 DOM 字符串
- * @private
- *
- * @param {String} domString
- * @return {String[]|false} 若合法则返回标签名数组,否则返回 false
- *
- * @example
- * validate('<div></div>')
- * // => ['div']
- *
- * @example
- * validate('<div></p>')
- * // => false
- *
- * @example
- * validate('<div><p><a><em></em></a></p></div>')
- * // => ['div', 'p', 'a', 'em']
- */
- function validate(domString) {
- const beginTagPattern = /^<(\w+)>/;
- const closeTagPattern = /^<\/(\w+)>/;
- const stack = [];
- const tags = [];
- let testString = domString;
- let delta = 1;
- while (testString.length > 0) {
- const beginTagMatches = testString.match(beginTagPattern);
- const closeTagMatches = testString.match(closeTagPattern);
- let matches;
- if (beginTagMatches) {
- matches = beginTagMatches;
- stack.push(matches[1]);
- // console.log('after push stack:', stack);
- } else if (closeTagMatches) {
- matches = closeTagMatches;
- if (stack[stack.length - 1] === matches[1]) {
- const tag = stack.pop();
- tags.push(tag);
- // console.log('after pop stack:', stack);
- }
- } else {
- break;
- }
- delta = matches[0].length + matches.index;
- testString = testString.slice(delta);
- }
- // console.log('final stack:', stack);
- return stack.length === 0 ? tags.reverse() : false;
- }
- /**
- * 将标签组装为嵌套的 DOM 结构
- * @private
- * @param {String[]} tags
- * @return {HTMLElement}
- *
- * @example
- * assemble(['div', 'p', 'a', 'em'])
- * // => <div><p><a><em></em></a></p></div>
- */
- function assemble(tags) {
- const elements = tags.map((tag) => document.createElement(tag));
- elements.forEach((element, index, elements) => {
- // console.log('element:', element);
- if (index !== elements.length - 1) {
- element.appendChild(elements[index + 1]);
- }
- });
- return elements[0];
- }
Add Comment
Please, Sign In to add comment