javascript - Fel fokus efter att ha stängt en andra modal
Jag använder vue.js 2 och bootstrap 3 för att öppna en modal som öppnar en andra modal.
För några dagar sedan ställde jag en fråga om hur man sätter fokus på en kontroll som finns i en andra modal. Jag fick ett fantastiskt svar som löste problemet.
Problem När man öppnar den första modalen kan användaren bläddra igenom den för att se dess botten. Men efter att ha öppnat och stängt den andra modalen flyttas fokus till sidan som innehåller den första modalen, och när användaren bläddrar för att se resten av den första modalen bläddrar han på sidan bakom den första modalen.
Det är mycket obekvämt att använda, särskilt när modalen är större än skärmens höjd. Finns det ett sätt att förhindra detta?
För att återskapa detta problem, öppna svaret och klicka på "Expandera utdrag"
Svar #1
Det fungerar för mig:
$('#my-modal').on('hidden.bs.modal', function () {
$('body').addClass('modal-open');
});
Svar #2
Här är en modifierad version av det tidigare svaret som återställer fokus till den ursprungliga modala efter att undermodalen stängts.
Förändringen är här:
$(this.$refs.submodal.$el).on("hidden.bs.modal", this.onShown)
Detta läggs till i mounted-hanteraren. Det lägger till en hanterare för hidden.bs.modal-händelsen i undermodalen. Det tar också bort hanteraren när komponenten förstörs.
Dessutom, eftersom stängning av en modal tar bort modal-open-klassen som tilldelas body när en modal öppnas, lägger koden nedan till den klassen på body när onShown anropas så att scrollningen inte påverkas för den överordnade modalen.
$("body").addClass("modal-open")
Här är ett fungerande exempel.
console.clear()
Vue.component("sub-modal", {
template: "#submodal",
methods: {
show() {
$(this.$el).modal("show")
},
onShown(event) {
console.log("submodal onshown")
this.$refs.input.focus()
}
},
mounted() {
$(this.$el).on("shown.bs.modal", this.onShown)
},
beforeDestroy() {
$(this.$el).off("shown.bs.modal", this.onShown)
}
})
Vue.component("modal", {
template: "#modal",
methods: {
show() {
$(this.$refs.modal).modal("show")
},
showSubModal() {
this.$refs.submodal.show()
},
onShown(event) {
console.log("parent")
this.$refs.input.focus()
// Add the "modal-open" class back to the body in case
// it was removed by the sub modal
$("body").addClass("modal-open")
}
},
mounted() {
$(this.$refs.modal).on("shown.bs.modal", this.onShown)
$(this.$refs.submodal.$el).on("hidden.bs.modal", this.onShown)
},
beforeDestroy() {
$(this.$refs.modal).off("shown.bs.modal", this.onShown)
$(this.$refs.submodal.$el).on("hidden.bs.modal", this.onShown)
}
})
new Vue({
el: "#app",
})<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://unpkg.com/[email /dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div id="app">
<modal ref="modal"></modal>
<button @click="$refs.modal.show()" class="btn">Show Modal</button>
</div>
<template id="submodal">
<div class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
<input ref="input" type="text" class="form-control">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</template>
<template id="modal">
<div>
<div ref="modal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body" style="height: 80vh">
Stuff
<input ref="input" type="text" class="form-control">
</div>
<div class="modal-footer">
<button @click="showSubModal" type="button" class="btn btn-primary">Show Sub Modal</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<sub-modal ref="submodal"></sub-modal>
</div>
</template>