模拟操作系统演示
主要依靠CSS布局以及JS的DOM操作来完成,包括删除、复制DOM节点,控制DOM元素的显示和隐藏等等
代码中用到了一些图片资源,想要复现需要按照路径添加图片资源
GitHub地址
DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模拟操作系统title>
head>
<body>
<div class="container" onmouseup="desktopEve()" ondragover="dragover()" ondrop="drop()">
<div class="icon" draggable="true" style="display: none;">
<img src="desktop/filefolder.png" onmouseup="fileIconEve()" ondblclick="openFileFolder()" ondragstart="dragStart()">
<input type="text" value="新建文件夹">
<ul class="fileMenu" style="display: none;">
<li onclick="openFileFolder()">打开li>
<li onclick="copyFileFolder()">复制li>
<li onclick="delFileFolder()">删除li>
<li onclick="renameFileFolder()">重命名li>
ul>
div>
<div class="container filefolder" style="display: none" onmouseup="filefolderEve()" ondragover="dragover()" ondrop="drop()">
<img class="close" src="desktop/close.svg" onclick="parentNode.style.display='none'">
<ul class="fileFolderMenu" style="display: none;">
<li onclick="newFileFolder()">新建文件夹li>
ul>
div>
<div class="icon" draggable="true">
<img src="desktop/filefolder.png" onmouseup="fileIconEve()" ondblclick="openFileFolder()" ondragstart="dragStart()">
<input type="text" value="新建文件夹">
<ul class="fileMenu" style="display: none;">
<li onclick="openFileFolder()">打开li>
<li onclick="copyFileFolder()">复制li>
<li onclick="delFileFolder()">删除li>
<li onclick="renameFileFolder()">重命名li>
ul>
div>
<div class="container filefolder" style="display: none" onmouseup="filefolderEve()" ondragover="dragover()" ondrop="drop()">
<img class="close" src="desktop/close.svg" onclick="parentNode.style.display='none'">
<ul class="fileFolderMenu" style="display: none;">
<li onclick="newFileFolder()">新建文件夹li>
ul>
div>
<div class="icon" draggable="true">
<img src="desktop/browser.svg" onclick="parentNode.classList.add('active')" ondblclick="getElementById('browser').style.display='block'" ondragstart="dragStart()">
<input type="text" value="浏览器">
div>
<div id="browser" class="filefolder" style="display: none;">
<input id="urlInput" style="width: 880px; height: 20px;" onkeydown="openBrowser()">
<button onclick="openBrowser()">前往button>
<img class="close" src="Desktop/close.svg" onclick="parentNode.style.display='none'">
<iframe id="iframe">iframe>
div>
<div class="icon" draggable="true">
<img src="desktop/trashBin.svg" onclick="parentNode.classList.add('active')" ondblclick="getElementById('trash').style.display='block'" ondragstart="dragStart()">
<input type="text" value="回收箱">
div>
<div id="trash" class="filefolder " style="display: none">
<img class="close" src="desktop/close.svg" onclick="parentNode.style.display='none'">
div>
<ul class="desktopMenu" style="display: none;">
<li onclick="newFileFolder()">新建文件夹li>
<li onclick="changeBack()">更改桌面背景li>
<li onclick="pasteFileFolder()">粘贴li>
<li>排序方式li>
<li onclick="location.reload()">刷新li>
ul>
div>
body>
<script src="./emulateOS.js">script>
<link rel="stylesheet" type="text/css" href="emulateOS.css" />
html>
let copyedElem // 复制的对象
let dragged
let ofx
let ofy
let backOrder = 0
let curFileFolder
// 右键菜单事件
document.oncontextmenu = (event) => {
event.preventDefault()
};
// 桌面点击事件
const desktopEve = (event) => {
let e = event || window.event
let fileMenus = document.getElementsByClassName('fileMenu')
let desktopMenus = document.getElementsByClassName('desktopMenu')
if (e.button == 0) { // 单击桌面
for (let i of e.target.children) {
if (i.classList.contains('icon')) {
i.classList.remove('active')
}
}
for(let f of fileMenus) {
f.style.display = 'none'
}
desktopMenus[0].style.display = 'none'
} else if (e.button == 2) { // 右击桌面
desktopMenus[0].style.display = 'block'
desktopMenus[0].style.top = e.offsetY + 'px'
desktopMenus[0].style.left = e.offsetX + 'px'
}
e.stopPropagation()
return false
}
// 文件夹图标点击事件
const fileIconEve = (event) => {
let e = event || window.event
if (e.button == 0) {
e.target.parentNode.classList.add('active')
} else if (e.button == 2) {
e.target.parentElement.children[2].style.display = 'block'
e.target.parentElement.children[2].style.top = e.clientY + 'px'
e.target.parentElement.children[2].style.left = e.clientX + 'px'
}
e.stopPropagation()
return false
}
// 文件夹点击事件
const filefolderEve = (event) => {
let e = event || window.event
if (e.button == 0) {
for (let i of e.target.children) {
if (i.classList.contains('icon')) {
i.classList.remove('active')
} else if (i.classList.contains('fileFolderMenu')) {
i.style.display = 'none'
}
}
} else if (e.button == 2) {
for (let i of e.target.children) {
if (i.classList.contains('fileFolderMenu')) {
i.style.display = 'block'
i.style.top = e.offsetY + 'px'
i.style.left = e.offsetX + 'px'
}
}
}
e.stopPropagation()
return false
}
// 更改桌面背景事件
const changeBack = (event) => {
let e = event || window.event
let body = document.getElementsByTagName('body')
backOrder = (backOrder + 1) % 4
body[0].style.backgroundImage = `url(desktop/back${backOrder}.jpg)`
e.stopPropagation()
return false
}
// 打开网址
const openBrowser = (event) => {
let e = event || window.event
let urlInput = document.getElementById('urlInput')
if (e.keyCode == 13 || e.button == 0) {
let i = document.getElementById('iframe')
i.setAttribute('src', urlInput.value)
}
e.stopPropagation()
return false
}
// 拖拽开始事件
const dragStart = (event) => {
let e = event || window.event
dragged = e.target.parentElement
ofx = e.offsetX
ofy = e.offsetY
return false
}
// 拖拽过程事件
const dragover = (event) => {
let e = event || window.event
e.preventDefault()
return false
}
// 拖拽结束事件
const drop = (event) => {
let e = event || window.event
dragged.style.position = "absolute"
dragged.style.left = (e.offsetX - ofx) + 'px'
dragged.style.top = (e.offsetY - ofy) + 'px'
return false
}
// 打开文件夹事件
const openFileFolder = (event) => {
let e = event || window.event
if (e.target.tagName == 'IMG') {
e.target.parentElement.nextElementSibling.style.display = 'block'
} else if (e.target.tagName == 'LI') {
e.target.parentElement.parentElement.nextElementSibling.style.display = 'block'
}
e.stopPropagation()
return false
}
// 复制文件夹
const copyFileFolder = (event) => {
let e = event || window.event
copyedElem = e.target.parentElement.parentElement.cloneNode(true)
e.stopPropagation()
return false
}
// 删除文件夹
const delFileFolder = (event) => {
let e = event || window.event
let trash = document.getElementById("trash")
trash.appendChild(e.target.parentElement.parentElement)
e.target.parentElement.remove()
e.stopPropagation()
return false
}
// 文件夹重命名
const renameFileFolder = (event) => {
let e = event || window.event
e.target.parentElement.parentElement.children[1].focus()
e.target.parentElement.parentElement.children[1].setSelectionRange(-1,-2,'backward')
e.target.parentNode.style.display = 'none'
e.stopPropagation()
return false
}
// 新建文件夹事件
const newFileFolder = (event) => {
let e = event || window.event
let containers = document.getElementsByClassName('container')
let newItem1 = containers[0].children[0].cloneNode(true)
let newItem2 = containers[0].children[1].cloneNode(true)
newItem1.style.display = 'block'
e.target.parentElement.parentElement.appendChild(newItem1)
e.target.parentElement.parentElement.appendChild(newItem2)
e.target.parentElement.style.display = 'none'
e.stopPropagation()
return false
}
// 粘贴文件夹
const pasteFileFolder = (event) => {
let e = event || window.event
e.target.parentElement.parentElement.appendChild(copyedElem)
e.stopPropagation()
return false
}
body {
background-image: url(desktop/back0.jpg);
}
.container {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
}
.icon {
box-sizing: border-box;
width: 130px;
height: 160px;
margin: 5px;
}
.icon img {
width: 130px;
height: 130px;
border: 3px solid rgba(0, 0, 0, 0);
}
.active img {
border: 3px solid white;
border-radius: 3px;
background-color: rgba(0, 0, 0, 0.3);
}
.icon input {
width: 130px;
text-align: center;
color: white;
border: none;
background-color: rgba(0, 0, 0, 0);
}
.active input {
background-color: blue;
}
.filefolder {
width: 1000px;
height: 700px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-45%);
background-color: rgba(255, 255, 255, 0.8);
z-index: 99;
}
.fileMenu, .desktopMenu, .fileFolderMenu {
list-style: none;
width: 200px;
height: 120px;
position: absolute;
background-color: rgba(255, 255, 255, 0.8);
margin: 0;
padding: 5px 0;
}
.desktopMenu {
height: 148px;
}
.fileFolderMenu {
height: 30px;
}
li {
height: 30px;
line-height: 30px;
padding: 0 20px;
}
li:hover {
cursor: pointer;
background-color: blue;
}
.close{
width: 30px;
height: 30px;
padding: 5px;
float: right;
}
#iframe {
width: 1000px;
height: 650px;
border: none;
}
#urlInput {
margin: 8px;
}