javascript - 函数也会为每个先前的元素执行

标签 javascript jquery html css contextmenu

我目前正在创建一个 codepen ,您可以在打开上下文菜单时更改页面上每个元素的颜色、背景颜色、文本...。

我将右键单击的元素存储在一个变量中:

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

当我在控制台中返回该变量 efp 的值时,它会返回正确的元素。


现在的问题是:
更改文本元素的颜色效果很好。但是当我下次尝试这样做时,它不仅改变了元素,而且我之前改变的元素也改变了。

像这样的事情:
改变颜色p -> 更改 p
改变部分的背景 -> 改变部分 AND p
更改 h1 的颜色 -> 更改 h1 AND section AND p


这是我的完整代码:

$(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>

最佳答案

是因为这一行:

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

每次调用 bgcolorPick() 函数时,您都会附加一个点击处理程序。因此,每次单击时,所有单击处理程序都会对之前单击的所有元素执行,并更改它们的颜色。在将点击处理程序再次附加到最新点击的元素之前分离点击处理程序:

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

Updated codepen

关于javascript - 函数也会为每个先前的元素执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45716050/

相关文章:

javascript 街道地址正则表达式验证

javascript - jquery .show() 和 .hide() 不工作..!

javascript - 选择单选按钮时,div 未显示在 html 中

javascript - 在 Canvas 中制作弧形动画的最佳方式

html - 调整图像大小以适合 div 有效但不适用于 Firefox

javascript - 将 PDF 存储到 Google 云端硬盘

javascript - 如何从链接(字符串)创建文档对象

javascript - 尝试使用当前时间与关闭时间javascript进行倒计时

javascript - 在dojo中找到ajax请求

javascript - jQuery scrollTop() 在移动浏览器上滚动 DIV 时不起作用,替代方案?