开发智联笔记项目时的js问题

问题分析

应用需要以下JS文件:

  • jsmind.js - 核心脑图库
  • jsmind.draggable.js - 拖拽功能
  • jsmind.undo.js - 撤销重做功能

解决方案

1. 获取缺失的JS文件

需要下载这些JS文件并放在 static 目录下:

jsmind.js - 核心文件
可以从官方仓库获取:https://github.com/hizzgdev/jsmind

jsmind.draggable.js - 拖拽插件

// jsmind.draggable.js
(function(){if(!window.jsMind) throw new Error('jsMind is not defined');var jm = window.jsMind;jm.draggable = function(jm){this.jm = jm;this.selected_node = null;this.moving = false;this.offset_x = 0;this.offset_y = 0;this.init();};jm.draggable.prototype = {init: function(){var container = this.jm.view.container;container.addEventListener('mousedown', this.mousedown_handler.bind(this));container.addEventListener('mousemove', this.mousemove_handler.bind(this));container.addEventListener('mouseup', this.mouseup_handler.bind(this));container.addEventListener('touchstart', this.touchstart_handler.bind(this));container.addEventListener('touchmove', this.touchmove_handler.bind(this));container.addEventListener('touchend', this.touchend_handler.bind(this));},mousedown_handler: function(e){if(e.button !== 0) return;var node = this.find_node(e);if(!node) return;this.start_drag(node, e.clientX, e.clientY);e.stopPropagation();e.preventDefault();},mousemove_handler: function(e){if(!this.moving) return;this.drag(e.clientX, e.clientY);e.stopPropagation();e.preventDefault();},mouseup_handler: function(e){if(!this.moving) return;this.end_drag();e.stopPropagation();e.preventDefault();},touchstart_handler: function(e){if(e.touches.length !== 1) return;var touch = e.touches[0];var node = this.find_node(touch);if(!node) return;this.start_drag(node, touch.clientX, touch.clientY);e.stopPropagation();e.preventDefault();},touchmove_handler: function(e){if(!this.moving || e.touches.length !== 1) return;var touch = e.touches[0];this.drag(touch.clientX, touch.clientY);e.stopPropagation();e.preventDefault();},touchend_handler: function(e){if(!this.moving) return;this.end_drag();e.stopPropagation();e.preventDefault();},find_node: function(e){var target = e.target;while(target && target !== this.jm.view.container){if(target.nodeName.toLowerCase() === 'jmnode'){var node_id = target.getAttribute('nodeid');return this.jm.get_node(node_id);}target = target.parentNode;}return null;},start_drag: function(node, client_x, client_y){this.selected_node = node;this.moving = true;var view_data = this.jm.view.get_node_view_data(node.id);this.offset_x = client_x - view_data.abs_x;this.offset_y = client_y - view_data.abs_y;this.jm.view.select_node(node);},drag: function(client_x, client_y){if(!this.moving || !this.selected_node) return;var x = client_x - this.offset_x;var y = client_y - this.offset_y;this.jm.view.move_node(this.selected_node, x, y);},end_drag: function(){this.moving = false;this.selected_node = null;}};jm.plugin.draggable = jm.draggable;
})();

jsmind.undo.js - 撤销重做插件

