附录5-大事件项目前端

news2025/3/10 11:26:23

目录

1  前言

2  用到的插件

2.1  截取图像 cropper

2.2  富文本编辑器 tinymce

3  项目结构

4  config.js

5  主页

5.1  iframe

5.2  页面的宽高

5.3  修改文章

6  个人中心-基本资料

7  个人中心-更换头像

8  个人中心-更换密码

9  文章管理-文章分类

10  文章管理-文章列表

11  文章管理-发布文章

12  文章列表-编辑文章


1  前言

前端视频地址 【前端第四阶段】前后端交互-大事件后台管理系统项目(第三部分)_哔哩哔哩_bilibili

前端代码地址

链接:百度网盘 请输入提取码 提取码:q0pq

视频中用layui快速写静态页面,我没有使用layui,部分功能使用了其他框架

在写的时候使用了插件 live server,这样能在修改后就得到反馈

在调试的时候使用了插件 express,后续要上传uploads,如果使用live server,每一次上传成功后都会刷新页面,这样就得不到我们想要的效果了

live server与express的用法可以看一下这个 附录5-vscode常用配置_Suyuoa的博客-CSDN博客

写前端的时候如果不用框架,工作量是十分巨大的,而且有时会出一些问题(且在样式上不会好看),比如传递base64字符串的时候,使用xhr的默认配置发送就不行,使用jQuery就可以直接发送

在iframe中,可以通过window.parent.主页面方法 来调用主页面的方法

base64字符串直接放在img的src中就能用,base64在前端中可以完全替代路径索引图片,好处是不需要进行额外的请求了,坏处是html文件会变大,经过Base64 编码后的文件体积一般比源文件大 30% 左右。

在这个网址上可以手动将 图像 转为base64 格式 图片在线转换Base64,图片编码base64

img src可以直接显示出存储的blob文件,在编辑文章的时候会有提到

请求的时候要不就一直用xhr请求,要不就一直用jQuery请求,如果既出现了xhr请求,又出现了jQuery请求,有时会有冲突

有的时候我们需要让JS执行完一些指令,再执行一些指令,试了好多个方法,总的来讲还是搞一个定时器最好用,但像我项目中的定时器方法只是一种取巧的方法,定时器给的时间越长,我们的程序看起来就越稳定,速度也越慢,如果要搞一个鲁棒性高的程序,还是要搞很多个回调函数,使用到很多的flag,那样就代表这要有更多的代码,开发与维护更加费时

在iframe页面中使用location.href改变的是iframe的src,总的来说iframe页面中使用的location是他自己,而不是iframe的父级页面

2  用到的插件

2.1  截取图像 cropper

cropper可以截取图像上的一部分,并预览

我们可以将预览内容转换为 base64或blob

可以用node搞下来 cropper - npm

也可以在github上搞下来 GitHub - fengyuanchen/cropperjs: JavaScript image cropper.

我是从github上搞下来的,解压后拿 dist/cropper.min.js dist/cropper.min.css

使用的时候需要看文档,当前的使用方式与视频已经不一致了

