为什么一次性功能?

时间:2015-11-06 13:17:19

标签: jquery

我刚刚开始玩jQuery,并创建了一个简单的功能。它工作正常,除了事实,它是活跃的,并且只是第一次继续工作。 (函数本身就像选择列表)。当您再次单击它时它没有响应。



    $('.selected').click(function(){
            $(this).removeClass('selected').addClass('selectoption');
            $('.selectoption').show().click(function(){
                $(this).removeClass('selectoption').addClass('selected');
                $('.selectoption').hide();
            });
        return true;
    });

.selectoption {
    display: none;
    float: right;
    clear: both;
    margin-top: 3px;
    padding: 5px 10px 5px 10px;
    text-align: right;
    color: #FFFFFF;
    background: #3399FF;
    border: solid #ffcc00 1px;
}
.selected {
    display: block;
    border-bottom: dashed #3399FF 1px;
}

<div style="display: block; position: absolute; top: 32px; right: 220px; border: 0;">
                            <a href="#" class="selected">1</a>
                            <a href="#" class="selectoption">2</a>
                            <a href="#" class="selectoption">3</a>
                            <a href="#" class="selectoption">4</a>
                        </div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

.click()仅绑定绑定事件时存在的DOM节点。您的代码假定事件绑定到事件本身发生时存在的DOM节点。

第一行将click函数仅绑定到当前具有'.selected'类的元素 - 因此只有HTML中的第一个锚标记绑定了一个click事件。将此事件称为A:

$('.selected').click(function(){
        $(this).removeClass('selected').addClass('selectoption');

单击第一个锚时,将新的click事件绑定到所有四个锚点(因为您已从第一个锚点中删除了'.selected'类并添加了'.selectoption')。将此事件称为B:

        $('.selectoption').show().click(function(){
            $(this).removeClass('selectoption').addClass('selected');
            $('.selectoption').hide();
        });
    return true;
});

因此,在第一次单击锚点1后,锚点1将在下次单击时触发事件A和事件B(将新事件绑定到同一元素不会替换现有事件)。其余的锚点只会触发事件B.

您实际需要的行为可以通过在父元素上使用.on()来实现 - 这有效地将事件绑定到CSS选择器而不是特定的DOM节点,这样当用户单击父元素时,代码将检查被点击的目标是否与类选择器匹配:

    $('.parent')
      .on('click', '.selected', function(evt) {
        $(evt.target).removeClass('selected').addClass('selectoption');
      }).on('click', '.selectoption', function(evt) {
        $('.selected').removeClass('selected').addClass('selectoption');
        $(evt.target).removeClass('selectoption').addClass('selected');
      });
.selected {
  background-color: #F00
}
.selectoption {
  background-color: #0F0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
  <a href="#" class="selected">1</a>
  <a href="#" class="selectoption">2</a>
  <a href="#" class="selectoption">3</a>
  <a href="#" class="selectoption">4</a>
</div>
(我删除了hide()show()并更改了css规则,以便更容易查看正在发生的事情,但除此之外,我的行为符合我的意图。)

所以现在两个点击事件绑定到.parent;如果父级内的点击目标与.select匹配,则第一个将触发,如果点击目标与.selectoption匹配,则第二个将触发 - 与原始代码不同,类匹配是实时的,因此您可以安全地更改DOM元素上的类,或者在绑定事件后添加新元素,并使行为遵循新的类名。

在此处阅读“委派活动”以获取更多详细信息:http://api.jquery.com/on/

答案 1 :(得分:0)

您正在删除一个类,因此无法再找到它。最好添加一个额外的类来收听点击

<div style="display: block; position: absolute; top: 32px; right: 220px; border: 0;">
    <a href="#" class="option selected">1</a>
    <a href="#" class="option">2</a>
    <a href="#" class="option">3</a>
    <a href="#" class="option">4</a>
</div>

然后将脚本简化为

$('.option').click(function() {
    $(".option").removeClass('selected'); // we need to remove all selected classes first ;)
    $(this).addClass('selected');
    return true;
});