美文网首页
小程序自动分离出css

小程序自动分离出css

作者: JSwifter | 来源:发表于2018-01-25 16:03 被阅读0次

    问题

    因为在工作中需要经常写小程序的页面, 但是在写一个页面的时候通常会写完html结构再去写css, 在过程中免不了忘记了元素的类名, 便会在两个文件中不时的切换来切换去, 但若直接用行内样式的写法, 会有什么不好大家都懂... 于是对我来说若能既采用行内样式的写法, 又能分离出html和css的需求就出来了, 所以便花了几个小时写了个小工具: https://www.npmjs.com/package/onetotwo. (还不完善, 只能暂时满足我最基础的需求, 忘大屌们见谅.)

    介绍

    所以这边一个需要解决的常见问题便是如何解析html结构, 并转换为我所想要的数据结构, 以下为简易版实现(诸多情况尚未考虑):, 主要实现便是一个个读取html字符串, 如果遇到了<符号变把它当做标签解析, 并记录该标签全部内容, 直到遇到了>字符, 便开始解析出标签中的style和class属性, 代码如下:

    
    const [Node, Tree] = require('./tree');
    
    function parse(html, _callback) {
    
        // 先去除html中的注释与空白字符
    
        html = html.replace(/<!--[\s\S]*?-->/g, '');
    
        html = html.replace(/>\s+([^\s<]*)\s+</g, '>$1<').trim();
    
        var parseHTML = (function () {
    
            var __i = 0,
    
                __currentFn = parse_text, // 对当前字符的处理函数
    
                __tag = '',
    
                __tag_all_content = '',
    
                __have_root = false,
    
                __tree = new Tree(),
    
                __current_node = null,
    
                __stack = [];
    
    
    
            // 处理标签
            function parse_tag(token) {
    
                if (token === '/') {
    
                    return parse_end_tag;
    
                }
    
                __i --; // 开始处理标签的时候索引需要回退1位
    
                return parse_begin_tag;
    
            }
    
    
    
            // 处理开始标签
            function parse_begin_tag(token) {
    
                if (token === '>') {
    
                    const style_regex = /\bstyle\s*=\s*(?:"([^"]*)"|'([^']*)'|([^'">\s]+))/ig;
    
                    const class_regex = /\bclass\s*=\s*(?:"([^"]*)"|'([^']*)'|([^'">\s]+))/ig;
    
                    const class_result = class_regex.exec(__tag_all_content);
    
                    const style_result = style_regex.exec(__tag_all_content);
    
                    const tag_name = __tag_all_content.replace(/\s.*/g, '');
    
                    const class_name = class_result && (class_result[1] || class_result[2] || class_result[3]);
    
                    const style = style_result && (style_result[1] || style_result[2] || style_result[3]);
    
                    if (!__have_root) {
    
                        __tree.root = { tag: tag_name, parent: null, child: [], hierarchy: 0 };
    
                        __current_node = __tree.root;
    
                        __have_root = true;
    
                    }else {
    
                        let new_node = { tag: tag_name, parent: __current_node, child: [], hierarchy: __stack.length};
    
                        __current_node.child.push(new_node);
    
                        __current_node = new_node;
    
                    }
    
                    class_name && (__current_node.class_name = class_name);
    
                    style && (__current_node.style = style);
    
                    __stack.push(__current_node);
    
                    __tag_all_content = '';
    
                    return parse_text;
    
                }
    
                __tag_all_content += token;
    
                return parse_begin_tag;
    
            }
    
            // 处理结束标签
            function parse_end_tag(token) {
    
                if (token === '>') {
    
                    if (__current_node.tag !== __tag) {
    
                        console.log('\x1b[31m >>>' + 'Wrong closed tag at char ' + __i + '\x1b[39m');
    
                    }
    
                    __tag = '';
    
                    __stack.pop();
    
                    __current_node = __current_node.parent;
    
                    return parse_text;
    
                }
    
                __tag += token;
    
                return parse_end_tag;
    
            }
    
            function parse_text(token) {
    
                if (token === '<') {
    
                    return parse_tag;
    
                }
    
                return parse_text;
    
            }
    
            return function (html) {
    
                for (; __i < html.length; __i++) {
    
                    __currentFn = __currentFn(html[__i]);
    
                }
    
                return __tree;
    
            }
    
        })();
    
        _callback(parseHTML(html))
    
    }
    
    

    相关文章

      网友评论

          本文标题:小程序自动分离出css

          本文链接:https://www.haomeiwen.com/subject/vqivaxtx.html