【问题标题】:JQuery removed elements are still displayedJQuery 删除的元素仍然显示
【发布时间】:2017-02-25 10:10:17
【问题描述】:

我正在开发一个模拟一些“postit”功能的网站。当用户双击浏览器窗口时,会弹出一个表单(使其可见),允许在输入文本中引入一条消息。通过单击表单按钮,会创建一个 postit 元素 (div.postit) 并显示在正文上(在用户最初单击的位置)。 div.postit 包括一个带有消息的div.msg 和另一个带有“x”的div.close,允许通过单击“x”来关闭/擦除帖子(div.postit -parent div- 从正文中删除)。

到目前为止一切顺利。但是当用户再次双击窗口并通过单击表单按钮创建新的 postit 时,不仅会显示新的div.postit,还会显示以前的 postit(已从正文中删除)。这是为什么?

这是我的代码的简化版本。只有一个 html 表单最初被 CSS 隐藏并在窗口上双击可见:

// Event handler dblclick on browser window: Form is made visible
function ondblclickHtml(event) {
  var x = event.clientX;
  var y = event.clientY;

  // Show form (fade in)
  $('form').fadeIn(1000);
  $('form').removeClass('hidden');

  // Pass (x, y) arguments to event handler wrapped inside an object
  $('input#nueva-nota').on('click', {x: x, y: y}, onclickButton);
} 


// Event handler for onclick form button
function onclickButton(event) {

  $('form').fadeOut(1000); // Form fades out

  var msg = $('input#note').val();
  var pos = [event.data.x, event.data.y]; // Retrieve the coordinates
  displayPostIt(msg, pos);
} 

function displayPostIt(msg, pos) {
  var $divPostIt = $('<div class="postit"></div>');
  var $closeDiv = $('<div class="close">x</div>');
  // Bind click event on close div
  $closeDiv.on('click', onclickCloseDiv);
  var $msgDiv = $('<div class="msg">' + msg + '</div>');
  $divPostIt.css({'left': pos[0], 'top': pos[1]});
  $divPostIt.append($closeDiv);
  $divPostIt.append($msgDiv);
  $('body').append($divPostIt); // Finally, append the PosIt div to the body
}

function onclickCloseDiv(event) {
  console.log("onclickCloseDiv ...");
  var divPostIt = $(this).parent();
  divPostIt.remove();
}

【问题讨论】:

  • 每次双击表单时,都会将新的单击处理程序绑定到input#nueva-nota。这意味着从您第二次打开表单开始,输入将绑定多个事件处理程序,并将多次调用onclickButton。此外,我没有看到任何实际删除 postit 的代码,只有创建它的代码。删除过程是否由图书馆处理?
  • 好的,我现在看到了。我无意中删除了最后一行的删除,我已经编辑了代码以包含它。
  • 多个处理程序部分呢?
  • 为什么不只是 jQuery('.postit').remove(); ?
  • @AVAT 是的,我明白这是我的问题。我应该从双击事件处理程序中取出onclick按钮的绑定,然后呢?

标签: jquery arrays dom


【解决方案1】:

正如@Avavt 已经评论的那样,您的问题是每次用户双击窗口/正文时,您都将一个新的单击事件处理程序(连同位置信息)绑定到按钮。因此,即使您删除第一个帖子,然后第二次双击正文,您的第一个单击处理程序也将与具有新位置信息的新事件处理程序一起执行(并且它将具有旧的位置信息) .这就是您添加 2 div.postits 的原因。如果你第三次双击body,将会添加3个div.postits,以此类推。

解决方案是删除对pos 的依赖,以作为点击事件数据传递。这样你就可以只绑定一次点击事件处理程序。

这是一个示例。我将 pos 数据存储在隐藏字段 (input#pos) 中,然后从 displayPostIt() 读取它。

Working JSFiddle

$(function(){
  $('input#nueva-nota').on('click', onclickButton);
  $(document).on('dblclick', ondblclickHtml);
})

// Event handler dblclick on browser window: Form is made visible
function ondblclickHtml(event) {
  var x = event.clientX;
  var y = event.clientY;

  // Show form (fade in)
  $('form').fadeIn(1000);
  $('form').removeClass('hidden');
  $('input#note').focus();

  $('input#pos').val(JSON.stringify({'left': x, 'top': y}));
} 


// Event handler for onclick form button
function onclickButton(event) {

  $('form').fadeOut(1000); // Form fades out

  var msg = $('input#note').val();
  displayPostIt(msg);
} 

function displayPostIt(msg) {
  var $divPostIt = $('<div class="postit"></div>');
  var $closeDiv = $('<div class="close">x</div>');
  // Bind click event on close div
  $closeDiv.on('click', onclickCloseDiv);
  var $msgDiv = $('<div class="msg">' + msg + '</div>');
  var pos = JSON.parse($('input#pos').val());
  $divPostIt.css(pos);
  $divPostIt.append($closeDiv);
  $divPostIt.append($msgDiv);
  $('body').append($divPostIt); // Finally, append the PosIt div to the body
}

function onclickCloseDiv(event) {
  console.log("onclickCloseDiv ...");
  var divPostIt = $(this).parent();
  divPostIt.remove();
}

【讨论】:

  • 这是解决如何传递坐标的好方法。
猜你喜欢
  • 1970-01-01
  • 2013-01-30
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多