簡體   English   中英

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 ie 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>

目標- 當用戶單擊設計按鈕時,圓圈會在mousedown事件中添加到畫布中。 當用戶單擊編輯按鈕時,他們可以移動圓圈。 當再次單擊設計按鈕時,用戶可以繼續添加圓圈並從上次停止的地方增加數字。

要解決的錯誤- 第一次單擊設計時,我能夠成功地將圓圈添加到畫布。 如果我點擊編輯按鈕並移動圓圈,然后立即點擊設計按鈕,它會在點擊時附加兩個圓圈。 為什么要附加兩個圓圈? 這只會在我點擊編輯后發生。

***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;
}

  1. 問題是每次用戶切換到設計模式時,您都會在設計模式下注冊鼠標按下事件處理程序。
  2. 但是,您永遠不會在切換到編輯模式時取消注冊鼠標按下事件處理程序
  3. 這會導致為畫布單擊事件(鼠標按下)注冊多個事件處理程序。
  4. 因此,每當您切換回設計模式並單擊畫布時,它都會為先前注冊的偵聽器和新注冊的偵聽器觸發單擊處理程序。
  5. 檢查更新的片段

注釋行標有// 解決方案:

 //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 ie 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM