0

According to jQuery documentation, the event.stopPropagation(); should stop the event bubbling. In the following script, when I remove event.stopPropagation(); the function removes the ul element code block including it's all children. I added event.stopPropagation(); to stop bubbling but It returns following error:

TypeError: undefined is not an object (evaluating 'event.stopPropagation')

The following is the HTML and jQuery code:

$('span.remove').on('click', function() {
  $(this).parent().hide(500, function(event) {
    event.stopPropagation();
    $(this).parent().remove();
  });
});
.todo-list {
  list-style: none;
  padding: 0px;
}
.todo-item {

  border: 2px solid #444;
  margin-top: -2px;
  padding: 10px;
  cursor: pointer;
  display: block;
  background-color: #ffffff;

}
.remove {
  float: right;
  font-family: Helvetica, Arial, sans-serif;
  font-size: 0.8em;
  color: #dd0000;
}
.remove:before {
  content: 'X';
}
.remove:hover {
  color: #ffffff;
}
.todo-item::after:hover {
  background-color: #dd0000;
  color: white;
}
.todo-item:hover {
  background-color: #0EB0FF;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class='todo-list'>
  <li class='todo-item'>4L 2% Milk
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Butter, Unsalted
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Dozen Eggs
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Walk the dog
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Cut the lawn
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Laundry
    <span class='remove'></span>
  </li>
</ul>

References:

  1. How to delete parent element using jQuery?
  2. How to stop events bubbling in jQuery?
Community
  • 1
  • 1
Maihan Nijat
  • 9,054
  • 11
  • 62
  • 110
  • you can access the original DOM event in `event.originalEvent`, like `event.originalEvent.stopPropagation()`. – rupps Apr 21 '16 at 20:40
  • There is no event that is being passed to your `hide` function because it isn't an event. Put `event` in the `click, function(event)` – Adjit Apr 21 '16 at 20:43
  • 1
    The `hide()` function doesn't have an event, the `.on('click', function(event) {...` does – adeneo Apr 21 '16 at 20:44

3 Answers3

2

You have to get your event object from the click() callback. If you look at the jquery hide() api docs, the complete callback doesn't get passed anything so your event is undefined, but the click() handler on the other hand gets passed the event object. So you just need to change your javascript to:

$('span.remove').on('click', function(event) {
  event.stopPropagation();
  $(this).parent().hide(500, function() {
    $(this).parent().remove();
  });
});

The reason however that the whole list gets removed is another issue. You reference parent() twice targeting the ul to be removed, so just get rid of one of the parents (the scope of $(this) changes to the parent in the hide callback). With this edit the code is:

$('span.remove').on('click', function(event) {
  event.stopPropagation();
  $(this).parent().hide(500, function() {
    $(this).remove();
  });
});

It's true however that the propagation of the event, doesn't really have anything to do with the ul being hidden as a whole so you can just remove the event.stopPropagation() line. Final code being:

$('span.remove').on('click', function() {
  $(this).parent().hide(500, function() {
    $(this).remove();
  });
});
jpopesculian
  • 712
  • 3
  • 11
2

Move event obj to the delegated click event.

Instead of this use event.target.

$('span.remove').on('click', function(event) {
  var tgt = event.target;
  $(tgt).parent().hide(500, function() {
    $(tgt).parent().remove();
     
  });
 
});
.todo-list {
  list-style: none;
  padding: 0px;
}
.todo-item {

  border: 2px solid #444;
  margin-top: -2px;
  padding: 10px;
  cursor: pointer;
  display: block;
  background-color: #ffffff;

}
.remove {
  float: right;
  font-family: Helvetica, Arial, sans-serif;
  font-size: 0.8em;
  color: #dd0000;
}
.remove:before {
  content: 'X';
}
.remove:hover {
  color: #ffffff;
}
.todo-item::after:hover {
  background-color: #dd0000;
  color: white;
}
.todo-item:hover {
  background-color: #0EB0FF;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class='todo-list'>
  <li class='todo-item'>4L 2% Milk
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Butter, Unsalted
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Dozen Eggs
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Walk the dog
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Cut the lawn
    <span class='remove'></span>
  </li>
  <li class='todo-item'>Laundry
    <span class='remove'></span>
  </li>
</ul>
Jed Fox
  • 2,979
  • 5
  • 28
  • 38
zer00ne
  • 41,936
  • 6
  • 41
  • 68
1

Multiple problems:

  1. The event variable is not being passed. Don't include the event parameter in the hide() function, but rather in the on() event handler. This should stop the error.
  2. You are removing the parent of the parent. Replace the following line: $(this).parent().remove(); with $(this).remove();
  3. You actually don't need the stopPropagation(). After fixing the above two problems, you don't need it. The click event is not propagating.
Jonathan Lam
  • 16,831
  • 17
  • 68
  • 94