I ran into a problem with jQuery selectors when setting up an ajaxnavigation for a site. The site is based on twitter bootstrap and uses the nav-bar and dropdowns provided by the framework.
I use hashchange events to load new content into section#main
when a link with class="ajaLink"
is clicked.
I got stuck as it seemed the event wouldn't bind to the links in the twitter bootstrap dropdown menu. I investigated the JS for the dropdowns but I couldn't see anything that would prevent the event from being bound and triggered.
In frustration I chanegd the selector from
$(document).on('click', '.ajaxLink', function (e) {
...
}
To
$('.ajaxLink').on('click', function (e) {
...
}
This made the event bind to all the links in the nav-bar and dropdowns, but would leave the links in the dynamically loaded content.
I can't figure out the difference between the two selectors and why I get this behaviour. My solution so far is to use both the selectors, but this doesnt feel as a solution as long as I cant tell for sure the event wont bind twice to the same element.
So question is what is the difference between the two selectors used?
How would I rewrite the selector to make sure I bind each .ajaLink
element only once?
The HTML...
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="container">
<header>
<div class="navbar navbar-inverse">
<div class="navbar-inner">
<div class="container">
<!-- Minimizing the menu under a button when screen gets too small. -->
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
...
</a>
<div class="nav-collapse">
<ul class="nav">
<!-- Choose application. -->
<li class="dropdown">
<a class="dropdown-toggle" href="#" data-toggle="dropdown"> Menu 1 <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class=""><a class="ajaxLink" href="/Blabla">Blabla</a></li>
<li class=""><a class="ajaxLink" href="/Yadayada">Yadayada</a></li>
...
</ul>
</li>
<!-- Choose application. -->
<li class="dropdown">
<a class="dropdown-toggle" href="#" data-toggle="dropdown"> Menu 2 <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class=""><a class="ajaxLink" href="/Blabla2">Blabla 2</a></li>
<li class=""><a class="ajaxLink" href="/Yadayada2">Yadayada 2</a></li>
...
</ul>
</li>
</ul>
<form class="navbar-search pull-right" action="/Home/Search" method="post" >
<input type="search" class="search-query" placeholder="Sök" />
<button type="submit" class="btn btn-inverse" id="search-button ">Search</button>
</form>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
</header>
<div class="log label label-important" style="display:none;" ></div>
<section id="main" style="opacity: 1; ">
<div class="row-fluid">
<div class="span2">
</div>
<div class="span10">
<span class="gradientlabel"><a href="#">Artiklar</a></span>
<table class="table table-striped table-bordered table-condensed overview-table">
<tbody><tr>
<th>
Art No.
</th>
<th>
Description
</th>
<th>
Price
</th>
<th></th>
</tr>
<tr>
<td>
16791
</td>
<td style="overflow:hidden;white-space: nowrap;">
175/70-13 82Q Semperit Ice Grip 2 Dubbat
</td>
<td>
300
</td>
<td>
<a class="ajaxLink" href="/Artiklar/Edit/16791">Edit</a>
</td>
</tr>
<tr>
<td>
16792
</td>
<td style="overflow:hidden;white-space: nowrap;">
195/55-15 85Q Uniroyal Nordic Dubbat
</td>
<td>
550
</td>
<td>
<a class="ajaxLink" href="/Artiklar/Edit/16792">Edit</a>
</td>
</tr>
...
</tbody></table>
</div>
</div>
</section>
<footer>
</footer>
</div>
</body>
</html>
The Javascript
//Add event for all ajaxLink (except for the ones in the bootstrap dropdown)
$(document).on('click', '.ajaxLink', function (e) {
var self = $(this);
if (self.attr('href').length > 2) {
window.location.hash = "!" + self.attr('href');
}
return false;
});
//I dont really know yet, but this is the only way to attach the event to bootstraps dropdown, and also have to close the dropdown programmatically.
$('.ajaxLink').on('click', function (e) {
var self = $(this);
//if (self.prop('tagName') != 'A') { alert('not a link'); self = self.find('a:first'); }
if (self.attr('href').length > 2) {
window.location.hash = "!" + self.attr('href');
}
self.closest('.dropdown').removeClass('open');
return false;
});