开源一个无后端也无前端彻底无服务的网页版记事本

2023-06-01 01:12:48 +08:00
 meeop

data:text/html;base64,PGh0bWwgY29udGVudGVkaXRhYmxlPmVkaXQgbWU8L2h0bWw+

复制到浏览器即可使用,可加书签,可分享,不需要网络,全平台可用

有时候需要有个地方临时复制粘贴一些东西,这时候可以用记事本,但是记事本或者其他文本编辑软件关闭时一般需要确认是否保存,且这些临时内容会和工作内容混合

还有个问题是记事本页面不够大,ui 也略复杂一点

这个网页版记事本就能支持这种场景,原则上不支持保存,随用随关,铺满全屏

而且我觉得最有意思的点是,这其实是一个彻底开源极端易于分享的软件形式,软件所有内容都塞到 url 数据里,所见即所得,无需安装,适配全平台,用户还能随时修改逻辑,无需网络,没有服务器成本

缺点是软件大小有限制 以及软件作者可能不太好赚钱

17332 次点击
所在节点    分享创造
150 条回复
meeop
2023-06-06 21:39:40 +08:00
@ixoy 不太一样,峰哥这个是在当前页面上下文注入一段 js 代码,更接近于浏览器插件

例如这个链接会 alert 当前页面的标题 javascript:alert(document.title)

不过浏览器限制挺狠的,这个链接不能复制粘贴到地址栏,只能手敲前面的 javascript:,或者编辑书签地址才能使用
不过有意思的点是它能访问当前页面上下文,可以拿来做页面插件和外挂功能
rookiebulls
2023-06-07 15:28:46 +08:00
```
data:text/html;charset=utf-8,<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> </head> <body style="margin: 0; height: 100vh"> <div id="container" style="width: 100%; height: 100%"></div> <script type="text/javascript" src="https://unpkg.com/monaco-editor@latest/min/vs/loader.js"></script> <script> require.config({ paths: { vs: "https://unpkg.com/monaco-editor@latest/min/vs" } }); require(["vs/editor/editor.main"], function () { monaco.editor.create(document.getElementById("container"), { language: "json", theme: "vs-dark", }); }); </script> </body> </html>
```

给个 vscode 版的
InkAndBanner
2023-06-08 15:30:48 +08:00
@Cheons #100 怎么规避审查呢?反骨 boy 十分感兴趣,这个记事本原则上不支持保存呀,除非 ctrl+s
meeop
2023-06-08 16:37:40 +08:00
@InkAndBanner 比如这样 data:text/html;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0iVVRGLTgiPgo8L2hlYWQ+CjxodG1sIGNvbnRlbnRlZGl0YWJsZT7ov5nmmK/kuIDmrrXpmZDliLbnuqflhoXlrrk8L2h0bWw+
xml123
2023-06-25 10:15:16 +08:00
@rookiebulls 这个不能适应浏览器窗口大小的变化,可以改进吗?另外 langugae 只能在地址里设置吗?
freepoint
2023-07-14 13:56:30 +08:00
@mokevip #61 文本 data:text/html;text,<html contenteditable>edit me</html> 是一段 HTML 代码,它创建了一个可编辑的 HTML 页面。你可以在浏览器中打开这段代码,并编辑页面的内容。

这段代码的具体解释如下:

data: 是数据 URI 协议。数据 URI 协议允许你在 HTML 文档中嵌入数据,例如图像、文本或脚本。
text/html 是数据类型。在本例中,数据类型是 HTML 。
text, 是分隔符。它用于分隔数据类型和数据。
<html contenteditable> 是 HTML 代码。这段代码创建了一个 HTML 页面,页面的内容是可编辑的。
edit me 是页面的内容。你可以在浏览器中打开这段代码,并编辑页面的内容。
shayebushi
2023-07-21 14:24:25 +08:00
每隔 5 秒自动保存到 localstorage
<html contenteditable>
<head>
<title>Note</title>
<script>
const contentEditable = document.querySelector('[contenteditable]');
const savedContent = localStorage.getItem('savedContent');
if (savedContent) {
contentEditable.innerHTML = savedContent;
}
setInterval(function() {
const content = contentEditable.innerHTML;
localStorage.setItem('savedContent', content);
}, 5000);
</script>
</head>
<body>
</body>
</html>
wangxiao20170401
2024-06-05 09:08:48 +08:00
结合上面大家所发代码优点,可以防关闭、刷新,可设置标题,可复制
-------------------------------------------------

