How can I access a DOM element with jQuery that I have "moved" around the page?

时间:2015-09-01 22:08:49

标签: javascript jquery html css javascript-events

I have a page with 2 areas. There are boxes in each area. If the user clicks on a box in the top area, it gets moved to the bottom and vice versa. This works fine for the first movement. Theoretically, I should be able to move them back and forth between sections as I please.

Box HTML:

<div id="top-area">
    <div class="top-box" id="blue-box"></div>
    <div class="top-box" id="yellow-box"></div>
    <div class="top-box" id="green-box"></div>
</div>
<hr/>
<div id="bottom-area">
    <div class="bottom-box" id="red-box"></div>
    <div class="bottom-box" id="gray-box"></div>
</div>

I use jQuery.remove() to take it out of the top section and jQuery.append() to add it to the other. However, when I try to move a box back to its original position, the event that I have created to move them doesn't even fire.

jQuery/JavaScript:

$(".top-box").on('click', function ()
{
    var item = $(this);
    item.remove();    
    $(this).removeClass("top-box").addClass("bottom-box");    
    $("#bottom-area").append(item);
});

$(".bottom-box").on('click', function ()
{
    var item = $(this);
    item.remove();    
    $(this).removeClass("bottom-box").addClass("top-box");    
    $("#top-area").append(item);
});

I have verified that the classes I am using as jQuery selectors are getting added/removed properly. I am even using $(document).on() to handle my event. How come my boxes are not triggering the jQuery events after they are moved once?

Please see the Fiddle: http://jsfiddle.net/r6tw9sgL/

2 个答案:

答案 0 :(得分:4)

Your code attaches the events on the page load to the elements that match the selector right then.

If you attach the listener to #top-area and #bottom-area and then use delegated events to restrict the click events to the boxes, it should work like you expect. See .on: Direct and Delegated Events for more information.

Use the below JavaScript:

$("#top-area").on('click', '.top-box', function ()
{
    var item = $(this);
    item.remove();

    $(this).removeClass("top-box").addClass("bottom-box");

    $("#bottom-area").append(item);
});

$("#bottom-area").on('click', '.bottom-box', function ()
{
    var item = $(this);
    item.remove();

    $(this).removeClass("bottom-box").addClass("top-box");

    $("#top-area").append(item);
});

Alternatively:

You could also change .on() to .live(), which works for "all elements which match the current selector, now and in the future." (JSFiddle)

JSFiddle

答案 1 :(得分:0)

Here's another way you could work it:

function toBottom ()
{
    var item = $(this);
    item.remove();
    item.off('click', toBottom);
    item.on('click', toTop);
    $(this).removeClass("top-box").addClass("bottom-box");
    $("#bottom-area").append(item);
}

function toTop ()
{
    var item = $(this);
    item.remove();
    item.off('click', toTop);
    item.on('click', toBottom);
    $(this).removeClass("bottom-box").addClass("top-box");
    $("#top-area").append(item);
}

$(".top-box").on('click', toBottom);

$(".bottom-box").on('click', toTop);
#top-area, #bottom-area {
    height: 100px;
    border: 1px solid black;
    padding: 10px;
}
.top-box::before {
    content: "Top";
}
.bottom-box::before {
    content: "Bottom";
}
#blue-box, #red-box, #yellow-box, #green-box, #gray-box {
    width: 100px;
    cursor: pointer;
    float: left;
    margin: 0 5px;
    text-align: center;
    padding: 35px 0;
}
#blue-box {
    background-color: blue;
}
#red-box {
    background-color: red;
}
#yellow-box {
    background-color: yellow;
}
#green-box {
    background-color: green;
}
#gray-box {
    background-color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top-area">
    <div class="top-box" id="blue-box"></div>
    <div class="top-box" id="yellow-box"></div>
    <div class="top-box" id="green-box"></div>
</div>
<hr/>
<div id="bottom-area">
    <div class="bottom-box" id="red-box"></div>
    <div class="bottom-box" id="gray-box"></div>
</div>

This basically removes the listener that switched the object to bottom to a listener that switches the object to the top and viceversa.