J'ai un menu déroulant d'amorçage ci-dessous. Il contient un lien relié à une liaison knockout.js, qui renvoie false car je ne souhaite pas que la balise # soit envoyée à l'URL du navigateur. Cependant, cela ne ferme pas le menu déroulant lorsque je clique sur le lien. En tout cas autour de ça?
HTML
<div class="btn-group">
<button class="btn dropdown-toggle" data-toggle="dropdown" data-bind="enable: !noResults()"><i class="icon-download-alt" ></i> Export <span class="icon-caret-down"></span></button>
<ul class="dropdown-menu">
@foreach(var exportUrl in Model.ExportUrls)
{
<li>
<a href="#" data-bind="disable: noResults(), download: { url: '@exportUrl.Value', data: data }"><img src="/Content/less/images/img/@(exportUrl.Key.ToString().ToLower()).png" alt="@exportUrl.Key.GetDisplayName()"/> @exportUrl.Key.GetDisplayName()</a>
</li>
}
</ul>
</div>
knockut.js contraignant
ko.bindingHandlers.download = {
init: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
id = 'download-iframe-container',
iframe;
$(element).unbind('click').bind('click', function () {
iframe = document.getElementById(id);
if (!iframe) {
iframe = document.createElement("iframe");
iframe.id = id;
iframe.style.display = "none";
}
if (value.data) {
iframe.src = value.url + (value.url.indexOf('?') > 0 ? '&' : '?') + $.param(ko.mapping.toJS(value.data));
} else {
iframe.src = value.url;
}
document.body.appendChild(iframe);
return false;
});
}
};
Attribuez une classe à vos liens (téléchargement, par exemple):
<a href="#" class="download" data-bind="disable: noResults()....
Et votre liste déroulante un identifiant (par exemple, dlDropDown):
<button class="btn dropdown-toggle" id="dlDropDown" data-toggle="dropdown" data-bind="enable: !noResults()">
Et ajoutez ensuite le gestionnaire d'événements suivant:
$("a.download").click(function() {
$("#dlDropDown").dropdown("toggle");
});
Cela fonctionnera réellement avec votre balisage de démarrage existant sans avoir à ajouter de nouvelles classes ou identifiants. J'espère que cela sera utile à quelqu'un qui voudrait simplement laisser tomber une solution sans rien changer.
$(".dropdown-menu a").click(function() {
$(this).closest(".dropdown-menu").prev().dropdown("toggle");
});
Ceci peut être réalisé avec les bootstraps de la classe CSS dropdown-toggle
Ajoutez simplement cette classe à vos éléments de lien, comme ceci: <a class='dropdown-toggle'></a>
et le menu déroulant sera basculé.
Je pense que cela fermera tous les menus déroulants et les menus de navigation étendus sur la page:
$('.in,.open').removeClass('in open');
Utiliser event.preventDefault()
au lieu de return false
fait l'affaire.
Changez votre code pour:
$(element).unbind('click').bind('click', function(e) {
e.preventDefault();
// ...
return true; // or just remove the return clause
});
Malheureusement, je n'ai pas réussi à utiliser .dropdown('toggle')
comme suggéré ci-dessus ...
Cependant, ce qui a bien fonctionné a été d'appliquer les attributs de données du bouton déroulant de bootstrap à ses propres liens déroulants:
<button type="button" data-toggle="collapse" data-target=".navbar-collapse" class="navbar-toggle navbar-btn">
...
<ul class="nav navbar-nav">
<li><a href="#about" class="scroll-to" data-toggle="collapse" data-target=".navbar-collapse">About</a></li>
Tout ce que je fis, c’est d’ajouter les data-toggle="collapse"
et data-target=".navbar-collapse"
à chaque lien de navigation déroulant.
Aucun css ou js supplémentaire et cela a fonctionné comme un charme :)
Changez simplement le href="#"
en href="javscript:void(0);"
puis return true
dans votre événement click (au lieu de false
)
Une solution plus propre pour conserver la fonctionnalité de liste déroulante et obtenir ce que vous recherchez.
$("body").on('click', function (e) {
if (!$(e.target).hasClass("open") && $(e.target).parents(".btn-group.open").length == 0)
$(this).find(".btn-group.open a").trigger("click");
});
Si vous avez un paramètre d'événement, faites simplement:
$(element).unbind('click').bind('click', function (event)
{
event.preventDefault();
return true;
});
vous pouvez également ajouter un masque transparent pour bloquer tout autre clic indésirable lorsque la liste déroulante est ouverte:
OnDomReadyHeaderItem.forScript("$('.dropdown').on('shown.bs.dropdown', function (e) { $(this).append('<span id=\"transparent-mask\"></span>')})"));
OnDomReadyHeaderItem.forScript("$('.dropdown').on('hidden.bs.dropdown', function (e) { $('#transparent-mask').remove()})"));
avec le masque:
.dropdown.open #transparent-mask{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: block;
margin: auto;
height: initial;
z-index: 1000 !important;
}
la meilleure réponse sera de cliquer afin que l'utilisateur agisse de la même façon que l'utilisateur clique avec la souris pour masquer le menu déroulant. Pour ce faire, ajoutez ce code d'instantané à votre page:
<script>
$(document).ready(function () {
$("li.dropdown ul.dropdown-menu li").click(function (event) {
event.toElement.parentElement.click();
})
})
</script>