Tobias Glaus Tobias Glaus - 1 year ago 41
HTML Question

Function gets executed for every previous element aswell

I am currently creating a codepen, where you can change the color,background-color,text,... of each element on the page when opening the contextmenu.

I store the element, which I right-clicked in a variable:

var x = event.clientX, y = event.clientY,
efp = document.elementFromPoint(x, y);


When I return the value of that variable
efp
in the console, it returns me the correct element.





Now the problem:

Changing the color of, for example a text element, works fine. But when I try to do that another time, it not only changes the element, but the element I previously changed aswell.

Something like this:
Change color of
p
-> changes
p


Change background of
section
-> changes
section
AND
p


Change color of
h1
-> changes
h1
AND
section
AND
p







And here's my full code:



$(document).on("contextmenu", function(e){
$('.custom-menu li').show(0);
e.preventDefault();
var el = e.target.nodeName;
var x = event.clientX, y = event.clientY,
efp = document.elementFromPoint(x, y);
console.log(efp);
switch(el){
case "P":
ctxP();
break;
case "CONTENT":
ctxCon();
break;
case "HEADER":
ctxHead();
break;
case "FOOTER":
ctxFoot();
break;
}
$(".custom-menu li").on("click", function(){
switch($(this).attr("data-action")) {
case "color":
colorPick();
break;
case "bgcolor":
bgcolorPick();
break;
case "text":
textChange();
break;
}
$(".custom-menu").fadeOut(100);
});
$(".custom-menu").finish().fadeIn(100).css({
top: e.pageY + "px",
left: e.pageX + "px"
});
function ctxP(){
$('.custom-menu li[data-action=bgcolor]').hide();
}
function ctxCon(){
$('.custom-menu li[data-action=color]').hide();
$('.custom-menu li[data-action=text]').hide();
}
function ctxHead(){
$('.custom-menu li[data-action=color]').hide();
$('.custom-menu li[data-action=text]').hide();
}
function ctxFoot(){
$('.custom-menu li[data-action=color]').hide();
$('.custom-menu li[data-action=text]').hide();
}
function colorPick(){
$(".overlay").fadeIn();
$(".colorpicker").fadeIn().css('display', 'flex');
$(".color").click(function(){
var color = $(this).css('background-color');
$(efp).css('color', color);
$(".colorpicker, .overlay").fadeOut();
});
}
function bgcolorPick(){
$(".overlay").fadeIn();
$(".colorpicker").fadeIn().css('display', 'flex');
$(".color").click(function(){
var color = $(this).css('background-color');
$(efp).css('background-color', color);
$(".colorpicker, .overlay").fadeOut();
});
}
function textChange(){
$(".overlay, .textChange").fadeIn();
$('.textChange input').keypress(function(e) {
var text = $(this).val();
if(e.keyCode == 13){
$(efp).text(text);
$(".overlay, .textChange").fadeOut();
$(this).val("");
}
});
}
});

$(document).click(function(e){
if (!$(e.target).parents(".custom-menu").length > 0) {
$(".custom-menu").fadeOut(100);
}
});

*{
margin:0;
padding:0;
box-sizing:border-box;
}
header,content,footer{
display:block;
width:100%;
height:200px;
padding:50px 20%;
}
header{
background:#efefef;
}
content{
background-color:#cccccc;
}
footer{
background-color:#afafaf
}

.custom-menu {
display: none;
z-index: 1000;
position: absolute;
overflow: hidden;
border: 1px solid #CCC;
white-space: nowrap;
background: #FFF;
color: #333;
}
.custom-menu li {
padding: 8px 12px;
cursor: pointer;
list-style-type: none;
transition: all .3s ease;
user-select: none;
}
.custom-menu li:hover {
background-color: #DEF;
}
.colorpicker{
position:fixed;
z-index:20;
display:flex;
display:none;
flex-wrap:wrap;
top:10%;
left:10%;
height:80%;
width:80%;
background-color:white;
-webkit-box-shadow: 0px 0px 15px 0px rgba(0,0,0,0.5);
-moz-box-shadow: 0px 0px 15px 0px rgba(0,0,0,0.5);
box-shadow: 0px 0px 15px 0px rgba(0,0,0,0.5);
}
.color{
display:block;
flex-grow:1;
transition:.5s ease-in-out;
cursor:pointer;
}
.textChange{
display:none;
position:fixed;
z-index:20;
top:calc(50% - 25px);
width:20%;
height:50px;
left:40%;
}
.textChange input{
height:100%;
width:100%;
padding:10px;
font-size:1.1em;
}
.overlay{
display:none;
position:fixed;
z-index:10;
width:100%;
background-color:black;
height:100%;
opacity:.5;
top:0;
}
.disabled{
pointer-events:none;
color:#a3a3a3;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="wrapper">
<header><p>Hello</p></header>
<content><p>Peter</p></content>
<footer><p>Hallo</p></footer>
</div>


<div class="overlay"></div>
<div class="textChange">
<input type="textarea" placeholder="Type new text in here">
</div>

<div class="colorpicker">
<div class="color" style="background-color:#1abc9c"></div>
<div class="color" style="background-color:#16a085"></div>
<div class="color" style="background-color:#2ecc71"></div>
<div class="color" style="background-color:#27ae60"></div>
<div class="color" style="background-color:#3498db"></div>
<div class="color" style="background-color:#2980b9"></div>
<div class="color" style="background-color:#9b59b6"></div>
<div class="color" style="background-color:#8e44ad"></div>
<div class="color" style="background-color:#e74c3c"></div>
<div class="color" style="background-color:#c0392b"></div>
<div class="color" style="background-color:#e67e22"></div>
<div class="color" style="background-color:#d35400"></div>
<div class="color" style="background-color:#f1c40f"></div>
<div class="color" style="background-color:#f39c12"></div>
<div class="color" style="background-color:#ecf0f1"></div>
<div class="color" style="background-color:#bdc3c7"></div>
<div class="color" style="background-color:#95a5a6"></div>
<div class="color" style="background-color:#7f8c8d"></div>
<div class="color" style="background-color:#34495e"></div>
<div class="color" style="background-color:#2c3e50"></div>
</div>

<ul class='custom-menu'>
<li data-action="color">change color</li>
<li data-action="bgcolor">change background-color</li>
<li data-action="text">change text</li>
</ul>




Answer Source

It is because of this line :

$(".color").click( function(){

Every time the bgcolorPick() function is called, you attach one more click handler. So every time you click, all your click handlers execute on all the elements previously clicked, changing their colour. Detach the click handler before attaching it again to the latest clicked element :

$(".color").off("click").on("click", function(){

Updated codepen

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download