bxSlider cuts off slide viewing mobile - javascript

I am using bxSlider and it's working great...I'm having a slight issue with some functionality...when I view the slideshow on mobile it shows 1.5...basically one full slide and then part of the next one. In the code, I have minSlides set to 1 and maxSlides set to 3...what I'd like to do is have bxSlider display a particular li only if the entire li will fit on the screen. For example, my div's are 300px wide, in order to show two of them your screen size would have to be at least 600px wide...is that possible?
I created a fiddle: https://jsfiddle.net/785gcrnp/.
The example page is: http://joshrodg.com/hallmark/ - all the way on the bottom in the dark area where it says "Latest Media".
Thanks,
Josh

Nice, looks like you've made some good progress. There is a way you can wrap your current code in a function and call it when the window resizes or orientation changes.
Here's what it would look like wrapped in a function:
function adjustSlider(){
var sw = 200;
var sm = 20;
var ms = Math.floor($('#nocrop').width() / (sw + sm));
$('#nocrop .bxslider').bxSlider({
pager: false,
slideWidth: sw,
slideMargin: sm,
maxSlides: ms > 1 ? ms : 1,
});
}
Then, we need to call this function when the document first loads, otherwise your calculations will only get used when the window resizes:
$(document).ready(function(){
adjustSlider();
});
Then, we add a window resize event. I place the call to the adjustSlider fucntion inside a timer so it helps if the window is resized a bunch within a short amount of time. We can also add the onorientationchange event in here too that makes the same call. Orientation changes have their own delays built in and this event doesn't fire off as frequently as window resize, so I didn't put this in a timer.
$(window).resize(function(){
setTimeout(function(){
adjustSlider();
}, 250);
});
window.onorientationchange = function(event){
adjustSlider();
}
250 ms for the timer might be a little high, feel free to adjust this. It still feels pretty weighty to me when resizing the panes on jsfiddle. This could be due to how the javascript is being run inside jsfiddle, or it could have something to do with the way this slider is handling having it's properties set. It will show best on your actual site, so do some testing there to be sure speed and performance don't become an issue with this. Let me know how it goes!
Also, here is a working jsfiddle for an example of how it all looks when put together: http://jsfiddle.net/sm1215/0517f76w/4/
edit: words, woops also placed the onorientationchange inside the resize event, which wouldn't work. This is fixed and I've updated the fiddle.

A friend of mine helped me get this working!
I have updated the fiddle: https://jsfiddle.net/785gcrnp/1/
var sm = 20;
var podcastSlider;
function podcastSettings() {
var minmax;
var win=$(window).width();
if(win > 960) {
minmax=3;
var sw = 300;
} else if(win > 660) {
minmax=2;
var sw = 300;
} else {
minmax=1;
var sw = 480;
}
var sliderSettings={
adaptiveHeight: true,
infiniteLoop: false,
maxSlides: minmax,
mode: 'horizontal',
nextSelector: '.next',
nextText: 'Next',
pager: false,
prevSelector: '.prev',
prevText: 'Prev',
slideMargin: sm,
slideWidth: sw
};
return sliderSettings;
}
$(window).resize(function() {
podcastSlider.reloadSlider(podcastSettings());
});
$(document).ready(function(){
podcastSlider = $('.podcast').bxSlider(podcastSettings());
});
This will center the slides and only show the amount of slides that will be fully visible without cutting anything off.
This is also responsive, so if I resize the browser everything will update as it should.
In addition, I specified a different width for smaller screens.
I hope this helps someone else!
Thanks,
Josh

Related

jQuery height change not working in Safari

I have a JS feature on the following site that is working just fine in Firefox but not in Safari: http://rossbolger.com/kids/light-stories/
The feature slides out a grid of thumbnails called #image-thumbs when the mouse hovers over the container called #hit-area. It works (at least in Firefox) by first changing #image_thumbs height from '48px' to 'auto', the height is then measured using jQuery's height(). This height is stored in a variable and then using jQuery's css() it is given back to the #image-thumbs when the mouse is over.
The code on the site looks a little something like this:
// Thumbnails Nav Reveal and Hide Scripts
var thumbs_height = 1,
thumbs = $('#image-thumbs'),
thumbs_original_height = thumbs.css('height');
// Slide Up Thumbs
(function revealThumbs() {
// On hover let the thumbs become their full height
$('#image-thumbs #hit-area').hover(function(){ // Mouse over
// Get the unrestricted height of the thumbs
thumbs.css('height', 'auto');
thumbs_height = thumbs.height();
// then put it back to what it was so we can animate it using CSS3 transition
thumbs.css('height', 'inherit');
// delay 0.1s before triggering the change in height (time for the calculations to complete)
setTimeout( function() { thumbs.css('height', thumbs_height ) }, 100 );
}, function(){ // Mouse out
hideThumbs();
});
})();
// Hide thumbs
function hideThumbs(){
thumbs.css('height', thumbs_original_height );
};
The reason for measuring the unrestricted height and passing it back as a pixel value, rather than simply setting the height to 'auto', is to create a sliding effect via CSS3 (i.e. transition: height 0.5s). The transition only takes place if the affected attribute goes from one numeric value to another.
Thanks for any help bug testing this. I haven't even looked at other browsers yet.
All the best,
Laurence
Okay, so I've worked it out...
In the javascript document (scripts.js on the site) there was a function higher up the page calling the hideThumbs() function. So it wasn't working because the variables in hideThumbs() hadn't been declared at that point. Funny that it should still work in Firefox and IE9!
I've moved all this code to a point before that other function and the problem is now resolved. So far I've only done this locally. I'll update the site in the link above later.

javascript not updating css attribute on modal popup

I have the following javascript code:
<script type="text/javascript">
function doPopup(file){
var dlg=$('#popup').dialog({
resizable: false,
autoOpen: false,
modal: true,
hide: 'fade',
position: ['center', 'center']
});
dlg.load(file, function(){
dlg.dialog('open');
});
var maskHeight = $(document).height();
var maskWidth = $(window).width();
$('#mask').css({'width':maskWidth, 'height':maskHeight});
$('#mask').fadeTo("slow", 0.85);
dlg.parent().css('z-index', 9001);
dlg.parent().css('position', 'absolute');
//alert('I'm an alert');
if(file.indexOf("CustomerCouponDisplay.asp" !== -1)) {
var imgWidth = $('#couponImg').width();
var winW = $(window).width();
dlg.parent().css('left', (winW - imgWidth)/2);
}
}
</script>
Essentially, when this function is called, it takes in a file name of a web page and displays the contents in a modal popup.
When the code is run as is, the general expected behavior happens according to plan: the mask div takes over the screen, fades to dark, and the popup shows up.
The problem: Our coupon image is way too big for the popup div, so I have an if statement in there that will automatically re-center the popup on the screen. However, this re-centering never happens, despite that code being executed.
The fun part: If I uncomment that alert, the image still shows up off-center. Upon clicking OK to dismiss the alert, the screen redraws and the image is now centered as desired.
I've tried a number of things, including different ways of accessing the popup's parent, different ways of supplying the arguments to css(), putting the popup.parent.css line in a number of different places, hardcoding the 'left' value, opening the dialog only after everything is loaded and css updated (this one broke everything), and several other things that also did not work.
My current thought: I saw in one not-really-related post that the reason some of the CSS styles weren't being updated was because "the animation was taking too long" (or something like that). I am certainly making the html rewrite with the dialog and mask fading, so could that somehow be related to the 'left' attribute not taking over?
My rejection of my current thought: I feel like this is NOT the case, because RIGHT BEFORE I try setting the 'left' attribute, I'm successfully setting other attributes for the same component, and they take effect without issue. In case it WAS the fadeTo line, I even moved that at the bottom. Same thing happened: not centered until after the alert was closed.
Thoughts?
Edit: just on the offchance this is relevant, this is being run on an ASP page. It is not .NET.
The clue is the alert. It shows that the code that tries to resize is occuring before the dialog has loaded and opened.
Try putting the code for manipulating the dialog into the event handler for the opening of the dialog.
See here
function doPopup(file){
var dlg=$('#popup').dialog({
resizable: false,
autoOpen: false,
modal: true,
hide: 'fade',
position: ['center', 'center'],
open: function () {
var dialogParent = $(this).parent();
var maskHeight = $(document).height();
var maskWidth = $(window).width();
$('#mask').css({'width':maskWidth, 'height':maskHeight});
$('#mask').fadeTo("slow", 0.85);
dialogParent.css('z-index', 9001);
dialogParent.css('position', 'absolute');
if(file.indexOf("CustomerCouponDisplay.asp" !== -1)) {
var imgWidth = $('#couponImg').width();
var winW = $(window).width();
dialogParent.css('left', (winW - imgWidth)/2);
}
}
});
dlg.load(file, function(){
dlg.dialog('open');
});
}

How to resize Facebook Canvas app (iFrame) correctly?

I need to adjust canvas size after updating content of a page. I can do it explicitly by
FB.Canvas.setSize({ width: 760, height: 1480 });
however, it doesn't work without parameters, i.e. .setSize().
Also, I can adjust the height by
FB.Canvas.setAutoResize(true);
but only increasing - it doesn't reduce the height when content is reduced.
The following lines do not work:
FB.Arbiter.inform("setSize", FB.Canvas._computeContentSize());
FB.Canvas.setSize(FB.Canvas._computeContentSize());
How can one make it working?
Some more comments on the subject:
http://developers.facebook.com/blog/post/93
http://developers.facebook.com/docs/reference/javascript/fb.canvas.setautoresize
Related:
facebook-api: what's Facebook Connect cross-domain receiver URL?
facebook-app: how can i change the height of a resizeable iframe application?
Document height grows on resize when setting canvas dimensions dynamically
How do you control the size of your Facebook Canvas apps?
Don't write your own function for timed Auto-resize. Fb has one:
FB.Canvas.setAutoResize();
If you know when you need to resize it use
FB.Canvas.setSize()
So, if you want to make is smaller when you click a link, stick it in a function and then call that function later like:
function sizeChangeCallback() {
FB.Canvas.setSize();
}
//start some function or on click event - here i used jquery
$("#something").click(function() {
sizeChangeCallback()
});
You don't need to set an explicit height, but sometimes you can have trouble with dynamic xfbml elements like the comments plugin. Try using an event subscribe callback:
FB.Event.subscribe('xfbml.render', function(response) {
FB.Canvas.setAutoResize();
});
http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setSize/
http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setAutoResize/
http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/
I have managed to make .setSize() working by delaying its execution (as suggested on various forums):
window.setTimeout(function() {
FB.Canvas.setSize();
}, 250);
If you have XFBLM elements, especially fb:comments, then you need to parse the page before setting its size
window.setTimeout(function() {
FB.XFBML.parse();
FB.Canvas.setSize();
}, 250);
Note, that you need to run this script after your content block, otherwise increase the time interval (in ms) allowing webserver and client browser building the content before resizing canvas.
This approach only increases the height of your page and doesn't decrease it. You can achieve decreasing manually by firing the following line before the code above
FB.Canvas.setSize({height: 480}); // min height - .setSize() won't reduce it
however, there is a drawback - the page will be blinking due to the double resizing.
Also, one suggests running .setSize in several time intervals to account delayed content:
FB.Array.forEach([300, 600, 1000, 2000], function(delay) {
setTimeout(function() {
FB.XFBML.parse();
FB.Canvas.setSize();
}, delay)
});
In this case, the page and XFBML elements become quite blinky.
We have pages in our iframe that append content to the page and then allow the user to refresh the content within the page in place. In these cases, we saw the same thing, where the content would not shrink when appropriate.
FB.Canvas.setSize() calls _computeContentSize, which is shown below:
_computeContentSize: function() {
var body = document.body,
docElement = document.documentElement,
right = 0,
bottom = Math.max(
Math.max(body.offsetHeight, body.scrollHeight) +
body.offsetTop,
Math.max(docElement.offsetHeight, docElement.scrollHeight) +
docElement.offsetTop);
if (body.offsetWidth < body.scrollWidth) {
right = body.scrollWidth + body.offsetLeft;
} else {
FB.Array.forEach(body.childNodes, function(child) {
var childRight = child.offsetWidth + child.offsetLeft;
if (childRight > right) {
right = childRight;
}
});
}
if (docElement.clientLeft > 0) {
right += (docElement.clientLeft * 2);
}
if (docElement.clientTop > 0) {
bottom += (docElement.clientTop * 2);
}
return {height: bottom, width: right};
},
The problematic line is here:
bottom = Math.max(
Math.max(body.offsetHeight, body.scrollHeight) +
body.offsetTop,
Math.max(docElement.offsetHeight, docElement.scrollHeight) +
docElement.offsetTop);
Even if the content inside your iframe has shrunk, the value of body.offsetHeight will not shrink.
To solve this, we made a custom version of the computeContentSize function that only consults the docElement for height, like so:
function rfComputeContentSize() {
var body = document.body,
docElement = document.documentElement,
right = 0,
bottom = Math.max(docElement.offsetHeight, docElement.scrollHeight) + docElement.offsetTop;
if (body.offsetWidth < body.scrollWidth) {
right = body.scrollWidth + body.offsetLeft;
} else {
FB.Array.forEach(body.childNodes, function(child) {
var childRight = child.offsetWidth + child.offsetLeft;
if (childRight > right) {
right = childRight;
}
});
}
if (docElement.clientLeft > 0) {
right += (docElement.clientLeft * 2);
}
if (docElement.clientTop > 0) {
bottom += (docElement.clientTop * 2);
}
return {height: bottom, width: right};
}
Anytime we want to resize and know that the content could shrink we'll use the custom function to pass content to setSize (e.g. FB.Canvas.setSize(rfComputeContentSize())), and anytime we know that the content will only grow, we'll use the standard FB.Canvas.setSize() function.
Note that we were using setAutoGrow() and I didn't check, but am assuming that it uses the same function to determine size. We disabled our call to setAutoGrow() and will have to be vigilant about calling setSize() at approrpriate times.
Logged this bug with Facebook: https://developers.facebook.com/bugs/228704057203827
We ran into an issue where their FB.Canvas functions didn't work, although everything was properly initialized, because they’re using ‘IFRAME’ instead of iframe in their cross-domain JS setup, hence no XHTML compatibility.
We fixed this by prototyping our own createElement function and overriding theirs.
Just put this right after you include Facebooks all.js:
document.__createElement = document.createElement;
document.createElement = function(tagName) {
return document.__createElement(tagName.toLowerCase());
}
bit of excess functionality, but this article explains why you cant do that dynamically and provides the easiest solution...
http://www.twistermc.com/36764/shrink-facebook-tabs/
The answer is simple:
Shrink it really small, then after a pause use AutoGrow to make it the correct size... Alice in Wonderland style.
I say easiest because from a dev and user point of view this slows things down by about 1/4 second, and the user gets a tiny flash of the scrollbars...
Bobby's answer is very good. Only thing I would add to it is that some people have had success getting the page to shrink by doing the following:
FB.Canvas.setSize({ width: 760, height: 10 });
And then follow it with:
FB.Canvas.setAutoResize();
You don't have to use 10, just something smaller than the minimum size of your page. Then the FB.Canvas.setAutoResize() should go ahead and make it the proper height again and continue to update. The only time you need to call FB.Canvas.setSize({ width: 760, height: 10 }); again would be if the content shrunk again.
The danger of doing this is that if the FB.Canvas.setAutoResize(); doesn't work, you could have content that is cut off.
None of this worked for me. Make sure to type this before the closing tag.
<div id="fb-root"></div>
<script type="text/javascript">
window.fbAsyncInit = function() {
//Der folgende Code ändert die Grösse des iFrames alle 100ms
FB.Canvas.setAutoResize(100);
};
(function() {
var e = document.createElement('script');
e.async = true;
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>
I tried to use FB.Canvas.setSize(e); to resize my app, but it did not resize at all.
I took a look in the Facebook Javascript and found out, that FB.Canvas.setSize calls the FB.Arbiter.inform('setSize',e) function.
If I call the FB.Arbiter.inform('setSize',{ width: 760, height: 1480 }) function right from my code, the canvas resizes correctly.
This has worked for me:
<script type='text/javascript'>
window.onload=function() {
FB.Canvas.setSize({width:760,height:document.body.offsetHeight});
}
</script>
Note that you don't need FB.init unless you are using it for other reasons.
When resizing to the minimum height do not forget to make it a little bit bigger than it is, to account for horizontal scrolling bar and some extra pixels that some browsers add, otherwise you will end-up with vertical scroll.
Also I do not recommend to use body to count height.
This worked for me :
window.fbAsyncInit = function()
{FB.Canvas.setSize({height:document.getElementById('m_table').offsetHeight+40});}
where m_table is table ID with all my content (you can use div instead).

Jquery Cycle + Firefox Squishing Images

I am running jQuery Cycle for an image gallery. View the link: Here
My problem is that the images are getting squished when viewed in firefox. The problem disappears when I re-load the page. This leads me to believe that the Javascript is triggering before all the images are loaded (usually the first image works fine and the rest are squished.)
A hard re-fresh reproduces the problem.
I've wrapped everything in a $(document).ready(function(){ }); but it still happens.
Additional Info: If I specify the width and height of the image, everything works fine. However there are hundreds of images all at different sizes..
I'm pretty frustrated with this problem. Any ideas/help is greatly appreciated!
Here is my code:
$(document).ready(function(){
//function onBefore(curr,next,opts) {
// var $slide = jQuery(next);
// var w = $slide.outerWidth();
// var h = $slide.outerHeight();
// $slide.css({
// marginTop: (482 - h) / 2,
// marginLeft: (560 - w) / 2
// });
//};
// Decare the function that center the images...
function onBefore(curr,next,opts) {
var $slide = jQuery(next);
var w = $slide.outerWidth();
var h = $slide.outerHeight();
$slide.css({
marginTop: (480 - h) / 2,
marginLeft: (560 - w) / 2
});
};
$(document).ready(function() {
$('#slideshow').cycle({
fx: 'fade',
next: '#next',
pause: 0,
speed: 500,
before: onBefore,
prev: '#prev',
pause: '#pause',
pager: '.thumbs',
pagerClick:function(zeroBasedSlideIndex, slideElement) {$(slideElement).find('div.cover').hide();},
pagerAnchorBuilder: function(idx, slide) {
var src = $('img',slide).attr('src');
//Change height of thumbnail here
return '<li><img src="' + slide.src + '" height="90" /></li>';
}
});});});
There is a much simpler and cleaner solution that I used to solve this problem than what has already been proposed:
Using jQuery, you need to use $(window).load instead of $(document).ready for your particular situation. To fix the issue, change this:
$(document).ready(function() {
$('#slideshow').cycle({
/* ... */
});
});
To this:
$(window).load(function() {
$('#slideshow').cycle({
/* ... */
});
});
Why does this work? Because window.onload fires after all referenced images on the page are loaded (See https://developer.mozilla.org/en/DOM/window.onload, and .load() - jQuery API), which is the desired behavior in your situation. $(document).ready, better known as "DOM Ready", will fire before images have loaded. This is typically the desired behavior, but in your situation it's too early.
I had the same problem when working on a site several months ago (linked below). If you're starting cycle in $(document).ready(), here's what happens when a client browses to your page:
1) The client's browser sends a request for each img element. Those requests take variable amounts of time to fulfill.
2) Before the image requests are completed, cycle starts. Cycle works by hiding all but the first image in the slide show: it sets visibility:hidden and display:none on each of its images.
The problem is that Firefox fixes the img element's size once and for all at the point the display style is set to none. So if the image hasn't finished loading, its height and width style attributes are small (I'm not sure exactly what they correspond to - perhaps the size of Firefox's image placeholder). When cycle shows the image by setting its style attribute to display:block, it uses whatever dimensions it had at the time it was hidden.
I solved this by changing my code so that it doesn't start the cycle plugin until all the images are finished loading. To do that, I initialize a counter variable to the number of images I'm cycling, then bind a load event to each image like this:
var imagesRemaining = 12; // 12 is just the number of images in the slideshow div
$(document).ready(function() {
$('#slideshow > img').bind('load', function(e) {
imagesRemaining = imagesRemaining - 1;
if (imagesRemaining == 0) {
// I'm doing some other stuff when initializing cycle
startCycle();
// My images all start with visibility:hidden so they don't show
// before cycle hides them in a 'stack', so ...
$('#slideshow > img').css('visibility', 'visible');
}
});
});
function onBefore(curr, next, opts) { // Your code here ... }
function startCycle() {
$('#slideshow').cycle({ ... // your initialization here });
}
You can see it in action by viewing the galleries on this site in Firefox. I'm building the gallery pages dynamically, so it's structured a bit differently than your page, but you can see more details if you poke around with Firebug.
I'd also like to add that it seems adding a width and height attribute solves this problem.
Ok i know its probably an awfull way of calling load but i just coulnd bind my cycle code to .load for some reason it just don't work so i called the whole Cycle initializer inside the ...
i couldn't force the sizes since i'm cycling through li containing dynamic images and data
its probably flawed at some extend but for those as desperated as me...
Josh, your solution has just saved me a headache, thank you very much!
I think i've amended it slightly in order to handle pages where you don't know the total number of images. It seems to be working fine for me, if anyone can see any flaws, please point them out - i'm still learning.
$(document).ready(function () {
$('#slideshow > img').each(
function go() {
$(this).bind('load', function (e) {
projects();
$('#slideshow > img').css('visibility', 'visible');
});
});
});
function projects() {
$('#slideshow').cycle({
fx: 'scrollHorz',
speed: 300,
timeout: 0,
next: '#next ',
prev: '#prev ',
after: onAfter,
nowrap: 1,
autostop: 1
});
}
If you're using a database to populate the slideshow you could try accessing the image dimensions from the image itself.
For example, using django you can use
width="{{ xxx.image.width }}px" height="{{ xxx.image.height }}px"
in your img tag.
You can use a solution similar to making youtube videos responsive. You need to know the ratio of your width to height, and add that as padding-bottom to the cycling div. For my 1024X680 photos, I used 680/1024 = 66.4%
In your case, I believe
#slideshow{
padding-bottom:66.4%;
}
will show the image unshrunk. I have no idea what the actual height and width values you are working with, so substitute your own. I had to use this solution when the $(window).load solution proved maddeningly ineffective -- so now I use both.
This is better than setting the dimensions of the image, because it's slides into a fluid, responsive enviroment.

JQuery UI Tabs Causing Screen to "Jump"

I'm using the latest version of the jQuery UI tabs. I have tabs positioned toward the bottom of the page.
Every time I click a tab, the screen jumps toward the top.
How can I prevent this from happening?
Please see this example:
http://5bosses.com/examples/tabs/sample_tabs.html
If you're animating your tab transitions (ie. .tabs({ fx: { opacity: 'toggle' } });), then here's what's happening:
In most cases, the jumping isn't caused by the browser following the '#' link. The page jumps because at the midpoint of the animation between the two tab panes, both tab panes are fully transparent and hidden (as in display: none), so the effective height of the whole tabbed section becomes momentarily zero.
And if a zero-height tabbed section causes the page to be shorter, then the page will appear to jump up to compensate, when in reality it's simply resizing to fit the (momentarily) shorter content. Makes sense?
The best way to fix this is to set a fixed height for the tabbed section. If this is undesirable (because your tab content varies in height), then use this instead:
jQuery('#tabs').tabs({
fx: { opacity: 'toggle' },
select: function(event, ui) {
jQuery(this).css('height', jQuery(this).height());
jQuery(this).css('overflow', 'hidden');
},
show: function(event, ui) {
jQuery(this).css('height', 'auto');
jQuery(this).css('overflow', 'visible');
}
});
It will set the computed height of the pane before the tab transition. Once the new tab has appeared, the height is set back to 'auto'. Overflow is set to 'hidden' to prevent content from breaking out of the pane when going from a short tab to a taller one.
This is what worked for me. Hope this helps.
If you have something along these lines:
Tab 1
Try adding return false; after the tab activation command:
Tab 1
My guess is that you are animating your tab transitions? I am having the same problem, where the page scroll jumps back to the top with every click.
I found this in the jquery source:
// Show a tab, animation prevents browser scrolling to fragment,
Sure enough, if I have this:
$('.tab_container > ul').tabs();
$('.tab_container > ul').tabs({ fx: { height: 'toggle', opacity: 'toggle', duration: 'fast' } });
my code jumps to the top and is annoying (but there's animation). If I change that to this:
$('.tab_container > ul').tabs();
//$('.tab_container > ul').tabs({ fx: { height: 'toggle', opacity: 'toggle', duration: 'fast' } });
there is no tab animation, but switching between tabs is smooth.
I found a way to make it scroll back, but it's not a proper fix, as the browser still jumps to the top after clicking a tab. The scroll happens between the events tabsselect and tabsshow, so the following code jumps back to your tab:
var scroll_to_x = 0;
var scroll_to_y = 0;
$('.ui-tabs-nav').bind('tabsselect', function(event, ui) {
scroll_to_x = window.pageXOffset;
scroll_to_y = window.pageYOffset;
});
$('.ui-tabs-nav').bind('tabsshow', function(event, ui) {
window.scroll(scroll_to_x, scroll_to_y);
});
I'll post any more progress I make.
I was given a solution for this...
How to stop screen from jumping up when tab is clicked:
Wrap the div that contains the tabs in a div with a fixed height.
See example here: http://5bosses.com/examples/tabs/sample_tabs.html
I had the same problem with jquery ui's menu - a preventDefault() on the anchor's click event stops the page from scrolling back to the top:
$("ul.ui-menu li a").click(function(e) {
e.preventDefault();
});
Mike's solution demonstrated the principle greatly but it has a big drawback - if the resultant page is short, the screen will jump to the top anyway! The only solution is to remember the scrollTop, and restore it after the tabs are switched. But before the restoration, enlarge the page (html tag) appropriatelly:
(edit - modified for new Jquery UI API + small improvement for large pages)
$(...).tabs({
beforeActivate: function(event, ui) {
$(this).data('scrollTop', $(window).scrollTop()); // save scrolltop
},
activate: function(event, ui) {
if (!$(this).data('scrollTop')) { // there was no scrolltop before
jQuery('html').css('height', 'auto'); // reset back to auto...
// this may not work on page where originally
// the html tag was of a fixed height...
return;
}
//console.log('activate: scrolltop pred = ' + $(this).data('scrollTop') + ', nyni = ' + $(window).scrollTop());
if ($(window).scrollTop() == $(this).data('scrollTop')) // the scrolltop was not moved
return; // nothing to be done
// scrolltop moved - we need to fix it
var min_height = $(this).data('scrollTop') + $(window).height();
// minimum height the document must have to have that scrollTop
if ($('html').outerHeight() < min_height) { // just a test to be sure
// but this test should be always true
/* be sure to use $('html').height() instead of $(document).height()
because the document height is always >= window height!
Not what you want. And to handle potential html padding, be sure
to use outerHeight instead!
Now enlarge the html tag (unfortunatelly cannot set
$(document).height()) - we want to set min_height
as html's outerHeight:
*/
$('html').height(min_height -
($('html').outerHeight() - $('html').height()));
}
$(window).scrollTop($(this).data('scrollTop')); // finally, set it back
}
});
Works with the fx effect too.
Try using event.preventDefault();. On the click event which is switching the tabs. My function looks like this:
$(function() {
var $tabs = $('#measureTabs').tabs();
$(".btn-contiue").click(function (event) {
event.preventDefault();
$( "#measureTabs" ).tabs( "option", "active", $("#measureTabs").tabs ('option', 'active')+1 );
});
});
Thanks for your help. Good suggestion, but I tried before with no luck. I think JQuery UI may be overriding my efforts.
Here is the code per tab:
<li class=""><span>Two</span></li>
I already tried this with no success:
<li class=""><span>Two</span></li>
Here is a simple example (without return false): http://5bosses.com/examples/tabs/sample_tabs.html
Any other suggestions?
Try just adding a min-height using css to each of the tab content areas ( not the tabs themselves ). That fixed it for me. :)
> var scroll_to_x = 0; var scroll_to_y =
> 0;
> $('.ui-tabs-nav').bind('tabsselect',
> function(event, ui) {
> scroll_to_x = window.pageXOffset;
> scroll_to_y = window.pageYOffset; }); $('.ui-tabs-nav').bind('tabsshow',
> function(event, ui) {
> window.scroll(scroll_to_x, scroll_to_y); });
Thanks for your help! Please let me know what else you find.
The above function works (screen doesn't move permanently)... but, the screen is very wobbly on click.
Here is a simple example showing how clicking a tabs causes the screen to jump toward the top (without the above code):
http://5bosses.com/examples/tabs/sample_tabs.html
Note that there's no animation being used.
I prefer to have an href="#" in my links that do not take the user anywhere, but you can do this as long as you add an onclick="return false;". The key, I guess, is not sending the user to "#", which depending on the browser seems to default as the top of the current page.
There is a much more simple way which I discovered from the comments on this page that is to simply remove the href="#" and it will not jump to the top any more! I verified and it works for me. Cheers
I had such a problem. My code was:
$("#tabs").tabs({
hide: {
effect: "fade",
duration: "500"
},
show: {
effect: "fade",
duration: "500"
}
});
I have simply removed show and it worked like a charm!
$("#tabs").tabs({
hide: {
effect: "fade",
duration: "500"
}
});
I had the same problem, plus mine were rotating on their own so if you were at the bottom of the page, the browser window would be scrolled up tot he top. Having a fixed height for the tab container worked for me. Kind of a weird thing still is that if you leave the window or tab and go back, it will still scroll. Not the end of the world, though.
replace the href="#" with href="javascript:void(0);" in 'a' element
works 100%
I found in my case the tab href=#example1 was causing the page to jump to the position of the id. Adding a fixed height to the tabs made no difference so I just added:
$('.nav-tabs li a').click( function(e) {
e.preventDefault();
});
Did you tryed:
fx: {opacity:'toggle', duration:100}

Categories

Resources