Reputation: 2286
I have an element (#cols
) that's 3x wider than the <body>
. It has 3 columns, each of which is exactly as wide as <body>
. Clicking a button slides the #cols
element over by the width of one column and simultaneously focuses the <input>
in the column that's sliding into view:
http://jsbin.com/puhurakewa/1/edit?html,css,js,output
The problem, as you can see from the demo, is that focusing the input causes weird behavior. I believe the browser says,
"Crap, the user focused an input that's off-screen. I need to show it!"
and then magically scrolls the input into view. This breaks the transition.
Is there a way to disable this behavior? It's extremely undesirable. I've noticed it in Chrome, Safari, and Firefox on my Mac.
EDIT: Thank you for the answers so far. I should have been more specific with my question. I'm aware that I can "work around" this issue by waiting for the animation to end, but what I'm curious about is how to work through this issue and focus the input immediately. It's a better experience, because users can begin typing before the transition is over.
Upvotes: 5
Views: 2489
Reputation: 2541
magically scrolls the input into view
This is the key. Just change scrollLeft
of the container to 0
after focusing. I had to put a wrapper around it though.
http://jsbin.com/danarucama/1/edit?html,css,js,output
Upvotes: 1
Reputation: 1615
Since you already using Jquery might as well leverage the animate method, then on the complete function you focus the input, for more info check out the docs
Heres the JS (this works perfectly, but spend some time neatening it up/refactoring if you wish):
$(document).ready(function () {
$('button').on('click', function () {
var colId = $('.showing').attr('id');
if(colId == "col-1"){
$('#cols').animate({
right: '200px'
}, 1000, "swing", function(){
$("#col-2").find('input').focus();
$('#col-1').removeClass('showing');
$('#col-2').addClass('showing');
});
}
else if(colId == "col-2"){
$('#cols').animate({
right: '400px'
}, 1000, "swing", function(){
$("#col-3").find('input').focus();
$('#col-2').removeClass('showing');
$('#col-3').addClass('showing');
});
}
else if(colId == "col-3"){
$('#cols').animate({
right: '0px'
}, 1000, "swing", function(){
$("#col-1").find('input').focus();
$('#col-3').removeClass('showing');
$('#col-1').addClass('showing');
});
}
});
});
Then change your CSS to position relative like so:
#cols {
height: 100%;
transition: transform 400ms;
white-space: nowrap;
width: 600px;
position:relative;
}
HTML (just add 'showing' class to first col):
<body>
<button>Shift Cols & Focus Input</button>
<div id="cols" col-to-show="1" >
<div class="col showing" id="col-1">
<input type="text" value="1" />
</div>
<div class="col" id="col-2">
<input type="text" value="2" />
</div>
<div class="col" id="col-3">
<input type="text" value="3" />
</div>
</div>
</body>
Here's a fiddle
Upvotes: 1
Reputation: 7257
Add the focus event after transition ends
$('#cols').on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function() {
$input.focus();
});
Upvotes: 1