通过pre标签进行json格式化展示,并实现搜索高亮和通过鼠标进行逐个定位的功能

功能说明

  1. 实现一个对json进行格式化的功能
  2. 添加搜索框,回车进行关键词搜索,并对关键词高亮显示
  3. 搜索到的多个关键词,回车逐一匹配
  4. 监听json框,如果发生了编辑,需要在退出时提示,在得到用户确认的情况下再退出

效果展示

在这里插入图片描述

说明:如上图中,输入“编程”两个字,每回车一下,就定位到匹配到的第二个位置,并将当前匹配到的文字滚动到顶部。

实现步骤

第一步:编写HTML

分别添加一个输入框、一个用于展示json的pre标签、和一个取消按钮

说明:此处的其它功能有省略

<template>
    <div>
        <el-input class="input" v-model="searchValue" @keyup.enter.native="handleEnter" placeholder="输入关键词回车搜索"></el-input>
        
        <pre class="content" id="json-pre" contenteditable="true" v-html="preJsonHtml"></pre>

        <el-button @click="handleCancle">取消</el-button>
    </div>
</template>

第二步:实现JavaScript方法

2.1 定义必要的变量和进行变量监听

<script lang="ts" setup>
import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessageBox } from 'element-plus';

const route = useRoute()
const router = useRouter()

// 存放获取到的json文件的内容
let jsonData = ref()

// 搜索框内容
let searchValue = ref()

// 用于在pre标签里展示的HTML
let preJsonHtml = ref()

// 表示json是否被修改
let isPreEdit = ref(false)

// 当前搜索匹配到第几个
let matchNum = ref(0)

// 拼接一个获取json文件的地址
const jsonUrl = computed(() => {

    // 这是亚马逊上面部署的一个pdfjs服务,及存放json文件的文件夹拼接地址
    const aws_server = 'http://xxx.s3-website-xxx.amazonaws.com/pdfjs-4.0.379-dist/web/docs/'

    // 从路由中获取到文件名称
    const json_name = route.query.json as string

    // 拼接得到最终的文件地址
    return `${aws_server}${json_name}`
})

// 监听jsonData,修改后需要动态更新文本框里显示的内容
watch(() => jsonData.value, val => {
    preJsonHtml.value = JSON.parse(JSON.stringify(val, null, 4))
})

// 监听搜索框的内容,主要目的是:当搜索框中的内容变化了,需要将matchNum重置为0,开始新输入内容的第一个搜索
watch(() => searchValue.value, val => {
    matchNum.value = 0
})

onMounted(() => {

    // 这里注意,需要使用nexttick,在页面渲染出来以后再做计算
    nextTick(() => {

        // json-pre
        var preTag = document.getElementById('json-pre');
        var originalContent = preTag?.textContent;

        // 添加监听事件
        preTag?.addEventListener('input', function() {

            if (preTag?.textContent !== originalContent) {

                console.log('内容已被修改');

                isPreEdit.value = true // 标记json被修改了
            }
        });
    })

    // 获取json文件,并赋值给jsonData
    fetch(jsonUrl.value).then(res => res.json()).then(r => {
        jsonData.value = JSON.stringify(r, null, 4)
    })
})
</script>

2.2 输入框回车事件

// 输入框回车事件
// 之所以使用这个方法,是因为input输入框在输入一个文字后,需要多次联系重复搜索
const handleEnter = (event) => {

    // 判断下jsonData的类型,需要一个字符串格式
    let result = typeof jsonData.value !== 'string' && JSON.stringify(jsonData.value) || jsonData.value

    // 正则表达式,对输入框中的内容全匹配
    const Reg = new RegExp(searchValue.value, 'g')

    // 获取这种全匹配下,有多少个匹配结果
    // 这一步非常重要,因为需要多次进行搜索和修改样式,所以必须要记录匹配结果
    let matchs = result.match(Reg)

    // 判断:
    // 匹配到结果 且 当前搜索到匹配结果的最后一位时,重新开始搜索第一个
    if((matchs && matchs.length) && matchNum.value + 1 >= matchs.length) {
        matchNum.value = 0
    }
    // 否则,继续向下
    matchNum.value += 1

    // 如果匹配有结果
    if(result) {

        // 定义一个替换方案
        // 将匹配结果替换为一个span标签,id为highLight,颜色为黄色
        let replacement = `<span id="highlight" style="background: yellow;">${searchValue.value}</span>`

        // 调用字符串匹配方法:在后文中有写
        const res = replaceNumMatch(Reg, result, replacement, matchNum.value);

        // preJsonHtml赋值,将它包裹在了一个div中
        preJsonHtml.value = `<div>${JSON.parse(JSON.stringify(res, null, 4))}</div>`

        /**
         * 这里是实现dom结构的滚动
         */
        const div = document.getElementById('json-pre');
        const span = document.getElementById('highlight');

        if (div && span) {
            // 计算滚动位置
            const scrollTo = span.offsetTop - div.offsetTop - 10; // 这里多了一个10px的间距
            
            // 滚动到指定位置

            // 当搜索第一个时,滚动到顶部
            if(matchNum.value === 1) {
                div.scrollTop = 0
                return
            }
            // 其它滚动到指定为止
            div.scrollTop = scrollTo;
        }
    }
}

