Why can't I append an element, remove it, then

2019-08-31 02:47发布

问题:

In the code provided below, you will see a map made of various tiles. Clicking on a tile will "select" it.

What I want to happen:

  1. Click on a tile
  2. Press the "Place" button
  3. An oil derrick appears on that tile
  4. Press the "Remove" button
  5. The oil derrick goes away
  6. Click another tile
  7. Press the "Place" button
  8. A new oil derrick appears on that tile

The program works up until steps 7-8. For some reason, the oil derrick isn't appearing again.

I have the Place and Remove buttons set up so that only one oil derrick may be on the map at a time. To remove an oil derrick, I do not expect the tile with the oil derrick on it to be selected before removal (hence, you can have a different tile selected and clicking Remove will still remove the oil derrick no matter what tile it is on).

What I think is the problem is that the oil derrick isn't getting appended correctly the second time. This may be because of the way it's being removed.

http://jsfiddle.net/briz/jdhPW/17/


On a side not, I realize that there is a potential bug if the Place button gets pressed before a tile is selected.

回答1:

There are many ways to fix this. I think the simplest would be to $('.oilDerrick').hide() rather than remove(). An alternative would be to append clones and change class names, that requires changing a bit more code though.

UPDATE: http://jsfiddle.net/jdhPW/19/



回答2:

It looks like you're expecting $('.oilDerrick') to select the oil derrick element even after it has been .remove()d. This is not the case, as the oil derrick element is no longer part of the DOM at that point. You will need to save a reference to it somewhere after you .remove() it, then use that reference inside your call to append. Or you can just hide it.



回答3:

Another option is to use .append() to remove the element. I know that sounds like the opposite of what you want to do, but when you use .append() on an existing element it removes it from its current parent and adds it to the new parent. (Unless the new parent selector matches multiple parent elements, in which case copies of the child are made.)

So you could setup a "staging area" div that has display:none. Any elements like your ".oilDerrick" element that are added to tiles dynamically would start out as children of the "staging area" and thus be hidden automatically and not associated with any particular tile element. When you .append() to a tile element that automatically removes it from the "staging area" div. Then, to remove ".oilDerrick" from the tile just .append() back to the "staging area". The ".oilDerrick" div wouldn't need to be explicitly hidden with CSS, because all of the "staging area" div's children would be hidden, so you wouldn't even need .show() and .hide() (unless you specifically want to animate the add and remove).

Assuming your finished game is more complicated and has other objects that can be added to tiles this would also give you an easy way to find all currently unused objects: just enumerate the current children of the "staging area".

Anyway, I know you've already accepted an answer, but I just thought you might like some other ideas.