IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    面试官抚须:pre标签在工作中有具体应用场景否?答曰:渲染带转义字符的字符串文本内容

    水冗水孚发表于 2023-12-14 14:29:57
    love 0

    pre标签介绍

    官方介绍:

    HTML <pre> 元素表示预定义格式文本。在该元素中的文本通常按照原文件中的编排,以等宽字体的形式展现出来,文本中的空白符(比如空格和换行符)都会显示出来。(紧跟在 <pre> 开始标签后的换行符也会被省略)

    官方文档的介绍,有些“仙气飘飘”,不太接地气,本文将会用几个例子,来讲解一下,这样的话,更加便于了解之

    对于pre标签,我们可以这样简记:

    - pre标签,主要用来渲染带有转义字符的(空格符和换行符等) 的文本内容(字符串)

    举例场景一 渲染一首诗歌

    效果图

    解决方案一 使用&nbsp;空白符

    若是只论这个效果而言,我们可以在html中,使用&nbsp;空白符,去使劲堆出来也是没问题的,如下代码:

    <body>
        <div>白日依山尽</div>
        <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;黄河入海流</div>
        <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;欲穷千里目</div>
        <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;更上一层楼</div>
    </body>
    • 不过这种方式,就会有些呆板了,我们也不可能会在页面的标签中写一堆空白符号的(不美观,不想维护...)
    • 加之,后端只是负责返回字符串罢了,这种方式也不是动态的,所以不太推荐

    解决方案二 使用pre标签

    应用场景就是,后端把读取到txt文本内容字符串,返回给前端去渲染预览,假设数据库中,有这样一个文本文件,如下图:

    这里我们模拟一下后端,使用express简单写一个接口,读取此文件,为了方便直接流方式返回

    route.get('/pre.txt1', (req, res) => {
      let txtUrl = './public/txt1.txt' // 假设txt文件在同级目录public文件夹下
      // 此接口允许跨域
      res.header('Access-Control-Allow-Origin', '*');
      // 设置请求头,编码为utf-8
      res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
      // 将读取的结果以管道pipe流的方式返回给前端
      let readStream = fs.createReadStream(txtUrl)
      readStream.pipe(res);
    })

    有了接口以后,我们直接使用axios发请求,我们JSON序列化一下

    <script>
        axios.get('http://ashuai.work/api/pre.txt1').then((res) => {
            console.log( JSON.stringify(res.data) );
        })
    </script>

    看看打印的结果,如下图:

    而恰好,pre标签能够识别转义字符,那这样就对上了!直接来一段完整代码搞定:

    解决方案二的完整代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    </head>
    
    <body>
        <pre id="pre"></pre>
        <script>
            let pre = document.querySelector('#pre')
            axios.get('http://ashuai.work/api/pre.txt1').then((res) => {
                console.log( JSON.stringify(res.data) );
                // pre.innerHTML = res.data
                pre.innerText = res.data
            })
        </script>
    </body>
    </html>

    最后,我们审查一下dom元素看看:

    • 至此,一个简单的诗歌渲染需求,就完成了
    • 不过,有的道友就会问了,看着也就那回事啊
    • 莫急,我们来看看下一个需求,就会发现pre标签还是很强大的!

    举例场景二 渲染一尊大佛文本【复杂了很多】

    效果图:

    当然,这个大佛,也是服务器上的一个文本内容,如下截图:

    所以,遇到这种场景,就必须要使用pre标签,帮我们自动识别,带有转义字符的文本字符串

    完整代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    </head>
    
    <body>
        <pre id="pre"></pre>
        <script>
            let pre = document.querySelector('#pre')
            axios.get('http://ashuai.work/api/pre.txt2').then((res) => {
                console.log( JSON.stringify(res.data) );
                pre.innerHTML = res.data
                // pre.innerText = res.data
            })
        </script>
    </body>
    </html>

    注意事项一:pre标签横向文字换行样式控制

    - pre标签的内容,在宽度不够的情况下,不会自动换行,如下效果图:

    - 这个时候我们需要使用css去控制一下换行截断,如下效果图:

    完整代码,瞅瞅注释:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
        <style>
            pre {
                font-size: 36px;
                /* pre宽度不够换行 */
                word-wrap: break-word;
                white-space: pre-wrap;
                /* 加点行高,防止太挤了 */
                line-height: 42px;
            }
        </style>
    </head>
    
    <body>
        <pre id="pre"></pre>
        <script>
            let pre = document.querySelector('#pre')
            axios.get('http://ashuai.work/api/pre.txt3').then((res) => {
                console.log(JSON.stringify(res.data));
                pre.innerHTML = res.data
            })
        </script>
    </body>
    
    </html>

    注意事项二 文本的编码可能不是utf-8

    • 某些情况下,接口返回的字符串文本,并不是utf-8的编码方式
    • 这种情况下,就需要去编码和解码
    • 比如:charset=utf-8或gbk或gb2312
    • 编码解码,一般都是后端做,某些情况下,可能需要前端去编码和解码
    • 示例如下:
    <script>
        //utf-8转gbk
        function utf8ForGbk(str) {
            let enCode = new TextEncoder('gbk');
            let deCode = new TextDecoder('utf-8');
            let newStr = enCode.encode(str);
            let res = deCode.decode(newStr);
            return res;
        }
    
        //gbk转utf-8
        function gbkForUtf8(str) {
            let enCode = new TextEncoder('utf-8');
            let deCode = new TextDecoder('gbk');
            let newStr = enCode.encode(str);
            let res = deCode.decode(newStr);
            return res;
        }
    </script>

    行文至此,我们通过以上案例,就可以进一步理解:

    • pre标签可以用于 去渲染 带有转义字符的文本字符串...
    • 比如,我们去封装一个组件,去做txt的文本预览
    A bad pen is better than a good memory...


沪ICP备19023445号-2号
友情链接