// jsmind.undo.js
(function(){if(!window.jsMind) throw new Error('jsMind is not defined');var jm = window.jsMind;jm.undo = function(jm){this.jm = jm;this.stack = [];this.index = -1;this.max_stack_size = 100;this.init();};jm.undo.prototype = {init: function(){this.jm.add_event_listener(this.event_handler.bind(this));// 绑定快捷键var self = this;document.addEventListener('keydown', function(e){if((e.ctrlKey || e.metaKey) && !e.altKey){if(e.keyCode === 90){ // Ctrl+Zif(e.shiftKey) self.redo();else self.undo();e.preventDefault();}else if(e.keyCode === 89){ // Ctrl+Yself.redo();e.preventDefault();}}});},event_handler: function(type, data){if(type === 'edit' || type === 'add_node' || type === 'remove_node' || type === 'move_node' || type === 'resize'){this.push_snapshot();}},push_snapshot: function(){// 移除当前索引之后的所有记录this.stack = this.stack.slice(0, this.index + 1);// 添加新快照var snapshot = this.jm.get_data();this.stack.push(snapshot);// 限制栈大小if(this.stack.length > this.max_stack_size){this.stack.shift();}this.index = this.stack.length - 1;},undo: function(){if(this.index <= 0) return;this.index--;var snapshot = this.stack[this.index];this.jm.show(snapshot);},redo: function(){if(this.index >= this.stack.length - 1) return;this.index++;var snapshot = this.stack[this.index];this.jm.show(snapshot);},clear: function(){this.stack = [];this.index = -1;}};jm.plugin.undo = jm.undo;
})();

2. 创建项目目录结构

项目结构如下:

your_project/
├── app.py
├── templates/
│   ├── index.html
│   ├── login.html
│   └── register.html
└── static/├── jsmind.js├── jsmind.draggable.js├── jsmind.undo.js├── jsmind.css└── all.min.css

3. 数据库配置

确保MySQL数据库已创建:

CREATE DATABASE zhilian CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

4. 安装依赖

pip install flask flask-login flask-sqlalchemy flask-cors pymysql

5. 启动应用

python app.py

验证解决方案

  1. 访问 http://localhost:5000
  2. 注册新用户并登录
  3. 创建新的脑图文件
  4. 测试脑图的各项功能(添加节点、编辑、拖拽、撤销重做等)

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

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

相关文章

nju实验一选择器

本次实验将介绍几种常用的多路选择器的设计方法;Verilog语言中的always语句块、if-else语句和case语句的使用等。最后请读者自行设计一个多路选择器,熟悉电路设计的基本流程和Quartus的使用。实验一选择器 2选1多路选…

上海金蝶代理商推荐——上海宝蝶信息技术有限公司

一、企业概况 上海宝蝶信息技术有限公司成立于2016年,总部位于上海市松江区,是金蝶集团在上海地区的铂金合作伙伴,专注服务于国内ERP应用市场。 公司深耕中小制造企业全栈数字化服务,以金蝶云PLM+ERP、灵当CRM、致…

11.21模拟赛

T1 分层图板子,代码在 luogu。 T2 给定长度为 \(n\) 的数列 \(a\),维护 \(m\) 次操作,每次操作包括以下两种:1 x:要求输出包含 \(a_x\) 的最大子段和,即求 \(\max_{1 \leq l \leq x \leq r \leq n} \left\{ \sum…

HTML---------------图片转换(草稿)

<!DOCTYPE html> <html><head><meta charset="utf-8"><title>童心少年</title></head><body> <h1 onclick = "updateimage()">点击一下…

爱与时间反应鲜红色慢慢退却 一次次重复直到忘记了誓言

test45 今天怎么第一版 t1/t2 都是假的(构造字符串 数据范围不是特别大直接改条件 \(a_i=a_j/a_i\neq a_j\),你并查集前一种之后看一下符不符合第二种,如果符合的话肯定有解,比方说你考虑每个连通块给不同颜色。 注…

Mac 安装 JDK 8u281(JDK-8u281-1.dmg)详细步骤(附安装包)

Mac 安装 JDK 8u281(JDK-8u281-1.dmg)详细步骤(附安装包)​一、准备工作下载文件 安装包下载:https://pan.quark.cn/s/24c8755b74f0 ,下载了 JDK-8u281-1.dmg文件,它一般是个安装包。找到文件 打开你的 “下载”…

chrome: 允许远程调试

一,默认不能从远程访问chrome的调试端口: 例子: $ google-chrome --remote-debugging-port=9222 --user-data-dir=/data/python/xianyu/userdata 通过局域网ip访问:本地可以访问:二,通过端口转发供远程访问 $ soca…

Agent skills 实战

背景: 通过编码方式编写符合规范的ofd文件。 过程:通过调研,锁定使用 ofdrw和easyofd两种 java ofd生成工具上,最终选择easyofd组件(大模型不认识该组件)。那接下来遇到的问题是,大模型不知道怎样使用这两种组件。…

Vue 路由的学习

Vue 路由完全指南 Vue路由完全指南:从基础到实战,轻松掌握页面跳转核心 在Vue开发中,路由是实现单页面应用(SPA)页面切换的核心技术。无论是Vue2还是Vue3,路由都扮演着"导航指挥官"的角色,负责管理不…

P8809 [蓝桥杯 2022 国 C] 近似 GCD 题解

考虑到非常困难。再简单的计数题也要认真看一眼。 P8809 [蓝桥杯 2022 国 C] 近似 GCD 思路 考虑刻画充要条件去计数。发现一个子区间合法的充要条件是至多一个数不是 \(g\) 的倍数。 将不是 \(g\) 倍数的东西看作 1,…

推荐一款超级好用的命令行工具 http-server

推荐一款超级好用的命令行工具 http-server前言很多时候前端开发的项目需要放到线上才能出现一些问题,本地环境看不出来,此时很多小伙伴可能会喜欢用Live Serve来启动本地项目,但是部分框架打包的dist包无法通过Liv…

J 组要考,S 组也要考

在 CSP 竞赛中,J 组与 S 组是两项并行的赛事。在竞赛生涯中,许多人可能会认为只需专注其中一组即可,认为另一组无关紧要。然而,实际上,这两者都至关重要:J 组要考,S 组同样也要考。 正如鲁迅先生所言:“紫题是…

估值 7 亿美元,Wispr 要做语音操作系统,还要自研 ASR;马斯克:实时视频理解和生成是未来丨日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的技术」、「有亮点的产品」、「有思考的文章」、「有态…

AI浪潮下的新动向:协作、法律与未来工作

最近刷新闻,发现AI领域又炸开锅了。从OpenAI的群聊功能到商标纠纷,再到马斯克对未来的大胆预测,这些事件不仅让我这个学软件工程的看得津津有味,还引发了不少关于技术发展和就业的思考。先说说OpenAI的新功能“群聊…

day11-Dify智能体-发布-工作流

今日内容 1 对接大模型 # 0 Coze 是一个成熟的商业软件-咱们用户只需要访问地址--》直接使用 --》本身集成了大模型-豆包、deepseek大模型,插件:图像生成---》使用扣token-更适合小白-Coze 用gpt模型?用不了,没有提…

puff-pastry靶机

在探姬老师那里看到的一个内网渗透靶场,作为入门靶场挺好的,也是第一次打这种多层内网的靶场首先先将docker镜像拉起来 docker-compose up -ddocker ps -a用这个命令看看容器都跑起来没有,如果stastus都显示"u…

day27-MCP进阶

四、SSE传输方式的MCP服务器创建流程 以上MCP服务器都是stdio传输方式,而除此之外,目前MCP服务器还支持SSE传输和基于HTTP的流式传输。这两种传输方式也有非常广泛的实际用途,接下来详细介绍如何构建基于SSE和HTTP流…

Day37:2025年10月27日,星期一,上班。

今天照常开周例会,安排了一堆应知应会内容,需要尽快熟悉。一把年纪了,还要记这些,早些年要这么努力,清华北大都考上了。这或许就是所谓的少壮不努力老大徒伤悲。 ​​​

Day36:2025年10月26日,星期天,休息。

星期六出差回来,出差积压了几天的快递了,一次性拆了一堆,买了一件凯乐石的mont-x,非常不错,丝毫不比鸟差多少嘛,他的越野跑鞋fuga系列也非常火,我看户外越野跑的大神们人手一双。

Day42:2025年11月1日,星期六,值班,诸事皆顺。

今天家里厨房又添置一员大将,微蒸烤炸一体机,还可以联网查看食谱制作美食,这个太好了,我的微波炉、烤箱、蒸锅、空气炸锅都可以扔了。瞬间厨房就极简了,必须吹爆,非常满意。