2.3 正则表达式进行字符串匹配和替换方法

/**
 * 使用正则表达式进行字符串替换的方法
 */
function replaceNumMatch(regexp, str, replacement, i) {

    let count = 0;

    return str.replace(regexp, function(matched) {
        count++;
        if (count === i) {
            return replacement; // 替换第i个匹配字符为指定的字符串
        } else {
            return matched; // 保持其他匹配字符不变
        }
    });
}

2.4 json对话框编辑取消方法

/**
 * 取消方法:
 * 这里的要求是,当json被修改后退出需要提醒
 * 所以这里增加了一个isPreEdit的变量,标记json是否被修改
 */
const handleCancle = () => {

    if(isPreEdit.value) {
        // 如果被修改增加提醒
        ElMessageBox.confirm('内容有修改,是否进行保存?', '提示',
            {
                confirmButtonText: '是',
                cancelButtonText: '否',
                type: 'warning',
                closeOnClickModal: false,
                showClose: false
            }).then(() => {

                // do something 

                // 如可以保存数据等

            }).catch(() => {
                // 否则 跳转到指定路由
                router.push({ path: '/xxx' })
            })
        return
    }

    // 如果没有被修改,则跳转到指定路由
    router.push({ path: '/xxx' })
}

第三步:样式

pre在文字过长时,不换行。此处的目的是为了让长段的pre换行

<style lang="scss" scoped>

