V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
meeop
V2EX  ›  分享创造

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

  meeop · 2023-06-01 01:12:48 +08:00 · 15573 次点击
这是一个创建于 567 天前的主题,其中的信息可能已经有所发展或是发生改变。

data:text/html;base64,PGh0bWwgY29udGVudGVkaXRhYmxlPmVkaXQgbWU8L2h0bWw+

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

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

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

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

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

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

第 1 条附言  ·  26 天前
更新进展:
对这种形式的 app 起了个名字叫 urlapp
创建了 https://urlapp.org/
用来支持 urlapp 的在线发布,使用,讨论

更新进展 2:
https://genwebapp.com/

升级为支持 ai 编辑的 genwebapp 了,可以使用 ai 直接编写 urlapp ,纯自然语言编程
可以直接编辑,发布,并立即可用的 urlapp
150 条回复    2024-07-30 18:09:20 +08:00
1  2  
kenvix
    101
kenvix  
   2023-06-01 22:05:46 +08:00
不怕链接复杂,但是没有自动保存到 localstorage 有点没用
jaylee4869
    102
jaylee4869  
   2023-06-01 23:03:21 +08:00
meeop
    103
meeop  
OP
   2023-06-01 23:23:58 +08:00 via Android
@Cheons 这确实是一个挺重要的应用场景,而且不管能分享文本,还能分享图,不考虑大小的话理论上啥都能分享。比那种。 www 点 xxx 点 xxx 。 需要手动替换字符才能浏览的规避监管文本体验好
meeop
    104
meeop  
OP
   2023-06-01 23:24:23 +08:00 via Android   ❤️ 1
@Cheons 这确实是一个挺重要的应用场景,而且不管能分享文本,还能分享图,不考虑大小的话理论上啥都能分享。比那种。 www 点 xxx 点 xxx 。 需要手动替换字符才能浏览的文本体验好
TomPig0216
    105
TomPig0216  
   2023-06-01 23:25:17 +08:00
不错 很有意思哈哈
meeop
    106
meeop  
OP
   2023-06-01 23:26:35 +08:00 via Android
@kenvix 自己动手加呀
nexo
    107
nexo  
   2023-06-01 23:28:28 +08:00
前端很基础的东西...... 刚好最近在搞在线编辑器 看到这么多人惊讶 只能说网页编辑器领域太冷门了.....
meeop
    108
meeop  
OP
   2023-06-01 23:33:36 +08:00 via Android
@nexo 非前端就不知道了呀,好东西就该多分享,知道的人还是太少了
akira
    109
akira  
   2023-06-01 23:43:18 +08:00
这玩意。。风险有点大啊。。
meeop
    110
meeop  
OP
   2023-06-02 00:05:14 +08:00 via Android
@akira 有啥风险?
nexo
    111
nexo  
   2023-06-02 00:06:48 +08:00
@meeop
确实
SomethingIsWrong
    112
SomethingIsWrong  
   2023-06-02 00:09:18 +08:00
实话说,前天晚上需要临时复制 json 数据的时候还想过这种应用,没想到今天就有人搞出来了:)
lei2j
    113
lei2j  
   2023-06-02 00:33:16 +08:00 via Android
真会玩
kuangkuang
    114
kuangkuang  
   2023-06-02 09:38:06 +08:00
不错,临时的文本和图片其实更推荐 ditto ,毕竟有历史记录
fengqi
    115
fengqi  
   2023-06-02 10:04:07 +08:00
6 ,还能这么玩
southFlowFire
    116
southFlowFire  
   2023-06-02 11:41:13 +08:00   ❤️ 2
为什么我第一反应就是,这个玩法太适合规避审查了。
比如内网有份文档,正常情况发不出去,会被审查拦下,这么一搞审查直接无效,触发不了预警机制了
linyongqianglal
    117
linyongqianglal  
   2023-06-02 12:08:30 +08:00
好活
meeop
    118
meeop  
OP
   2023-06-02 12:33:02 +08:00 via Android
@southFlowFire 不是挺好的?
EaStack
    119
EaStack  
   2023-06-02 13:22:44 +08:00
便携版:data:text/html,<html contenteditable>hi
awesomes
    120
awesomes  
   2023-06-02 13:43:42 +08:00
说白了就是在你的浏览器中打开一个本地的 html 文件而已,有啥风险,有啥技术,有啥大惊小怪的么,但凡有点前端常识都明白的事
azui999
    121
azui999  
   2023-06-02 14:10:10 +08:00
挺有趣,收藏了
googlefans
    122
googlefans  
   2023-06-02 15:02:30 +08:00
