initial commit
This commit is contained in:
617
synthwave/index.html
Normal file
617
synthwave/index.html
Normal file
@@ -0,0 +1,617 @@
|
||||
<!doctype html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.5, user-scalable=yes"
|
||||
/>
|
||||
<title>V A P O R _ D I F F</title>
|
||||
|
||||
<!-- Highlight.js 主题 (Shades of Purple - 完美契合蒸汽波) -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/shades-of-purple.min.css"
|
||||
/>
|
||||
<!-- Diff2Html 核心样式 -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/diff2html@3.4.47/bundles/css/diff2html.min.css"
|
||||
/>
|
||||
|
||||
<!-- 引入蒸汽波风格字体 -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Righteous&family=
|
||||
|
||||
@message_part::reasoning-1_2
|
||||
|
||||
Space+Mono:ital,wght@0,400;0,700;1,400&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<!-- 引入 Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
|
||||
<!-- 配置 Tailwind -->
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
vapor: {
|
||||
bg: "#120458" /* 深邃夜空蓝 */,
|
||||
dark: "#2a0a4a" /* 暗紫色面板底色 */,
|
||||
pink: "#ff71ce" /* 迈阿密粉 */,
|
||||
cyan: "#01cdfe" /* 霓虹青 */,
|
||||
purple: "#b967ff" /* 亮紫色 */,
|
||||
yellow: "#fffb96" /* 落日黄 */,
|
||||
panel: "rgba(42, 10, 74, 0.75)" /* 半透明面板 */,
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
vapor: ['"Righteous"', "cursive"],
|
||||
mono: ['"Space Mono"', "monospace"],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style type="text/tailwindcss">
|
||||
@layer components {
|
||||
/* 蒸汽波半透明发光面板 */
|
||||
.vapor-panel {
|
||||
@apply bg-vapor-panel backdrop-blur-md border-2 border-vapor-purple shadow-[0_0_20px_rgba(185,103,255,0.3)] relative overflow-hidden;
|
||||
}
|
||||
|
||||
/* 蒸汽波输入框 */
|
||||
.vapor-input {
|
||||
@apply bg-transparent text-vapor-cyan border-none outline-none resize-y placeholder:text-vapor-cyan/40 focus:shadow-[inset_0_0_30px_rgba(1,205,254,0.15)] transition-all;
|
||||
text-shadow: 0 0 4px rgba(1, 205, 254, 0.4);
|
||||
}
|
||||
|
||||
/* 蒸汽波霓虹按钮 */
|
||||
.vapor-btn {
|
||||
@apply bg-transparent border-2 px-5 py-2 font-vapor tracking-widest uppercase transition-all duration-300 cursor-pointer;
|
||||
}
|
||||
.vapor-btn-cyan {
|
||||
@apply border-vapor-cyan text-vapor-cyan hover:bg-vapor-cyan hover:text-vapor-bg shadow-[0_0_10px_rgba(1,205,254,0.5)] hover:shadow-[0_0_25px_rgba(1,205,254,0.8)];
|
||||
}
|
||||
.vapor-btn-pink {
|
||||
@apply border-vapor-pink text-vapor-pink hover:bg-vapor-pink hover:text-vapor-bg shadow-[0_0_10px_rgba(255,113,206,0.5)] hover:shadow-[0_0_25px_rgba(255,113,206,0.8)];
|
||||
}
|
||||
|
||||
/* 视图切换按钮 */
|
||||
.view-option {
|
||||
@apply px-3 py-1 font-vapor text-sm tracking-wider text-vapor-purple hover:text-vapor-pink transition-colors;
|
||||
}
|
||||
.view-option.active {
|
||||
@apply text-vapor-bg bg-vapor-purple shadow-[0_0_15px_#b967ff];
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================
|
||||
纯 CSS 绘制:80年代落日与 3D 透视网格
|
||||
========================================== */
|
||||
body {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
#0f023b 0%,
|
||||
#2a0a4a 60%,
|
||||
#ff71ce 100%
|
||||
);
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
/* 霓虹落日 */
|
||||
.vapor-sun {
|
||||
position: fixed;
|
||||
top: 15%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
background: linear-gradient(to bottom, #fffb96 0%, #ff71ce 100%);
|
||||
border-radius: 50%;
|
||||
z-index: -2;
|
||||
box-shadow:
|
||||
0 0 80px #ff71ce,
|
||||
0 0 150px #fffb96;
|
||||
/* 百叶窗切割效果 */
|
||||
-webkit-mask-image: repeating-linear-gradient(
|
||||
to bottom,
|
||||
black 0%,
|
||||
black 6%,
|
||||
transparent 6%,
|
||||
transparent 8%
|
||||
);
|
||||
mask-image: repeating-linear-gradient(
|
||||
to bottom,
|
||||
black 0%,
|
||||
black 6%,
|
||||
transparent 6%,
|
||||
transparent 8%
|
||||
);
|
||||
}
|
||||
|
||||
/* 3D 赛博网格地板 */
|
||||
.vapor-grid {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 40vh;
|
||||
background-image:
|
||||
linear-gradient(
|
||||
to right,
|
||||
rgba(1, 205, 254, 0.6) 2px,
|
||||
transparent 2px
|
||||
),
|
||||
linear-gradient(to top, rgba(1, 205, 254, 0.6) 2px, transparent 2px);
|
||||
background-size: 50px 50px;
|
||||
transform: perspective(600px) rotateX(70deg);
|
||||
z-index: -1;
|
||||
animation: gridMove 3s linear infinite;
|
||||
/* 让网格向远处渐隐 */
|
||||
-webkit-mask-image: linear-gradient(
|
||||
to bottom,
|
||||
transparent 0%,
|
||||
black 100%
|
||||
);
|
||||
}
|
||||
@keyframes gridMove {
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
100% {
|
||||
background-position: 0 50px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================
|
||||
覆盖 Diff2Html 样式 (蒸汽波化)
|
||||
========================================== */
|
||||
.d2h-wrapper {
|
||||
font-family: "Space Mono", monospace !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.d2h-file-header {
|
||||
display: none !important;
|
||||
}
|
||||
.d2h-file-wrapper {
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.d2h-code-line-ctn {
|
||||
@apply font-mono text-[14px] !important;
|
||||
color: #e2e8f0 !important;
|
||||
}
|
||||
|
||||
/* 差异行背景色 (青色代表新增,粉色代表删除) */
|
||||
.d2h-ins {
|
||||
background-color: rgba(1, 205, 254, 0.2) !important;
|
||||
border-color: #01cdfe !important;
|
||||
color: #01cdfe !important;
|
||||
text-shadow: 0 0 5px rgba(1, 205, 254, 0.5);
|
||||
}
|
||||
.d2h-del {
|
||||
background-color: rgba(255, 113, 206, 0.2) !important;
|
||||
border-color: #ff71ce !important;
|
||||
color: #ff71ce !important;
|
||||
text-shadow: 0 0 5px rgba(255, 113, 206, 0.5);
|
||||
}
|
||||
|
||||
/* 行号区域 */
|
||||
.d2h-code-linenumber {
|
||||
background-color: rgba(18, 4, 88, 0.8) !important;
|
||||
border-color: #b967ff !important;
|
||||
color: #b967ff !important;
|
||||
}
|
||||
.d2h-info {
|
||||
background-color: rgba(42, 10, 74, 0.9) !important;
|
||||
color: #fffb96 !important;
|
||||
border-color: #b967ff !important;
|
||||
}
|
||||
.d2h-emptyplaceholder {
|
||||
background-color: rgba(18, 4, 88, 0.5) !important;
|
||||
border-color: #b967ff !important;
|
||||
}
|
||||
tbody {
|
||||
border-color: #b967ff !important;
|
||||
}
|
||||
td {
|
||||
border-color: #b967ff !important;
|
||||
}
|
||||
|
||||
/* 滚动条霓虹化 */
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #120458;
|
||||
border-left: 1px solid #b967ff;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #ff71ce;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #01cdfe;
|
||||
}
|
||||
|
||||
/* 选中文本颜色 */
|
||||
::selection {
|
||||
background: #ff71ce;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body
|
||||
class="font-mono p-4 md:p-8 min-h-screen flex flex-col items-center text-white relative overflow-x-hidden"
|
||||
>
|
||||
<!-- 纯 CSS 背景动画 -->
|
||||
<div class="vapor-sun"></div>
|
||||
<div class="vapor-grid"></div>
|
||||
|
||||
<!-- 主窗口 -->
|
||||
<div class="max-w-[1600px] w-full flex flex-col gap-6 z-10">
|
||||
<!-- 标题区 -->
|
||||
<header class="text-center mb-4">
|
||||
<h1
|
||||
class="font-vapor text-5xl md:text-7xl tracking-widest text-transparent bg-clip-text bg-gradient-to-b from-vapor-cyan to-vapor-purple drop-shadow-[0_0_15px_rgba(1,205,254,0.8)]"
|
||||
style="-webkit-text-stroke: 1px #fff"
|
||||
>
|
||||
V A P O R _ D I F F
|
||||
</h1>
|
||||
<p
|
||||
class="font-vapor text-vapor-pink mt-2 tracking-[0.5em] text-sm drop-shadow-[0_0_8px_#ff71ce]"
|
||||
>
|
||||
A E S T H E T I C S // 1 9 8 4
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<!-- 双栏输入区 -->
|
||||
<div class="flex flex-col lg:flex-row gap-6">
|
||||
<!-- 左侧面板 -->
|
||||
<div class="flex-1 flex flex-col vapor-panel rounded-xl">
|
||||
<div
|
||||
class="flex items-center justify-between px-4 py-3 border-b-2 border-vapor-purple bg-vapor-bg/50"
|
||||
>
|
||||
<label
|
||||
class="font-vapor text-vapor-cyan tracking-widest flex items-center gap-2 drop-shadow-[0_0_5px_#01cdfe]"
|
||||
>
|
||||
[ CASSETTE_A ]
|
||||
</label>
|
||||
<button
|
||||
id="clearLeftBtn"
|
||||
class="font-vapor text-xs text-vapor-purple hover:text-vapor-pink transition-colors tracking-widest"
|
||||
>
|
||||
EJECT
|
||||
</button>
|
||||
</div>
|
||||
<textarea
|
||||
id="leftTextarea"
|
||||
class="vapor-input w-full flex-1 min-h-[260px] h-[300px] p-5 text-[15px] leading-relaxed"
|
||||
spellcheck="false"
|
||||
>
|
||||
function playSynthwave() {
|
||||
console.log("Loading VHS tape...");
|
||||
return "Nostalgia";
|
||||
}</textarea
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- 右侧面板 -->
|
||||
<div class="flex-1 flex flex-col vapor-panel rounded-xl">
|
||||
<div
|
||||
class="flex items-center justify-between px-4 py-3 border-b-2 border-vapor-purple bg-vapor-bg/50"
|
||||
>
|
||||
<label
|
||||
class="font-vapor text-vapor-pink tracking-widest flex items-center gap-2 drop-shadow-[0_0_5px_#ff71ce]"
|
||||
>
|
||||
[ CASSETTE_B ]
|
||||
</label>
|
||||
<button
|
||||
id="clearRightBtn"
|
||||
class="font-vapor text-xs text-vapor-purple hover:text-vapor-cyan transition-colors tracking-widest"
|
||||
>
|
||||
EJECT
|
||||
</button>
|
||||
</div>
|
||||
<textarea
|
||||
id="rightTextarea"
|
||||
class="vapor-input w-full flex-1 min-h-[260px] h-[300px] p-5 text-[15px] leading-relaxed"
|
||||
spellcheck="false"
|
||||
>
|
||||
function playSynthwave() {
|
||||
console.log("Loading LaserDisc...");
|
||||
enableNeonGlow();
|
||||
return "A E S T H E T I C S";
|
||||
}</textarea
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<div
|
||||
class="vapor-panel rounded-xl p-4 flex flex-wrap items-center justify-between gap-4"
|
||||
>
|
||||
<div class="flex flex-wrap items-center gap-6">
|
||||
<!-- 语言选择 -->
|
||||
<div class="flex items-center gap-3">
|
||||
<label
|
||||
class="font-vapor text-sm tracking-widest text-vapor-yellow drop-shadow-[0_0_5px_#fffb96]"
|
||||
>FORMAT:</label
|
||||
>
|
||||
<select
|
||||
id="languageSelect"
|
||||
class="bg-vapor-bg border-2 border-vapor-purple text-vapor-cyan px-3 py-1.5 font-vapor text-sm outline-none cursor-pointer hover:border-vapor-cyan focus:border-vapor-cyan focus:shadow-[0_0_10px_#01cdfe] transition-all appearance-none"
|
||||
>
|
||||
<option value="javascript" selected>JS_WAVE</option>
|
||||
<option value="typescript">TS_WAVE</option>
|
||||
<option value="html">HTML_84</option>
|
||||
<option value="css">CSS_NEON</option>
|
||||
<option value="json">JSON_DATA</option>
|
||||
<option value="python">PY_SYNTH</option>
|
||||
<option value="plaintext">RAW_TEXT</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 视图切换 -->
|
||||
<div
|
||||
class="flex items-center border-2 border-vapor-purple p-1 rounded-md bg-vapor-bg/50"
|
||||
id="viewToggle"
|
||||
>
|
||||
<button
|
||||
class="view-option active rounded-sm"
|
||||
data-view="side-by-side"
|
||||
>
|
||||
STEREO
|
||||
</button>
|
||||
<button class="view-option rounded-sm" data-view="line-by-line">
|
||||
MONO
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<button id="swapBtn" class="vapor-btn vapor-btn-cyan rounded-md">
|
||||
REMIX
|
||||
</button>
|
||||
<button id="exampleBtn" class="vapor-btn vapor-btn-cyan rounded-md">
|
||||
DEMO
|
||||
</button>
|
||||
<button
|
||||
id="compareBtn"
|
||||
class="vapor-btn vapor-btn-pink rounded-md bg-vapor-pink/10"
|
||||
>
|
||||
SYNC_TRACKS
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 差异结果区域 -->
|
||||
<div class="vapor-panel rounded-xl flex flex-col">
|
||||
<div
|
||||
class="px-5 py-3 border-b-2 border-vapor-purple bg-vapor-bg/50 flex items-center justify-between"
|
||||
>
|
||||
<span
|
||||
class="font-vapor tracking-widest text-vapor-yellow drop-shadow-[0_0_5px_#fffb96]"
|
||||
>> PLAYBACK_RESULT</span
|
||||
>
|
||||
<span id="diffStats" class="font-vapor text-sm tracking-wider"></span>
|
||||
</div>
|
||||
<div
|
||||
id="diff-output"
|
||||
class="overflow-x-auto min-h-[150px] bg-vapor-bg/80"
|
||||
>
|
||||
<div
|
||||
class="p-12 text-center font-vapor text-vapor-purple tracking-widest text-xl animate-pulse"
|
||||
>
|
||||
PRESS [ SYNC_TRACKS ] TO PLAY...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 依赖库 -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/diff@5.1.0/dist/diff.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/diff2html@3.4.47/bundles/js/diff2html.min.js"></script>
|
||||
|
||||
<!-- 核心对比逻辑 -->
|
||||
<script>
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
const leftTextarea = document.getElementById("leftTextarea");
|
||||
const rightTextarea = document.getElementById("rightTextarea");
|
||||
const compareBtn = document.getElementById("compareBtn");
|
||||
const swapBtn = document.getElementById("swapBtn");
|
||||
const exampleBtn = document.getElementById("exampleBtn");
|
||||
const clearLeftBtn = document.getElementById("clearLeftBtn");
|
||||
const clearRightBtn = document.getElementById("clearRightBtn");
|
||||
const languageSelect = document.getElementById("languageSelect");
|
||||
const diffOutput = document.getElementById("diff-output");
|
||||
const diffStats = document.getElementById("diffStats");
|
||||
const viewOptions = document.querySelectorAll(".view-option");
|
||||
|
||||
let currentView = "side-by-side";
|
||||
|
||||
function getSelectedLanguage() {
|
||||
let val = languageSelect.value;
|
||||
// 映射回真实的语言名称
|
||||
if (val === "javascript") return "javascript";
|
||||
if (val === "typescript") return "typescript";
|
||||
if (val === "html") return "html";
|
||||
if (val === "css") return "css";
|
||||
if (val === "json") return "json";
|
||||
if (val === "python") return "python";
|
||||
return "plaintext";
|
||||
}
|
||||
|
||||
function getHighlightConfig() {
|
||||
const lang = getSelectedLanguage();
|
||||
if (lang === "plaintext") return false;
|
||||
return { enabled: true, language: lang };
|
||||
}
|
||||
|
||||
function generateUnifiedDiff(original, modified) {
|
||||
return Diff.createTwoFilesPatch(
|
||||
"CASSETTE_A",
|
||||
"CASSETTE_B",
|
||||
original || "",
|
||||
modified || "",
|
||||
"",
|
||||
"",
|
||||
{ context: 4 },
|
||||
);
|
||||
}
|
||||
|
||||
function renderDiff() {
|
||||
const leftText = leftTextarea.value;
|
||||
const rightText = rightTextarea.value;
|
||||
|
||||
let diffString;
|
||||
try {
|
||||
diffString = generateUnifiedDiff(leftText, rightText);
|
||||
} catch (e) {
|
||||
diffOutput.innerHTML = `<div class="p-12 text-center font-vapor text-vapor-pink tracking-widest text-xl">GLITCH_ERROR: ${e.message}</div>`;
|
||||
diffStats.textContent = "ERR";
|
||||
return;
|
||||
}
|
||||
|
||||
const configuration = {
|
||||
drawFileList: false,
|
||||
matching: "lines",
|
||||
outputFormat: currentView,
|
||||
highlight: getHighlightConfig(),
|
||||
renderNothingWhenEmpty: false,
|
||||
};
|
||||
|
||||
let diffHtml = "";
|
||||
try {
|
||||
diffHtml = Diff2Html.html(diffString, configuration);
|
||||
} catch (e) {
|
||||
diffOutput.innerHTML = `<div class="p-12 text-center font-vapor text-vapor-pink tracking-widest text-xl">TAPE_JAMMED</div>`;
|
||||
diffStats.textContent = "ERR";
|
||||
return;
|
||||
}
|
||||
|
||||
diffOutput.innerHTML = diffHtml;
|
||||
|
||||
const selectedLang = getSelectedLanguage();
|
||||
if (selectedLang !== "plaintext") {
|
||||
const codeBlocks = diffOutput.querySelectorAll("code");
|
||||
if (codeBlocks.length > 0 && window.hljs) {
|
||||
codeBlocks.forEach((block) => {
|
||||
block.classList.forEach((cls) => {
|
||||
if (cls.startsWith("language-")) block.classList.remove(cls);
|
||||
});
|
||||
block.classList.add(`language-${selectedLang}`);
|
||||
if (block.dataset.highlighted) {
|
||||
delete block.dataset.highlighted;
|
||||
}
|
||||
try {
|
||||
hljs.highlightElement(block);
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const addedLines = diffOutput.querySelectorAll(".d2h-ins").length;
|
||||
const deletedLines = diffOutput.querySelectorAll(".d2h-del").length;
|
||||
if (addedLines === 0 && deletedLines === 0) {
|
||||
diffStats.innerHTML =
|
||||
"<span class='text-vapor-cyan drop-shadow-[0_0_5px_#01cdfe]'>VIBES_SYNCED</span>";
|
||||
} else {
|
||||
diffStats.innerHTML = `<span class='text-vapor-cyan drop-shadow-[0_0_5px_#01cdfe]'>+${addedLines} UPLOADED</span> <span class='text-vapor-purple mx-2'>|</span> <span class='text-vapor-pink drop-shadow-[0_0_5px_#ff71ce]'>-${deletedLines} ERASED</span>`;
|
||||
}
|
||||
|
||||
if (!diffHtml.trim() || diffOutput.innerText.trim() === "") {
|
||||
diffOutput.innerHTML =
|
||||
'<div class="p-12 text-center font-vapor text-vapor-cyan tracking-widest text-xl">TRACKS_ARE_IDENTICAL</div>';
|
||||
diffStats.innerHTML = "<span class='text-vapor-cyan'>SYNCED</span>";
|
||||
}
|
||||
}
|
||||
|
||||
function setActiveView(view) {
|
||||
currentView = view;
|
||||
viewOptions.forEach((btn) => {
|
||||
const val = btn.getAttribute("data-view");
|
||||
if (val === view) {
|
||||
btn.classList.add("active");
|
||||
} else {
|
||||
btn.classList.remove("active");
|
||||
}
|
||||
});
|
||||
if (
|
||||
diffOutput.querySelector(".d2h-wrapper") ||
|
||||
diffOutput.children.length > 0
|
||||
) {
|
||||
renderDiff();
|
||||
}
|
||||
}
|
||||
|
||||
function loadExample() {
|
||||
leftTextarea.value = `function playSynthwave() {\n console.log("Loading VHS tape...");\n return "Nostalgia";\n}`;
|
||||
rightTextarea.value = `function playSynthwave() {\n console.log("Loading LaserDisc...");\n enableNeonGlow();\n return "A E S T H E T I C S";\n}`;
|
||||
// 恢复下拉框的显示值
|
||||
languageSelect.selectedIndex = 0;
|
||||
renderDiff();
|
||||
}
|
||||
|
||||
function swapTexts() {
|
||||
const temp = leftTextarea.value;
|
||||
leftTextarea.value = rightTextarea.value;
|
||||
rightTextarea.value = temp;
|
||||
renderDiff();
|
||||
}
|
||||
|
||||
function clearLeft() {
|
||||
leftTextarea.value = "";
|
||||
renderDiff();
|
||||
}
|
||||
function clearRight() {
|
||||
rightTextarea.value = "";
|
||||
renderDiff();
|
||||
}
|
||||
|
||||
compareBtn.addEventListener("click", renderDiff);
|
||||
swapBtn.addEventListener("click", swapTexts);
|
||||
exampleBtn.addEventListener("click", loadExample);
|
||||
clearLeftBtn.addEventListener("click", clearLeft);
|
||||
clearRightBtn.addEventListener("click", clearRight);
|
||||
|
||||
languageSelect.addEventListener("change", () => {
|
||||
if (
|
||||
diffOutput.querySelector(".d2h-wrapper") ||
|
||||
diffOutput.children.length > 0
|
||||
)
|
||||
renderDiff();
|
||||
});
|
||||
|
||||
viewOptions.forEach((btn) => {
|
||||
btn.addEventListener("click", (e) => {
|
||||
setActiveView(e.currentTarget.getAttribute("data-view"));
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
renderDiff();
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("DOMContentLoaded", renderDiff);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user