Open jaygao79 opened 10 years ago
Oh my! I never tested that! Thank you for finding it! Another opportunity for being Sherlock! That's a great question!
@suenotsuan Thank you for looking into this!
@suenotsuan Not to be a pain or something, just wondered if you had any time to look at this?
This is on my bug list but they have me doing more development with debugging at the end. I'll try to look into it today!
Why, when I click on the tab up the scroll in Easy Responsive Tabs to Accordion maquetadoresperu.com/clientes/sunwork/actual/producto1.html
How I can solve it email: jlcallalle@gmail.com twitter: jlcallalle
thanks
This is the web that the problem tab http://maquetadoresperu.com/clientes/sunwork/actual/producto1.html
Finally figured it out! Add this:
$('body').scrollTop(0);
here:
//Tab Click action function
$respTabs.find("[role=tab]").each(function () {
var $currentTab = $(this);
$currentTab.click(function () {
var $currentTab = $(this);
var $tabAria = $currentTab.attr('aria-controls');
$('body').scrollTop(0);
Sorry it took so long jaygao79!
Thank you @suenotsuan it is the idea. Thank you for taking the time to help me as well.
The problem with this solution is that it always scroll to the top of the page. It is fine if the tabs/accordions are at the top of the page, but when I have it lower in the content, or when I have 2 sets of tabs/accordions, it became a problem. The ideal would be for it to scroll to the div id position. For example, I have one horizontal and one vertical on the page, with div id="horizontal-tab", and div id="vertical-tab". Is it at all possible to set the scroll up position to be a variable which equals to the div id to which the clicked tab belongs, instead of a fixed position such as 0 or 100px from the top?
Do you think this is at all possible? Once again thanks for your time.
hi @suenotsuan, I realise that you are probably very busy at the moment. I have tried to work something out based on your solution, but because I am completely useless when it comes to javascript, I can't get it to work. I do think however that the position it should scroll to is the position of the <li id of the tab that I click on. We should be able to get the id from the
Hi @suenotsuan I have managed to figure it out with one tab on the page, although it is not perfect. Because the scrolling should only take place when I click on a tab that's not currently active, the code should be inserted in one of the if conditions. Since I also needed a bit of animation, my code looks like this: if (!$currentTab.hasClass('resp-tab-active') && $currentTab.hasClass('resp-accordion')) { $respTabs.find('.resp-tab-active').removeClass('resp-tab-active'); $respTabs.find('.resp-tab-content-active').slideUp().removeClass('resp-tab-content-active resp-accordion-closed'); $respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active');
$respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + ']').slideDown().addClass('resp-tab-content-active');
$('html, body').animate({scrollTop: $("#horizontalTab").offset().top}, 1000);
I used the id of the tab (#horizontalTab) as the position anchor, which is not ideal. Ideally, it should use the new resp-tab-active class as the anchor but for some reason that doesn't work.
Your code is very similar to what I came up with yesterday. Mine isn't perfect, as there's still a bit of jumpiness to it, but this is what I came up with.
I just needed this action for tabs that are in the accordion mode, my accordion div being C13 and the tabs themselves h2. I didn't want the top tab to do anything.
$(function() { $('#C13 h2:not(:first)').bind('click',function(){ var self = this; setTimeout(function() { theOffset = $(self).offset(); $('body,html').animate({ scrollTop: theOffset.top - 100 }); }, 310); }); });
And then, in the Easy Responsive Tabs.js I added a css call to hide overflow in the click function:
if (!$currentTab.hasClass('resp-tab-active') && $currentTab.hasClass('resp-accordion')) {
$respTabs.find('.resp-tab-active').removeClass('resp-tab-active');
$respTabs.find('.resp-tab-content-active').slideUp().removeClass('resp-tab-content-active resp-accordion-closed');
$respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active');
$respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + ']').slideDown().addClass('resp-tab-content-active').attr('style', 'overflow:hidden');
}
Maybe if we combined our code we'd have a perfect answer. I'm still going to try to make it better.
Thanks for sharing jaygao79!
@suenotsuan thanks and mine is barely a solution to be honest. I think your code would probably work perfectly to my requirement. Can I just ask where should I put the bit below on the page, as I assume it doesn't go into easyresponsivetabs.js? $(function() { $('#C13 h2:not(:first)').bind('click',function(){ var self = this; setTimeout(function() { theOffset = $(self).offset(); $('body,html').animate({ scrollTop: theOffset.top - 100 }); }, 310); }); });
It can go on your HTML page or it can go on a separate script page. I usually keep a utilities.js page with all of my little scripting pieces such as this. That's what I did with this piece.
Hi everyone.
I'm having trouble implementing this bug fix.
I've tried modifying the .js file with the new if statement. I tried in different places and got different behaviour.
One version made it that the accordian would open then close another version made the scroll really slow.
It seems i don't know what i'm doing.
I really like these tabs/accordian - it's perfect as the solution i'm trying. But i can't get top scroll part right.
So i stared and stared at the code.
Was i meant to REPLACE one of the if statements? Because I did and I does seem to work. Still testing.
thats my solution:
inside easyresponsivetabs.js: $respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + ']').slideDown('fast',function () { if (!$currentTab.isOnScreen()) { $('body,html').scrollTop($currentTab.offset().top); } }).addClass('resp-tab-content-active');
and outside: thanks to: http://upshots.org/javascript/jquery-test-if-element-is-in-viewport-visible-on-screen (function ($) { $.fn.isOnScreen = function(){ var viewport = {}; viewport.top = $(window).scrollTop(); viewport.bottom = viewport.top + $(window).height(); var bounds = {}; bounds.top = this.offset().top; bounds.bottom = bounds.top + this.outerHeight(); return ((bounds.top <= viewport.bottom) && (bounds.bottom >= viewport.top)); }; })(jQuery);
This seems to be the best solution I could come up with.. using the activate option:
$('#yourTabContainer').easyResponsiveTabs({
type: 'vertical',
activate: function() {
setTimeout(function() {
$('.resp-accordion.resp-tab-active')[0].scrollIntoView();
}, 500);
}
});
Another possible solution would be to have it close the current active panel first, then have the panel you clicked on slide down:
if (!$currentTab.hasClass('resp-tab-active') && $currentTab.hasClass('resp-accordion')) { $respTabs.find('.resp-tab-active').removeClass('resp-tab-active'); $respTabs.find('.resp-tab-content-active').slideUp('', function() { $respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + ']').slideDown().addClass('resp-tab-content-active') }).removeClass('resp-tab-content-active resp-accordion-closed'); $respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active'); }
I still can't get one particular tab in accordion to open and the focus remain on that tab. It's especially bad if a prior tab's contents are large and you open the next one. the previous one closes, and the screen jumps and focus is completely lost.
This seems to be a workable solution:
In the HTML, add a DIV with id "tab1" above the start of the tab content, so:
<div id="tab1"></div>
<div id="parentHorizontalTab">
Then modify easyresponsiveTabs.js with:
$('html, body').animate({scrollTop:$('#tab1').position().top}, 'slow');
I know virtually nothing about javascript, so didn't know where to add this, but I put it in the same place as @suenotsuan suggested for the scrollTop solution described above, which seems to work:
//Tab Click action function
$respTabs.find("[role=tab]").each(function () {
var $currentTab = $(this);
$currentTab.click(function () {
var $currentTab = $(this);
var $tabAria = $currentTab.attr('aria-controls');
if ($currentTab.hasClass('resp-accordion')) {
$('html, body').animate({scrollTop:$('#tab1').position().top}, 'slow')
};
I wrapped it inside an "if" statement so that it would only apply when in accordion mode - not sure if I've targeted/formed the "if" correctly?
The idea I got from:
http://stackoverflow.com/questions/4565381/scrolltop-jquery-scrolling-to-div-with-id
The page then scrolls to the top of the content whenever a new accordion is opened. It's not perfect (I would prefer that it scrolled to the top of the active accordion), but seems a lot more usable than scrolling all the way to the top of the page as described above and, as long as there are not a huge number of tabs in the list, seems to be quite usable even on very small screens.
If someone can suggest a better place to add the code in the easyresponsiveTabs.js or how to modify it for to replace #tab1 with an identifier for the active accordion, or if my "if" statement could be better expressed, that would be great! This solution was found just by trial and error searching. But it does seem to be an improvement.
@chadkouse Worked perfectly. Awesome solution, thanks for posting
On a mobile, when it turns into accordion, if I am reading a long text on tab 1, at the end of it, I tap on tab 2, then tab 2 opens, but I will be looking at the bottom of tab 2, rather than automatically scrolling up to the beginning of tab 2.
I know this is not an issue, but would be great if it does this. Without this, after tapping on tab 2, I would have to scroll up to the beginning of tab 2 to continue reading.
Any ideas? Thanks for your help.