我简单做个demo

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./cropperjs-main/dist/cropper.min.css">
    <style>
        .middle_img {
            position: absolute;
            left: 500px;
            top: 150px;
            display: inline-block;
        }

        .middle_img .w100 {
            width: 100px;
            height: 100px;
            border-radius: 50%;
            overflow: hidden;
        }

        .middle_img p {
            margin-top: 10px;
            text-indent: 20px;
        }

        .big_img {
            position: absolute;
            width: 400px;
            height: 400px;
        }

        .big_img img {
            display: block;
            max-width: 100%;
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div class="big_img">
        <img src="./AJAX.jpg">
    </div>
    <div class="middle_img">
        <div class="img-preview w100"></div>
        <p class="size">100 x 100</p>
    </div>
</body>
<script src="./cropperjs-main/dist/cropper.min.js"></script>
<script>
    const image = document.querySelector('.big_img img');
const cropper = new Cropper(image, {
  //   aspectRatio: 16 / 9,
  aspectRatio: 1 / 1,
  //   crop(event) {
  //     console.log(event.detail.x);
  //     console.log(event.detail.y);
  //     console.log(event.detail.width);
  //     console.log(event.detail.height);
  //     console.log(event.detail.rotate);
  //     console.log(event.detail.scaleX);
  //     console.log(event.detail.scaleY);
  //   },
  preview: '.img-preview'
});
</script>

</html>

2.2  富文本编辑器 tinymce

富文本编辑器可以使用用tinymce,中文文档地址 TinyMCE中文文档中文手册 在这个文档中有下载地址

我简单做个demo

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <textarea name="" id="tinydemo2" cols="30" rows="10"></textarea>
</body>
<script src="./tinymce/js/tinymce/tinymce.min.js"></script>
<script>
    tinymce.init({
        selector: '#tinydemo2',
        //skin:'oxide-dark',
        language: 'zh_CN',
        plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave bdmap indent2em autoresize formatpainter axupimgs',
        toolbar: 'code undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
    styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
    table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | bdmap indent2em lineheight formatpainter axupimgs',
        height: 650, //编辑器高度
        min_height: 400,
        /*content_css: [ //可设置编辑区内容展示的css,谨慎使用
            '/static/reset.css',
            '/static/ax.css',
            '/static/css.css',
        ],*/
        fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px',
        font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;',
        link_list: [
            { title: '预置链接1', value: 'http://www.tinymce.com' },
            { title: '预置链接2', value: 'http://tinymce.ax-z.cn' }
        ],
        image_list: [
            { title: '预置图片1', value: 'https://www.tiny.cloud/images/glyph-tinymce@2x.png' },
            { title: '预置图片2', value: 'https://www.baidu.com/img/bd_logo1.png' }
        ],
        image_class_list: [
            { title: 'None', value: '' },
            { title: 'Some class', value: 'class-name' }
        ],
        importcss_append: true,
        //自定义文件选择器的回调内容
        file_picker_callback: function (callback, value, meta) {
            if (meta.filetype === 'file') {
                callback('https://www.baidu.com/img/bd_logo1.png', { text: 'My text' });
            }
            if (meta.filetype === 'image') {
                callback('https://www.baidu.com/img/bd_logo1.png', { alt: 'My alt text' });
            }
            if (meta.filetype === 'media') {
                callback('movie.mp4', { source2: 'alt.ogg', poster: 'https://www.baidu.com/img/bd_logo1.png' });
            }
        },
        toolbar_sticky: true,
        autosave_ask_before_unload: false,
    });
</script>

</html>

获取与设置内容的时候不能再使用textarea.value,而是要使用他内置的方法

  • 获取 tinymce.activeEditor.getContent()
  • 设置 tinymce.activeEditor.setContent(),括号内为要设置的内容

3  项目结构

入口为index.html或login.html,文件夹index_iframe存放的都是主页的子页面

4  config.js

在js文件夹中,有一个config.js作为配置文件,在配置文件中,做了请求的一些信息

比如请求根路径,统一请求根路径还是很有必要的,如果后端的端口换了,如果你不统一,你就得一个一个去改

还有就是身份校验,先从浏览器的locatStorage中拿token,去给后端校验,如果能校验成功就向后端请求用户信息,如果不成功就删除token,然后返回登陆页面

// 请求根路径
request_root = 'http://127.0.0.1'

// 身份校验
function wrong_login() {
    localStorage.removeItem('token')
    if (!(/\/login/.test(location.href))) {
        location.replace('login.html')
    }
}

function make_sure_token(callback) {
    token = localStorage.getItem('token')
    if (token) {
        xhr = new XMLHttpRequest()
        xhr.open('GET', request_root + '/my/userinfo')
        xhr.setRequestHeader('Authorization', token)
        xhr.send()
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                const response = JSON.parse(xhr.responseText)
                const status = response.status
                if (status == 0) {
                    userdata = response.data
                    callback()
                    
                }
                else {
                    wrong_login()
                }
            }
        }
        xhr.onerror = function() {
            wrong_login()
        }
    }
    else {
        wrong_login()
    }
}