// 让pre里的文字自动换行
pre {
    white-space: pre-wrap;
    white-space: -moz-pre-wrap;
    white-space: -pre-wrap;
    white-space: -o-pre-wrap;
    word-wrap: break-word;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/533027.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

R: 支持向量机(Support Vector Machine,简称SVM)

在数据科学和机器学习领域中&#xff0c;支持向量机&#xff08;Support Vector Machine&#xff0c;简称SVM&#xff09;是一种强大的监督学习算法&#xff0c;常用于分类和回归分析。它的优点之一是可以适用于复杂的数据集&#xff0c;并且在高维空间中表现良好。在本文中&am…

基于java的某超市进销存管理系统

开发语言&#xff1a;Java 框架&#xff1a;ssm 技术&#xff1a;JSP JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclip…

智慧公厕中的大数据、云计算和物联网技术引领未来公厕管理革命

现代社会对于公共卫生和环境保护的要求越来越高&#xff0c;智慧公厕作为城市基础设施建设的重要组成部分&#xff0c;正引领着公厕管理的革命。随着科技的不断进步&#xff0c;大数据、云计算和物联网技术的应用为智慧公厕带来了全新的可能性&#xff0c;&#xff08;ZonTree中…

element-ui的按需引入报错解决:MoudleBuildFailed,完整引入和按需引入

官网&#xff1a; Element - The worlds most popular Vue UI framework 1.完整引入 &#xff08;1&#xff09;下载&#xff1a; npm i element-ui -S &#xff08;2&#xff09;引入&#xff1a; 在 main.js 中写入以下内容&#xff1a; import Vue from vue; impor…

Flutter Your project requires a newer version of the Kotlin Gradle plugin

在开发Flutter项目的时候,遇到这个问题Flutter Your project requires a newer version of the Kotlin Gradle plugin 解决方案分两步: 1、在android/build.gradle里配置最新版本的kotlin 根据提示的kotlin官方网站搜到了Kotlin的最新版本是1.9.23,如下图所示: 同时在Ko…

web APIs总结(2)

1. 页面滚动事件 很多网页需要检测用户把页面滚动到某个区域后做一些处理&#xff0c; 比如固定导航栏、返回顶部事件名&#xff1a;scroll监听某个元素的内部滚动直接给某个元素加即可 获取位置 scrollLeft和scrollTop &#xff08;属性&#xff09; &#xff08;注&#xf…

智能时代中的工业应用中前所未有的灵活桥接和I/O扩展功能解决方案MachXO2系列LCMXO2-1200HC-4TG100I FPGA可编程逻辑IC

lattice莱迪斯 MachXO2系列LCMXO2-1200HC-4TG100I超低密度FPGA现场可编程门阵列&#xff0c;适用于低成本的复杂系统控制和视频接口设计开发&#xff0c;满足了通信、计算、工业、消费电子和医疗市场所需的系统控制和接口应用。 瞬时启动&#xff0c;迅速实现控制——启动时间…

ORCAL SQLPLUS上机6-1

SQL> declare2 v_num number:9;3 begin4 v_num:v_num1;5 dbms_output.put_line(v_num);6 end;7 / --定义记录类型&#xff0c;类似结构体&#xff0c;用select...into --定义记录类型&#xff0c;类似结构体&#xff0c;用select...into SQL> declaretype employe…

OVITO-2.9版本

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

蓝桥杯刷题 二分-[2145]求阶乘(C++)

问题描述 满足 N! 的末尾恰好有 K 个 0 的最小的 N 是多少? 如果这样的 N 不存在输出 −1。 输入格式 一个整数 K。 输出格式 一个整数代表答案。 样例输入 2 样例输出 10 评测用例规模与约定 对于 30% 的数据&#xff0c;1 ≤ K ≤ 10的6次方 对于 100% 的数据&…

云手机解决海外社媒运营的诸多挑战

随着海外社交媒体运营的兴起&#xff0c;如何有效管理多个账户成为了一项挑战。云手机作为一种新兴的解决方案&#xff0c;为海外社媒运营带来了前所未有的便利。 云手机的基本原理是基于云计算和虚拟化技术&#xff0c;允许用户在物理手机之外创建和使用多个虚拟手机。这种创新…

嵌入式学习52-ARM1

知识零散&#xff1a; 1.flash&#xff1a; nor flash 可被寻地址 …

SOCKS代理概述

在网络技术的广阔领域中&#x1f310;&#xff0c;SOCKS代理是一个核心组件&#xff0c;它在提升在线隐私保护&#x1f6e1;️、实现匿名通信&#x1f3ad;以及突破网络访问限制&#x1f6ab;方面发挥着至关重要的作用。本文旨在深入探讨SOCKS代理的基础&#xff0c;包括其定义…

FPGA - 以太网UDP通信(一)

一&#xff0c;简述以太网 以太网简介 ​以太网是一种计算机局域网技术。IEEE组织的IEEE 802.3标准制定了以太网的技术标准&#xff0c;它规定了包括物理层的连线、电子信号和介质访问层协议的内容。 ​ 以太网类型介绍 以太网是现实世界中最普遍的一种计算机网络。以太网有…

python篇---图片转成视频

python篇—图片转成视频 import cv2 import os# 设置图片文件夹路径和视频输出路径 image_folder /workspace/11 video_name output_video.mp4# 获取图片文件夹中的所有图片文件名&#xff0c;并按顺序排序 images [img for img in os.listdir(image_folder) if img.endswi…

SSH穿透ECS访问内网RDS数据库

处于安全考虑&#xff0c;RDS一般只会允许指定的IP进行访问&#xff0c;而我们开发环境的IP往往是动态的&#xff0c;每次IP变动都需要去修改RDS的白名单&#xff0c;为我们的工作带来很大的不便。 那么如何去解决这个问题&#xff1f; 假如我们有一台ESC服务器&#xff0c;E…

虹科Pico汽车示波器 | 免拆诊断案例 | 2011款东风悦达起亚K5车发动机偶尔起动困难

一、故障现象 一辆2011款东风悦达起亚K5车&#xff0c;搭载G4KD发动机&#xff0c;累计行驶里程约为24.5万km。车主反映&#xff0c;第1次起动发动机时偶尔无法起动着机&#xff0c;第2次能够正常起动着机&#xff0c;但发动机故障灯异常点亮。为此在其他维修厂维修过&#xf…

java Web课程管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 课程管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使用ja…

【PDF.js】PDF文件预览

【PDF.js】PDF文件预览 一、PDF.js二、PDF.js 下载1、下载PDF.js2、在项目中引入3、屏蔽跨域错误 三、项目中使用四、说明五、实现效果 使用PDFJS实现pdf文件的预览&#xff0c;支持预览指定页、关键词搜索、缩略图、页面尺寸调整等等。 一、PDF.js 官方地址 文档地址 二、PD…

SpringCloudAlibaba-整合sleuth和zipkin(六)

目录地址&#xff1a; SpringCloudAlibaba整合-CSDN博客 一、整合sleuth 1.引入依赖 在需要追踪的微服务中引入依赖&#xff0c;user、order、product <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter…