我有以下小提琴: http://jsfiddle.net/mauricederegt/HMkcD/1/
它包含一系列彩色块(div),单击1可查看块。生成的HTML看起来像这样:
<div id="plane">
<div class="tile tile1" block-id="1" style-id="1" style="left:0px; top:0px"></div>
<div class="tile tile2" block-id="2" style-id="2" style="left:100px; top:0px"></div>
<div class="tile tile1" block-id="3" style-id="1" style="left:200px; top:0px"></div>
<div class="tile tile2" block-id="4" style-id="2" style="left:0px; top:100px"></div>
<div class="tile tile1" block-id="5" style-id="1" style="left:100px; top:100px"></div>
<div class="tile tile2" block-id="6" style-id="2" style="left:200px; top:100px"></div>
<div class="tile tile1" block-id="7" style-id="1" style="left:0px; top:200px"></div>
<div class="tile tile2" block-id="8" style-id="2" style="left:100px; top:200px"></div>
<div class="tile tile1" block-id="9" style-id="1" style="left:200px; top:200px"></div>
<div class="tile tile3" block-id="10" style-id="3" style="left:50px; top:50px"></div><div class="tile tile4" block-id="11" style-id="4" style="left:150px; top:50px"></div>
<div class="tile tile4" block-id="12" style-id="4" style="left:50px; top:150px"></div>
<div class="tile tile3" block-id="13" style-id="3" style="left:150px; top:150px"></div>
</div>
我想在单击一个块时向彩色块/ div添加一个类ss
;此单击的块将成为选定的块。然后我想点击选择另一个块。如果这两个块的style-id相同,我想删除这些块。如果没有,请再次删除ss
课程。
我已经创建了以下代码来执行此操作:
$('#plane').click(function(){ //the click function
var clickedBlock = $(this); //get the data of the clicked div/block
clickedBlock.addClass('ss'); //add class ss to the clicked div/block
if (blockSelected) { //if div/block is selected
if ($(blockSelected).attr('block-id') == clickedBlock.attr('block-id')) { //if block-id of the selected div equals the block-id of the clicked div
clickedBlock.removeClass('ss'); //remove class ss
} else { //else
if ($(blockSelected).attr('style-id') == clickedBlock.attr('style-id')) { //if style selected div equals style clicked div
$(blockSelected).addClass('x'); //ad class x to selected div or better: remove div
clickedBlock.addClass('x'); //ad class x to clicked div or better: remove div
totalTiles = totalTiles - 2; //deduct 2 of the total tiles
} else { //if not equal styles
$(blockSelected).removeClass('ss'); //remove class ss form the selected div
clickedBlock.removeClass('ss'); //remove class ss from the clicked div
}
}
blockSelected = null;
} else {
blockSelected = this;
}
});
问题是,我无法让它发挥作用。我认为#plane
一开始也不对,但由于#plane div
似乎不起作用,我不确定要放哪个代码。
谢谢!
答案 0 :(得分:1)
OP,
使用@Rodrigo Assis建议的on()
方法是成功的一半。简而言之,您试图将侦听器附加到DOM加载后创建的元素 - 为此,您不能使用直接事件,而是需要使用委托事件。旧方法是live()
,此后已被弃用。 on()
是新标准。有关here
至于你描述的逻辑,我重新编写了一些代码并对其进行了优化。我很确定这可以实现你所要求的,具有更强的逻辑。以下是纲要here is the updated Fiddle
...
var pairs = [];
$('#plane').on('click', '.tile', function () {
$(this).addClass('ss');
pairs.push($(this));
if (pairs.length == 2) {
if ($(pairs[0]).attr('style-id') === $(pairs[1]).attr('style-id') && $(pairs[0]).attr('block-id') != $(pairs[1]).attr('block-id')) {
$(pairs[0]).remove();
$(pairs[1]).remove();
pairs = [];
} else {
$(pairs[0]).removeClass('ss');
$(pairs[1]).removeClass('ss');
pairs = [];
}
}
});
...
我们想要的是基本上说:
在这种情况下,pairs
数组是您的朋友。
哦,另外一件事 - 您的原始代码有:totalTiles = totalTiles - 2
。我建议将totalTiles
映射为$('.tile').length
的引用。我查看了你的代码,但似乎无法弄清楚你为什么要减少它的价值。
希望它有所帮助。
- 编辑 -
更新了line 185 of app.js的条件,以确保选择相同的块两次,它不被视为一对。上面提到的小提琴和代码要点。
答案 1 :(得分:1)
我想我做了你想做的事。
我改变了你的小提琴。在您使用plane
创建el.innerHTML = html.join('');
的HTML后,我添加了以下内容:
$(el).find('.tile').click(function () {
//get the data of the clicked div/block
var clickedBlock = $(this);
//add class ss to the clicked div/block
clickedBlock.addClass('ss');
if (blockSelected) {
//if div/block is selected
if ($(blockSelected).attr('block-id') == clickedBlock.attr('block-id')) {
//if block-id of the selected div equals the block-id of the clicked div
//remove class ss
clickedBlock.removeClass('ss');
} else { //else
if ($(blockSelected).attr('style-id') == clickedBlock.attr('style-id')) {
//if style selected div equals style clicked div
//ad class x to selected div or better: remove div
$(blockSelected).remove();
//ad class x to clicked div or better: remove div
clickedBlock.remove();
//deduct 2 of the total tiles
totalTiles = totalTiles - 2;
} else { //if not equal styles
//remove class ss form the selected div
$(blockSelected).removeClass('ss');
//remove class ss from the clicked div
clickedBlock.removeClass('ss');
}
}
blockSelected = null;
} else {
blockSelected = this;
}
});
现在,当您单击具有相同sytle-id的两个块时,它们将被删除。单击第一个块然后单击不匹配的块时,将删除样式。
答案 2 :(得分:1)
如果您对完全不同的方法感兴趣,请考虑以下事项:
var BLOCK_PAIR = (function() {//Singleton NAMESPACE pattern.
//Private vars
var blocks = $(),
delay = 500,
selClss = 'ss',
compareAttr = 'style-id',
disabled = false;
//Private functions
var select = function(e) {
var $b = $(e.target);
if(disabled) return;
if( blocks.length == 1 && blocks.not($b).length == 0 ) {
reset();//allow first block to be deselected
return;
}
if( blocks.length >= 2 ) reset(); //should never happen
blocks = blocks.add($b.addClass(selClss));
compare();
};
var compare = function() {
if(blocks.length == 2) {
if(blocks.eq(0).attr(compareAttr) == blocks.eq(1).attr(compareAttr)) {
setTimeout(remove, delay);
}
else {
setTimeout(reset, delay);
}
disabled = true;//inhibit block selection during timeout delay.
}
};
var remove = function() {
blocks.remove();
reset();
};
var reset = function() {
blocks.removeClass(selClss);
blocks = $();
disabled = false;
};
//Expose private functions as public methods
return {
select: select,
};
})();
$(function() {
$('#plane').on('click', '.tile', BLOCK_PAIR.select);
});