登陆页比较简单就不赘述了

5  主页

5.1  iframe

点击左侧不同的导航,在右面会出现不同的页面,主页默认的iframe是用echarts做的图表,在这里有介绍 附录3-大事件项目涉及到的图表_Suyuoa的博客-CSDN博客

我们只需要改变iframe的src属性就可以了,默认状态是首页的html

这里的sandbox目的只是为了让iframe的alert()能弹出来,在项目上实际并没有用到

5.2  页面的宽高

左侧导航栏的宽是固定的,高随着页面的变化而变化,顶部的高度是固定的60px,这里多减1px在视觉上差不多,会避免很多问题

内容部分也是一样

使用JS来动态影响组件宽高的时候,要在body中加入overflow:hidden,要不然又可能进度条会对效果产生影响,使用overflow:hidden就没有进度条了

5.3  修改文章

修改文章并没有在左侧的导航栏内出现,他的入口是文章列表中的编辑

文章列表本身是一个iframe,从文章列表发一个信号给父网页index.html

然后在index.html中接收,拿到接收信息后改变iframe的src,然后再发一个信号给 编辑文章的iframe

在编辑文章的网页中再进行接收,从而渲染到页面上

6  个人中心-基本资料

这里使用了一个网上的关于邮箱验证的字符串,测了测还可以,如果在别的项目中没有具体要求,我们就可以直接用这个正则

  • !(/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/.test(email_input.value))

修改完毕后reload()自己

在index.js中注册了一个时间,当iframe刷新的时候,重新获取头像与昵称,然后进行渲染

7  个人中心-更换头像

我们是点击上传按钮更换图像,实际上点击按钮的同时相当于点击了这个隐藏的input,通过这个input选择的文件

检测input的改变时间,通过事件对象拿到选择的文件,这个时候会有直接点×的情况,那么文件列表长度就是0,就算了,如果确实选择了文件,那么通过将文件转换为flie_url,然后用cropper的方法替换掉原来的

当点击确认更换头像后,通过cropper的getCroppedCanvas()方法,将被选中的区域变为指定大小的canvas,然后再用canvas内置方法toDataURL将canvas转变为base64字符串

在发送base64字符串的时候,用之前XHR方法直接发会很麻烦,这里建议使用$.ajax

8  个人中心-更换密码

这里是通过大量的空白占位符搓出来,如果事件不紧的话还是建议用独立的类名,然后text-indent

9  文章管理-文章分类

这里的添加类别是做了个样式

这个搞的并不是很好看,其实他不应该属于这一层,如果不用框架工作量有点儿大,我就简单搞了搞

这个原生JS拖动窗口可以看一下

10  文章管理-文章列表

搞了四个全局变量,通过传入不同的变量,来控制不同的结果

每次刷新的时候,先更新目录,再更新文章

因为后台给的只是分类id,而不是分类名称,我们需要动态去索引

当页数过多的时候,这里会无限往后排,中间...这种功能我没做

编辑文章在主页部分介绍过了

11  文章管理-发布文章

在这里用了一个中文包

处理blob()图像只能用这个方法,这个也是官方给的方法,canvas.toBlob()参数为一个函数,函数中有一个形参就是blob

发formdata的时候直接发就行了,拿tinymce的内容使用tinymce.activeEditor.getContent()

12  文章列表-编辑文章

编辑文章相对于发布文章,多了一个把信息渲染到页面上的功能

点的哪个编辑按钮,就会得到信息,tinymce用tinymce.activeEditor.setContent()加载信息

blob直接放在img是src中就可以了,数据库中存的信息是这样的

存的本地路径在这

所以我们不用进行处理,直接使用就可以了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot集成kafka(环境搭建+演示)|超级详细,建议收藏

