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

pre标签介绍

官方介绍:

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

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

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

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

举例场景一 渲染一首诗歌

效果图

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

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

html 复制代码
<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简单写一个接口,读取此文件,为了方便直接流方式返回

js 复制代码
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序列化一下

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

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

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

解决方案二的完整代码

html 复制代码
<!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标签,帮我们自动识别,带有转义字符的文本字符串

完整代码

html 复制代码
<!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去控制一下换行截断,如下效果图:

完整代码,瞅瞅注释:

html 复制代码
<!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
  • 编码解码,一般都是后端做,某些情况下,可能需要前端去编码和解码
  • 示例如下:
js 复制代码
<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...

相关推荐
-seventy-4 分钟前
对 JavaScript 原型的理解
javascript·原型
谢尔登28 分钟前
Babel
前端·react.js·node.js
lxcw1 小时前
npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED
前端·npm·node.js
秋沐1 小时前
vue中的slot插槽,彻底搞懂及使用
前端·javascript·vue.js
QGC二次开发1 小时前
Vue3 : Pinia的性质与作用
前端·javascript·vue.js·typescript·前端框架·vue
布丁椰奶冻1 小时前
解决使用nvm管理node版本时提示npm下载失败的问题
前端·npm·node.js
影子落人间2 小时前
已解决npm ERR! request to https://registry.npm.taobao.org/@vant%2farea-data failed
前端·npm·node.js
子非鱼9212 小时前
【前端】ES6:Set与Map
前端·javascript·es6
想退休的搬砖人3 小时前
vue选项式写法项目案例(购物车)
前端·javascript·vue.js
啥子花道3 小时前
Vue3.4 中 v-model 双向数据绑定新玩法详解
前端·javascript·vue.js