JavaScript - Div 一键添加元素两次
JavaScript - Div Elements Appending Twice on One Click
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container');
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = [];
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
canvas.addEventListener('mousedown', (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y);
}
})
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>testing</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons@2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
Objective - 当用户单击设计按钮时,圆圈将添加到 canvas on mousedown
事件。当用户单击编辑按钮时,他们可以移动圆圈。再次单击设计按钮时,用户可以继续添加圆圈并从停止的地方增加数字。
解决错误 - 首次单击设计时,我能够成功地向 canvas 添加圆圈。如果我单击编辑按钮并四处移动圆圈,然后立即单击设计按钮,它会在单击时附加两个圆圈。为什么要附加两个圆圈?这只会在我点击编辑后发生。
***JAVASCRIPT***
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container')
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = []
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
canvas.addEventListener('mousedown', (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y)
}
})
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
***HTML***
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Testing</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons@2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
***CSS***
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
- 问题是每次用户切换到设计模式时,您都会在设计模式中注册鼠标按下事件处理程序。
- 但是您永远不会在切换到编辑模式时注销鼠标按下事件处理程序。
- 这会导致为 canvas 单击事件(鼠标按下)注册多个事件处理程序。
- 因此,无论何时您切换回设计模式并单击 canvas,它都会为之前注册的侦听器和新注册的侦听器触发单击处理程序。
- 检查更新后的代码段
Comment lines marked with // Solution :
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container');
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = [];
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
// Solution : Define a click handler
var designClickHandler = (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y);
}
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
// Solution : Register click handler
canvas.addEventListener('mousedown', designClickHandler)
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
// Solution : unregister click handler
canvas.removeEventListener('mousedown', designClickHandler)
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
user-select: none;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>hiveport</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons@2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container');
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = [];
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
canvas.addEventListener('mousedown', (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y);
}
})
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>testing</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons@2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
Objective - 当用户单击设计按钮时,圆圈将添加到 canvas on mousedown
事件。当用户单击编辑按钮时,他们可以移动圆圈。再次单击设计按钮时,用户可以继续添加圆圈并从停止的地方增加数字。
解决错误 - 首次单击设计时,我能够成功地向 canvas 添加圆圈。如果我单击编辑按钮并四处移动圆圈,然后立即单击设计按钮,它会在单击时附加两个圆圈。为什么要附加两个圆圈?这只会在我点击编辑后发生。
***JAVASCRIPT***
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container')
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = []
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
canvas.addEventListener('mousedown', (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y)
}
})
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
***HTML***
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Testing</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons@2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
***CSS***
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
- 问题是每次用户切换到设计模式时,您都会在设计模式中注册鼠标按下事件处理程序。
- 但是您永远不会在切换到编辑模式时注销鼠标按下事件处理程序。
- 这会导致为 canvas 单击事件(鼠标按下)注册多个事件处理程序。
- 因此,无论何时您切换回设计模式并单击 canvas,它都会为之前注册的侦听器和新注册的侦听器触发单击处理程序。
- 检查更新后的代码段
Comment lines marked with // Solution :
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container');
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = [];
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
// Solution : Define a click handler
var designClickHandler = (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y);
}
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
// Solution : Register click handler
canvas.addEventListener('mousedown', designClickHandler)
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
// Solution : unregister click handler
canvas.removeEventListener('mousedown', designClickHandler)
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
user-select: none;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>hiveport</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons@2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>