Springboot集成kafka一、前言&#x1f525;二、环境说明&#x1f525;三、概念&#x1f525;四、CentOS7安装kafka&#x1f525;1.下载kafka安装包2.下载好后&#xff0c;进行解压六、kafka项目集成&#x1f525;1️⃣pom引入2️⃣配置kafka3️⃣一个kafka消息发送端4️⃣定义一…

MySQL45讲笔记04深入浅出索引上

索引的目的: 索引的出现其实就是为了提高数据查询的效率&#xff0c;就像书的目录一样。常见索引模型&#xff1a; hash表&#xff0c;以K-V键值对的形式的一种数据结构&#xff0c;底层是数组加链表形式。通过一定的hash运算找到数据合适的位置放入&#xff0c;如果放入的位置…

[jetson]paddlepaddle2.4.0在jetpack5.0.2源码编译流程

由于官方暂时没有提供jetson对应的jetson jetpack5.0.2预编译包&#xff0c;因此只有源码编译&#xff0c;本次编译不带Tensorrt,编译已经顺利成功&#xff0c;注意本次使用的设备是jetson NX 测试环境&#xff1a; ubuntu20.04 jetpack5.0.2 GCC-8.4 Software part of jet…

Centos7搭建NFS

1.NFS简介Network File System(网络文件系统&#xff0c;通过网络让不同的机器系统之间可以彼此共享文件和目录&#xff0c;类似Samba服务。2.NFS挂载原理 在网络中服务器和客户端进行连接都是通过端口进行数据传输&#xff0c;而NFS服务端的端口是随机的&#xff0c;从而导致N…

Linux----网络基础(2)--应用层的序列化与反序列化--守护进程--0226

文章中有使用封装好的头文件&#xff0c;可以在下面连接处查询。 Linux相关博文中使用的头文件_Gosolo&#xff01;的博客-CSDN博客 1. 应用层 我们程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层 1.2 协议 我们在之前的套接字编程中使用的是…

最适合你的团队云协作工具

团队云协作工具哪个好&#xff1f;使用Zoho Projects的团队云协作软件套件&#xff0c;在一个平台上无缝协作&#xff0c;激励您的团队在任何地方以最好的状态完成他们的工作。 使您的团队能够使用团队云协作软件在任何地方进行协作和沟通。Zoho Projects提供了一套强大…

三天吃透计算机网络八股文

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

一文读懂光学天线

天线&#xff0c;按维基百科的定义&#xff0c;"是一种用来发射或接收无线电波—或更广泛来讲—电磁波的器件"。例如&#xff0c;在无线通信系统中&#xff0c;天线被用于发射与接收射频与微波波段的电磁波。而在我们的智能手机中&#xff0c;就有内置的平面倒F天线(…

01-认识产品经理

文章目录引入1.1 合格的产品经理1.2 产品经理的分类按服务对象不同划分按产品平台不同划分按公司所属行业不同按工作内容划分按职级高低划分1.3 产品经理的岗位职责产品的开发流程核心团队成员及其职责产品经理工作中常见误区1.4 产品经理的能力素质专业技能&#xff08;干得了…

Unity Lighting -- 配置平行光源和天空盒

识别不同种类的光源 在游戏或实时应用程序中&#xff0c;我们可能会创建多种不同种类的场景&#xff0c;比如室内场景、室外场景、真实的场景或完全想象的场景。即便项目是一个完全的想象的或是科幻的故事&#xff0c;灯光也是非常重要的一环&#xff0c;它能极大提升沉浸感。 …

Python3-条件控制

Python3 条件控制 Python 条件语句是通过一条或多条语句的执行结果&#xff08;True 或者 False&#xff09;来决定执行的代码块。 可以通过下图来简单了解条件语句的执行过程: 代码执行过程&#xff1a; if 语句 Python中if语句的一般形式如下所示&#xff1a; if condi…

Atlassian Server用户新选择 | 数据中心产品是否适合您的企业(3)?

2024年2月&#xff0c;也就是一年不到&#xff0c;Atlassian将终止对Server产品及插件的所有支持。 此公告发布后&#xff0c;许多用户需要了解怎样的前进方向才是最适合企业的。为此&#xff0c;Atlassian不仅提供云版&#xff0c;还提供了本地部署的数据中心&#xff08;Data…

jupyter lab安装和配置

jupyter lab 安装和配置 一、jupyter lab安装并配置 安装jupyterlab pip install jupyterlab启动 Jupyter lab默认会打开实验环境的&#xff0c;也可以自己在浏览器地址栏输入127.0.0.1:8888/lab 汉化 pip install jupyterlab-language-pack-zh-CN刷新一下网页&#xff0…

ChatGPT解答:PYQT5 组件化实例,Python代码实现,给出100个代码实例

ChatGPT解答&#xff1a; PYQT5 组件化实例&#xff0c;Python代码实现&#xff0c;给出100个代码实例 PYQT5 组件化实例&#xff0c;Python代码实现&#xff0c;给出100个代码实例 实现一个简单的窗口 import sys from PyQt5.QtWidgets import QApplication, QWidgetapp QA…

我90后,零基础成功转行python工程师,从月薪5K到现在月入2W+改变真的难吗?

我是25岁转行学python的。说实在&#xff0c;转行就是奔着挣钱去的。希望我的经历可以给想转行的朋友带来一点启发和借鉴。 先简单介绍下个人背景&#xff0c;三流大学毕业&#xff0c;物流专业&#xff0c;学习能力一般&#xff0c;没啥特别技能&#xff0c;反正就很普通的一…

CSS3新特性-变量

2017年三月&#xff0c;微软宣布 Edge 浏览器将支持 CSS 变量。 这个重要的 CSS 新功能&#xff0c;所有主要浏览器已经都支持了。本文全面介绍如何使用它&#xff0c;你会发现原生 CSS 从此变得异常强大。 一、变量的声明 声明变量的时候&#xff0c;变量名前面要加两根连词…

python入门应该怎么学习

国外Python的使用率非常高&#xff0c;但在国内Python是近几年才火起来&#xff0c;Python正处于高速上升期市场对于Python开发人才的需求量急剧增加&#xff0c;学习Python的前景比较好。 Python应用领域广泛&#xff0c;意味着选择Python的同学在学成之后可选择的就业领域有…

虚函数与多态性

5.1多态性概述&#xff1a; 按实施的机制&#xff0c;多态可以分为两类&#xff1a; 虚函数的定义&#xff1a; &#xff08;前面思维是虚基类&#xff0c;别搞混了&#xff09; 运行时多态的条件&#xff1a; 运行时的多态&#xff1a; 基类中有show(),派生类中也有show&…

叠氮化物标记糖92659-90-0,2-[(Azidoacetyl)amino]-2-deoxy-D-glucose广泛用于体内代谢标记

基础产品数据&#xff1a;CAS号&#xff1a;92659-90-0中文名&#xff1a;2-[(叠氮基乙酰基)氨基]-2-脱氧葡萄糖英文名&#xff1a;2-[(Azidoacetyl)amino]-2-deoxy-D-glucose性 状&#xff1a;白色粉末温馨提示&#xff1a;所有的试剂仅用于科研实验。结构式&#xff08;Struc…

ChatGPT解答:纯前端文档预览,Vue实现,无需后端,支持Word、Excel、PPT、pdf、文本、图片,附接入demo和文档

ChatGPT解答&#xff1a;纯前端文档预览&#xff0c;Vue实现&#xff0c;无需后端&#xff0c;支持Word、Excel、PPT、pdf、文本、图片&#xff0c;附接入demo和文档 ChatGPTDemo Based on OpenAI API (gpt-3.5-turbo). 纯前端文档预览&#xff0c;Vue实现&#xff0c;无需后…