太牛了..
太有创艺了
zhw2590582
    123
zhw2590582  
   2023-06-02 17:04:21 +08:00
有点意思
Leung818
    124
Leung818  
   2023-06-02 17:34:28 +08:00
我没啥文化,先来一句卧槽
kobezone
    125
kobezone  
   2023-06-02 18:43:50 +08:00 via Android
真是 NB 这都能想到 妙啊 楼主🐂🍺plus
dode
    126
dode  
   2023-06-02 21:32:19 +08:00
@codehz 不能用
mghio
    127
mghio  
   2023-06-02 21:38:49 +08:00
以下是来自 Google Bard 对其工作原理的解释:

The code data:text/html;base64,PGh0bWwgY29udGVudGVkaXRhYmxlPmVkaXQgbWU8L2h0bWw+ in a browser URL is a data URI scheme. It is a way of embedding a small amount of data, such as text, images, or CSS, directly into a web page. This can be useful for things like embedding a small logo or tracking pixel into a page, or for providing fallback content for users who cannot load external resources.

The data URI scheme is defined by the following syntax:

Code snippet
data:[<media type>][;base64],<data>
Use code with caution. Learn more
The <media type> is a string that identifies the type of data being embedded. The <data> is the actual data, encoded in base64.

In the example you provided, the <media type> is text/html and the <data> is the HTML code for a simple page. This page contains a heading and a paragraph of text.

When a browser encounters a data URI, it will decode the base64 data and then treat it as if it had been loaded from an external resource. In this case, the browser will load the HTML code and display it as a web page.

Data URIs can be a useful way to embed small amounts of data into web pages. However, they should be used sparingly, as they can increase the size of the page and make it slower to load.

Here are some additional things to keep in mind when using data URIs:

The maximum size of a data URI is 32KB.
Data URIs are not supported by all browsers.
Data URIs can be used to embed malicious code.
If you are considering using data URIs, it is important to weigh the benefits and drawbacks carefully.
fox233
    128
fox233  
   2023-06-03 14:18:58 +08:00
这种链接可以生产二维码吗?还有就是手机端访问字很小,可以适配手机端吗
Llesue
    129
Llesue  
   2023-06-03 16:33:25 +08:00
