Skip to content

Appending an Element on Mousedown Into Specific Div Element Only

I am trying to add circles when the event mousedown is generated into the square-one (grey square) only. If the mouse hovers outside of the square-one, it should not insert any circles anywhere else such as square-two(green square).

Question: How can I set the limits for the circles such that they are only inserted within the square-one boundaries? Thank you for your help.

***********
JavaScript
***********

let count = 1
let greySquare = document.getElementById("square-one")
let mousePosition;
let circlesArray = []

document.addEventListener('mousedown', (event)=>{

  let circle = document.createElement('div')
  let circleHeight = 40
  let circleWidth = 40

  mousePosition = {
    x: event.clientX,
    y: event.clientY
  }


  circle.style.height = `${circleHeight}px`
  circle.style.width = `${circleWidth}px`;
  circle.style.borderRadius = "50%"

  circle.style.backgroundColor = `#F0B27A`
  circle.style.position = "absolute"
  circle.style.left = (mousePosition.x - (circleWidth/2)) + "px"
  circle.style.top = (mousePosition.y - (circleHeight/2)) + "px"
  circle.style.lineHeight = `${circleHeight}px`
  circle.style.display = 'flex';
  circle.style.cursor = 'pointer'
  circle.style.justifyContent = 'center';
  circle.style.border = 'none'

  circle.textContent = count++
  greySquare.appendChild(circle)
  circlesArray.push(circle)

})
********
  HTML
********

  <body>
      <div class="container">
        <div id="square-one"></div>
        <div id="square-two"></div>
      </div>
    <script src="script.js"></script>
  </body>
******
CSS
******
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body{
  position: relative;
}

.container{
  position: relative;
  width: 100%;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

#square-one{
  position: relative;
  width: 300px;
  height: 300px;
  background-color: grey;
  margin-right: 100px;
}
#square-two{
  position: relative;
  width: 300px;
  height: 300px;
  background-color: green;
}

Answer

When I use your code, the circles aren’t being put where I actually click.

That is because you’re using the mouse’s position (which is relative to the page) to detect where you will put the circles, but then you append them to the

graySquare, which doesn’t start at (0,0). If you append them to the .contaner instead, you’ll be ok.

document.querySelector(".container").appendChild(circle)

Then regarding the set the limits for the circles such that they are only inserted within the square-one boundaries, you need to get the position (x and y), width and height of the squareOne and only proceed if the click occurs within those.

document.addEventListener('mousedown', (event)=>{

  mousePosition = {
    x: event.clientX,
    y: event.clientY
  }

  let greySquarePosition = greySquare.getBoundingClientRect();

  if(!(mousePosition.x>=greySquarePosition.left + window.scrollX&&
    mousePosition.x<=greySquarePosition.left + window.scrollX + greySquarePosition.width&&
    mousePosition.y>=greySquarePosition.top + window.scrollY&&
    mousePosition.y<=greySquarePosition.top + window.scrollY + greySquarePosition.height)) 
    return;
    // ...

I used this to get the position of the div, and this to get its width and height (although they ended up being the same solution).

EDIT!

I kept thinking about this and there’s a more obvious, more elegant solution (to me at least). You add the event listener to the graySquare and not the whole document.

greySquare.addEventListener('mousedown', (event)=> ...

Then you don’t need the ugly part where you check if the mouse is within the limits.

You can even bind the same function to different squares. Check the updated snippet.

let count = 1
let greySquare = document.getElementById("square-one")
let greenSquare = document.getElementById("square-two")
let mousePosition;
let circlesArray = []

greySquare.addEventListener('mousedown', paintCircles.bind(null, '#F0B27A'), false);
greenSquare.addEventListener('mousedown', paintCircles.bind(null, '#fa0123'), false);

function paintCircles(color, event){

    mousePosition = {
      x: event.clientX,
      y: event.clientY
    }

    let circle = document.createElement('div')
    let circleHeight = 40
    let circleWidth = 40

    circle.style.height = `${circleHeight}px`
    circle.style.width = `${circleWidth}px`;
    circle.style.borderRadius = "50%"

    circle.style.backgroundColor = `${color}`
    circle.style.position = "absolute"
    circle.style.left = (mousePosition.x - (circleWidth/2)) + "px"
    circle.style.top = (mousePosition.y - (circleHeight/2)) + "px"
    circle.style.lineHeight = `${circleHeight}px`
    circle.style.display = 'flex';
    circle.style.cursor = 'pointer'
    circle.style.justifyContent = 'center';
    circle.style.border = 'none'

    circle.textContent = count++;
    document.querySelector(".container").appendChild(circle)
    circlesArray.push(circle)

}
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body{
    position: relative;
  }

  .container{
    position: relative;
    width: 100%;
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  #square-one{
    position: relative;
    width: 300px;
    height: 300px;
    background-color: grey;
    margin-right: 100px;
  }
  #square-two{
    position: relative;
    width: 300px;
    height: 300px;
    background-color: green;
  }
<body>
  <div class="container">
    <div id="square-one"></div>
    <div id="square-two"></div>
  </div>
</body>