JavaScript实现HTML内嵌分离 | 青训营

82 阅读2分钟

近几天在学习node.js的过程中,对JavaScript产生了一些新的思考,那么,能不能手搓一个将内嵌js,css的一段HTML通过文件读写操作,将它分离成多个文件的代码呢?

答案是可以的,那么,我们在设计时首先要思考我们的代码实现要完成哪几步:

1.读取HTML文件,获得里面的内容

2.找到script标签和style标签的内容

3.创建.js,.css文件,将内容写入

4.删去内嵌的标签,添加外联标签以及路径

5.改写HTML文件并保存

对于第一步、第三步和第五步,我们可以使用fs模块中的readFile和writeFile完成,我在这里在代码里设定了文件的名称(也可以自己设定),这里不过多赘述

对于第二步,我们可以使用正则表达式,设定好匹配的样式后,我们直接RegExpObject.exec('待测字符串'),就可以将需要的字符串匹配出来,中间的内容可以使用[\s\S]*(/s/S表示空白/非空白字符,这样就匹配了所有字符),也可以用懒惰匹配.*?,不过因为返回的是一个列表,而一般我们只有一个要匹配的标签,所以我们直接读取里面的第一个元素(当然,不放心的话可以遍历一下)

第四步也比较容易完成,我们只需要用replace将标签替换即为外联的即可

最后附上代码:

//将目录下的 index.html 分离成 new_index.html 、index.js 、index.css 三个文件
const fs = require('fs')
const path = require('path')

const regStyle = /<style>[\s\S]*<\/style>/
const regScript = /<script>[\s\S]*<\/script>/

//读取html文件
fs.readFile(path.join(__dirname,'./index.html'),'utf8',function(err,data){
    if(err){return('failed:'+err.message)}
    resolveCSS(data)
    resloveJS(data)
    resloveHTML(data)
})
//处理css样式
function resolveCSS(html_str){
    //正则提取css
    const r = regStyle.exec(html_str)
    //将提取的字符串替换
    const css_str = r[0].replace('<style>','').replace('</style>','')
    fs.writeFile(path.join(__dirname,'index.css'),css_str,function(err){
        if(err){ return('failed:'+err.message)}
    })
    console.log('css succeed')
}
//处理js脚本
function resloveJS(html_str){
    //正则提取js
    const r = regScript.exec(html_str)
    const js_str = r[0].replace('<script>','').replace('</script>','')
    fs.writeFile(path.join(__dirname,'index.js'),js_str,function(err){
        if(err){return('failed:'+err.message)}
    })
    console.log('js succeed')
}
//处理HTML
function resloveHTML(html_str){
    //修改
    let new_html = html_str.replace(regStyle,'<link rel="stylesheet" href="./index.css" />')
    new_html = new_html.replace(regScript,'<script src="./index.js"></script>')
    //写入
    fs.writeFile(path.join(__dirname,'./new_index.html'),new_html,function(err){if(err){return('failed:'+err.message)}})
    console.log('html succeed')
}

鄙人才疏学浅,若有问题还望多多指正!