<!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>小小记事本</title>
<style>
* {
margin: 0 auto;
box-sizing: border-box;
color: #777777;
outline: none;
}
body {
background: #f5f5f5;
}
.main {
display: flex;
flex-direction: column;
max-width: 960px;
}
.container {
display: flex;
width: 100%;
margin: 5vh 0 1.5vh;
}
.title {
flex: 1;
font-size: 2em;
font-weight: 600;
padding-left: 16px;
white-space: nowrap;
}
.edit {
width: 100%;
min-height: 50vh;
padding: 16px;
font-size: 1.2em;
border: 1px dashed #ccc;
border-radius: 2px;
background: #fff;
}
button {
border: 1px solid #ccc;
padding: 0 20px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="main">
<div class="container">
<div class="title" contenteditable>编辑标题✏️</div>
<button id="btn">复制当前页 dataUrl</button>
</div>
<div class="edit" contenteditable>编辑这里开始.✏️</div>
</div>
<script>
function utf8_to_b64(str) {
return window.btoa(unescape(encodeURIComponent(str)));
}

// function b64_to_utf8(str) {
// return decodeURIComponent(escape(window.atob(str)));
// }

const btn = document.querySelector("#btn");
btn.addEventListener("click", () => {
const htmlContent = document.querySelector("html");
console.log(htmlContent.innerHTML);
const dataUrl = "<html>" + htmlContent.innerHTML + "</html>";
const base64 = utf8_to_b64(dataUrl);
// console.log(base64);

const inputValue = `data:text/html;base64,${base64}`
const input = document.createElement("input");
input.setAttribute("readonly", "readonly");
input.setAttribute("value", inputValue);
document.body.appendChild(input);
input.setSelectionRange(0, 9999);
input.select();
document.execCommand("copy");
document.body.removeChild(input);
alert('地址已复制。')
});
</script>
</body>
</html>
Llesue
    130
Llesue  
   2023-06-03 16:34:08 +08:00
@Llesue 不会做那个 dataurl 😂
Llesue
    131
Llesue  
   2023-06-03 17:55:13 +08:00   ❤️ 2
data:text/html;charset=utf-8,<title>小小记事本</title><style>* {margin: 0 auto;box-sizing: border-box;color: gray;outline: none;border-radius: 5px;}</style><script> function copyToClipboard() { var htmlContent = document.documentElement.outerHTML; var tempInput = document.createElement("textarea"); tempInput.style.opacity = 0; tempInput.value = 'data:text/html;charset=utf-8,' +htmlContent; document.body.appendChild(tempInput); tempInput.select(); document.execCommand("copy"); document.body.removeChild(tempInput); alert("已复制"); } </script><body style="background: gainsboro;"><div style="display: flex; flex-direction: column; max-width: 960px;"><div style="display: flex; width: 100%; margin: 5vh 0 1.5vh;"><div style="flex: 1; font-size: 2em; font-weight: 600; padding-left: 16px; white-space: nowrap;" contenteditable>编辑标题✏️</div><button onclick="copyToClipboard()" style="border: 1px solid lightgray; padding: 0 20px; cursor: pointer; font-size: 1em;">复制当前页 dataUrl</button></div><div style="width: 100%; min-height: 50vh; padding: 16px; font-size: 1.2em; border: 1px dashed lightgray; background: whitesmoke; text-align: justify;" contenteditable>编辑这里开始.✏️

会了
lizhenda
    132
lizhenda  
   2023-06-03 21:20:51 +08:00
厉害了啊,还可以这么玩
Llesue
    133
Llesue  
   2023-06-04 01:36:36 +08:00   ❤️ 1
@meeop #106 试过了,内容加不到 localstorage 里……
meeop
    134
meeop  
OP
   2023-06-04 02:05:38 +08:00 via Android
@fox233 网上搜索个二维码生成器就能做二维码了,但我试了下微信扫不会帮你打开链接,只能复制扫出来的内容手动贴浏览器执行。适配手机端的话肯定可以,这就是个标准网页,但需要额外开发下
fox233
    135
fox233  
   2023-06-04 10:41:28 +08:00
@fox233 我试了也是这样,想知道怎么直接打开这个二维码
xxl123456
    136
xxl123456  
   2023-06-05 17:19:08 +08:00
有无大佬解释原理是什么
lunhub
    137
lunhub  
   2023-06-05 17:27:31 +08:00
@Llesue 牛逼啊是
zeep
    138
zeep  
   2023-06-06 00:24:49 +08:00
@zhaol 如果分享时可以缩短链接就好了
jixule
    139
jixule  
   2023-06-06 15:07:51 +08:00
@Llesue 试了一下,界面好看多了,有俩问题:1. 如果复制 vscode 内容,编辑区带有格式生成 url ,打开是空白; 2.编辑区如果复制纯文本,遇到 16 进制颜色的#后面就不显示了,标题中有#后面页面全都不显示了
ixoy
    140
ixoy  
   2023-06-06 17:08:43 +08:00   ❤️ 1
meeop
    141
meeop  
OP
   2023-06-06 21:39:40 +08:00
@ixoy 不太一样,峰哥这个是在当前页面上下文注入一段 js 代码,更接近于浏览器插件

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

不过浏览器限制挺狠的,这个链接不能复制粘贴到地址栏,只能手敲前面的 javascript:,或者编辑书签地址才能使用
不过有意思的点是它能访问当前页面上下文,可以拿来做页面插件和外挂功能
rookiebulls
    142
rookiebulls  
   2023-06-07 15:28:46 +08:00   ❤️ 1
```
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
    143
InkAndBanner  
   2023-06-08 15:30:48 +08:00
@Cheons #100 怎么规避审查呢?反骨 boy 十分感兴趣,这个记事本原则上不支持保存呀,除非 ctrl+s
meeop
    144
meeop  
OP
   2023-06-08 16:37:40 +08:00
@InkAndBanner 比如这样 data:text/html;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0iVVRGLTgiPgo8L2hlYWQ+CjxodG1sIGNvbnRlbnRlZGl0YWJsZT7ov5nmmK/kuIDmrrXpmZDliLbnuqflhoXlrrk8L2h0bWw+
xml123
    145
xml123  
   2023-06-25 10:15:16 +08:00
@rookiebulls 这个不能适应浏览器窗口大小的变化,可以改进吗?另外 langugae 只能在地址里设置吗?
freepoint
    146
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
    147
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
    148
wangxiao20170401  
   196 天前   ❤️ 1
结合上面大家所发代码优点,可以防关闭、刷新,可设置标题,可复制
-------------------------------------------------

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
    149
wangxiao20170401  
   196 天前   ❤️ 1
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
    150
meeop  
OP
   141 天前
@所有人 我做了一个聚合这类 app 的网站,参考 https://www.v2ex.com/t/1059349?p=1#reply38
1  2  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1017 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 25ms · UTC 19:15 · PVG 03:15 · LAX 11:15 · JFK 14:15
Developed with CodeLauncher
♥ Do have faith in what you're doing.