jQuery替换只能为对象引用工作一次

时间:2015-07-23 15:38:23

标签: javascript jquery

我对replaceWith有一个奇怪的问题(或更可能是对象引用)。​​

我正在尝试创建一种具有空插槽或完整插槽的行表。作为一个演示,我做了这个简单的小提琴。 http://jsfiddle.net/Ltxtvyn3/3/在这个小提琴中,4个空槽被初始化。然后一个人被填满。然后应该清空同一个。但相反,它仍然充满了。就好像我只能使用replaceWith一次,或者我不了解我的对象引用。

HTML

<div class = "slot empty">Empty</div>
<div class = "slot full">Full</div>

<div class = "wrapper"></div>

CSS

.slot{
    width:50px;
    height:50px;
    display:none;
}
.empty{
    background-color:red;
}
.full{
    background-color:blue;
}

的Javascript

var wrapper = $('.wrapper');
var empty = $('.slot.empty');
var full = $('.slot.full');

var slots = {};

for(var i = 0; i < 4; i++){
    slots[i] = empty.clone().show();
    wrapper.append(slots[i]);    
}

function fillSlot(id){
    slots[id].replaceWith(full.clone().show());
}

function emptySlot(id){
    slots[id].replaceWith(empty.clone().show());
}

fillSlot(1);
emptySlot(1);

我希望对象var slot保持对div的引用,并且我不确定它是否正在这样做。

5 个答案:

答案 0 :(得分:2)

不,它没有保留参考,但你很容易解决这个问题。

这是一些正在运行的代码:

var wrapper = $('.wrapper');
var empty = $('.slot.empty');
var full = $('.slot.full');

for(var i = 0; i < 4; i++){
  wrapper.append(empty.clone().show());    
}

function fillSlot(id){
  $(".wrapper .slot").eq(id).replaceWith(full.clone().show());
}

function emptySlot(id){
  $(".wrapper .slot").eq(id).replaceWith(empty.clone().show());
}

fillSlot(1);

setTimeout(function() {
  emptySlot(1);
}, 2000);
.slot{
    width:50px;
    height:50px;
    display:none;
}
.empty{
    background-color:red;
}
.full{
    background-color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class = "slot empty">Empty</div>
<div class = "slot full">Full</div>
<div class = "wrapper"></div>

答案 1 :(得分:2)

<强>已更新

如果您更改选择方法并且不希望slots不再列出,那么您的代码可以正常工作。

替换:

function fillSlot(id){
    slots[id].replaceWith(full.clone().show());
}

function emptySlot(id){
    slots[id].replaceWith(empty.clone().show());
}

BY:

function fillSlot(id){
    wrapper.children().eq(id).replaceWith(full.clone().show());
}

function emptySlot(id){
    wrapper.children().eq(id).replaceWith(empty.clone().show());
}   

直接从包装器中选择什么意味着从新的DOM中进行选择。这将解决问题,看看更新后的小提琴。

<强> Updated JSFiddle

答案 2 :(得分:2)

感谢您的回答。我知道理解为什么对象没有引用,我真的希望如此。我只是添加了一个包装器插槽,然后我将影响包装器的内容。这样我总是可以参考插槽。

HTML

    <div class="slot-content empty">Empty</div>
<div class="slot-content full">Full</div>
<div class = "slot"></div>
<div id="wrapper"></div>

的Javascript

var wrapper = $('#wrapper');
var slot = $('.slot');
var empty = $('.slot-content.empty');
var full = $('.slot-content.full');

var slots = {};

for(var i = 0; i < 4; i++){
    slots[i] = slot.clone().show();
    slots[i].html(empty.clone().show());
    wrapper.append(slots[i]);
}

function fillSlot(id){
    slots[id].html(full.clone().show());
    slots[id].find('.slot-content').html('hello');
}

function emptySlot(id){
    slots[id].html(empty.clone().show());
}

fillSlot(1);
emptySlot(1);
fillSlot(2);

答案 3 :(得分:1)

问题是插槽[i]没有指向div - 所以replaceWith不会选择正确的项目。更新循环如下(添加slots [i] = wrapper.find(':last-child')):

for(var i = 0; i < 4; i++){
    slots[i] = empty.clone().show();
    wrapper.append(slots[i]);
    slots[i] = wrapper.find(':last-child')
}

实际上,这可能会使代码更容易理解(用此代替循环)

for(var i = 0; i < 4; i++){
    wrapper.append(empty.clone().show());
    slots[i] = wrapper.find(':last-child')
}

经过测试并在FF上工作..

答案 4 :(得分:0)

它没有保留对DOM元素的引用。如果您仍想使用该数组,那么每次更新其中一个元素时,您都可以重新填充该列表。效率不是很高,但我认为它可以帮助您避免在DOM中保持状态。

function redraw() {
  $('.wrapper').empty();
  for(var i = 0; i < 4; i++){
    wrapper.append(slots[i]);    
  }
}

JSFiddle