2015-11-06 63 views
0

我刚刚开始玩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>

+0

http://stackoverflow.com/questions/3731361/click-event-executed-only-the-first-time 的http:// stackoverflow.com/questions/10194728/jquery-click-event-works-only-once 和许多 –

+0

我建议你在浏览器中打开调试器,并在每个点击处理程序中放置一个断点。我怀疑你会发现两个点击处理程序正在运行,并且每个处理程序都执行另一个处理程序的反转处理,所以你不会看到任何净变化。 – dsh

回答

2

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

该第一行仅将click函数绑定到当前具有'.selected'类的元素 - 因此只有HTML中的第一个锚标记具有绑定到它的单击事件。调用此事件答:

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

在单击该第一锚,你绑定一个新的单击事件到锚的所有四个(因为你已经从第一锚删除“.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/

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; 
}); 
+0

我会挑剔一点,对不起。 :)这段代码有效(除非它不会从被选中的项目中删除'selected'状态,这可能是无意中的行为) - 但这里给出的原因是不正确的:删除类不会删除该事件或使其“不再被发现”。这个原因是因为你将click事件绑定到所有四个锚点 - 如果在事件之后添加了新的.option锚点,它不会拾取事件(并且类似地,如果删除选项类,这不会消除事件。) –

+0

但是,在添加新选项定位符的地方无法读取 –

+0

的确,这只是一个示例,可以帮助解释绑定发生了什么。 –