data:text/html;charset=utf-8,%3Chtml%3E%3Chead%3E%0A%20%20%20%20%3Ctitle%3E%E4%B9%A6%E7%AD%BE%E8%AE%B0%E4%BA%8B%E6%9C%AC%3C%2Ftitle%3E%0A%20%20%20%20%3Cstyle%3E%0A%20%20%20%20%20%20%20%20body%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-family%3A%20Arial%2C%20sans-serif%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%23f4f4f4%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3A%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2020px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.container%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20max-width%3A%20600px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3A%200%20auto%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2020px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%23fff%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20box-shadow%3A%200%200%2010px%20rgba(0%2C%200%2C%200%2C%200.1)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%208px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.input-group%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20flex%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-bottom%3A%2020px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23titleInput%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20flex%3A%201%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2010px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%201px%20solid%20%23ddd%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%204px%200%200%204px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%2016px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.input-group%20button%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2010px%2020px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%23007BFF%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20%23fff%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%2016px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20cursor%3A%20pointer%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20transition%3A%20background%200.3s%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.input-group%20button%3Ahover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%230056b3%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.input-group%20button%3Afirst-of-type%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%200%204px%204px%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-right%3A%2010px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.content-editable%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%202px%20dashed%20lightgray%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2010px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20text-align%3A%20justify%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20min-height%3A%20100px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%204px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fstyle%3E%0A%20%20%20%20%3Cscript%3E%0A%20%20%20%20%20%20%20%20window.addEventListener(%22beforeunload%22%2C%20function%20(e)%20%7B%20e.preventDefault()%2C%20e.returnValue%20%3D%20%22%22%2C%20alert()%20%7D)%3B%0A%20%20%20%20%20%20%20%20function%20updateTitle()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.title%20%3D%20document.getElementById('titleInput').value%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20copyPageContent()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20htmlContent%20%3D%20document.documentElement.outerHTML%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tempInput%20%3D%20document.createElement(%22textarea%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tempInput.style.opacity%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tempInput.value%20%3D%20'data%3Atext%2Fhtml%3Bcharset%3Dutf-8%2C'%20%2B%20encodeURIComponent(htmlContent)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.appendChild(tempInput)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tempInput.select()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.execCommand(%22copy%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.removeChild(tempInput)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20alert(%22Page%20content%20copied%20as%20data%20URL%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fscript%3E%0A%3C%2Fhead%3E%0A%0A%3Cbody%3E%0A%20%20%20%20%3Cdiv%20class%3D%22container%22%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22input-group%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20type%3D%22text%22%20id%3D%22titleInput%22%20placeholder%3D%22Enter%20new%20title%20here%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20onclick%3D%22updateTitle()%22%3ESet%20Title%3C%2Fbutton%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20onclick%3D%22copyPageContent()%22%3ECopy%3C%2Fbutton%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22content-editable%22%20contenteditable%3D%22%22%3E%3C%2Fdiv%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%0A%0A%3C%2Fbody%3E%3C%2Fhtml%3E
wangxiao20170401
2024-06-05 09:48:27 +08:00
data:text/html,<html><head><title>书签记事本</title><style>body{padding:20px}.content-editable{border:1px dashed;margin-top:10px;padding:10px;min-height:100px}</style><script>window.addEventListener("beforeunload",function(e){e.preventDefault(),e.returnValue="",alert()});function updateTitle(){document.title=document.getElementById('titleInput').value}function copyPageContent(){var tempInput=document.createElement("textarea");tempInput.value='data:text/html;charset=utf-8,'+encodeURIComponent(document.documentElement.outerHTML);document.body.appendChild(tempInput);tempInput.select();document.execCommand("copy");document.body.removeChild(tempInput);alert("Page content copied")}</script></head><body><input type="text" id="titleInput" placeholder="Enter new title"><button onclick="updateTitle()">Set Title</button><button onclick="copyPageContent()">Copy</button><div class="content-editable" contenteditable></div></body></html>

上面的太笨重了,精简了下
meeop
2024-07-30 18:09:20 +08:00
@所有人 我做了一个聚合这类 app 的网站,参考 https://www.v2ex.com/t/1059349?p=1#reply38

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/944717

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX