2

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...

水冗水孚
1.1k 声望588 粉丝

每一个不曾起舞的日子,都是对生命的辜负