javascript not updating css attribute on modal popup - javascript

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');
});
}

Related

Fancybox - set widths for different overlays

I have a several blocks of content which open in a Fancybox. This all works as it's meant to but the contents of a couple of the boxes is quite small and doesn't really warrant a 1000px width Fancybox overlay. Is there a way to set the widths of these boxes to something else?
I've tried added a width to the content box (#login-overlay) for example but Fancybox just ignores this as it is built around the content once the relative link has been clicked which opens the overlay.
Here's my javascript:
$(document).ready(function() {
$(".fancybox").fancybox({
margin: [20,20,20,20],
padding: [20,20,0,20],
openEffect: 'fade',
openEasing: 'easeInQuad',
openSpeed: 400,
title: false,
//closeBtn: false,
//autoCenter: false,
scrolling : 'no', // turns off scrolling in box.
fitToView : false, // allows box to overflow out of viewport.
autoSize: false, // needs to be turned off for width/maxWidth to work.
height: 'auto', // if autoSize is set to 'false', this needs to be 'auto' so height matches content.
width: '100%',
maxWidth: 960,
helpers: {
overlay: {
// locked: false, // Prevents jump to top of window when opening a fancybox.
showEarly : false
}
},
tpl: {
closeBtn : '<a title="Close" class="fancybox-item fancybox-close icon-circle-cross" href="javascript:;"><span>Close</span></a>'
}
});
});
As you can see I'm using maxWidth to see the width of the default size. I couple of boxes could be almost half that. I've tried setting auto so see if it would inherit the width set on the content block in the CSS but this doesn't seem to work.
Any ideas that don't involve writing a whole need block of script for $(".fancybox-narrow")?
EDIT
I actually found an example on the Fancybox page which uses data-fancybox-width to set the width of an overlay: http://jsfiddle.net/wgPTR/
Though this doesn't seem to work with my code. The width sets but it isn't responsive anymore. Setting fitToView to false seems to get that working but then the fancybox crops when there's not enough vertical space and it's un-scrollable.
UPDATE
Just to update, here's a CodePen of the working (default) fancybox: http://codepen.io/moy/pen/YGgjqv
I've also created a forked version which uses data-fancybox-width to set a width - which works but unfortunately the fancybox is no longer responsive. The only way to get this to work is to take out fitToView: false which breaks my vertical scrolling.
Any ideas?
I seem to have found a solution (with a lot of help from the CSS Tricks forum) by using the following beforeLoad if statement:
beforeLoad: function() {
if ($(this.element).hasClass('fancybox--small')) {
this.maxWidth = 600;
}
}
Basically it checks for the class fancybox--small and if it's present it amends the maxWidth of the fancybox.
Can't see any problems with it (yet), checking in IE it seems to work down to IE8 as well. Hopefully this helps someone else but let me know if you find any issues with it ;)

bxSlider cuts off slide viewing mobile

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

jQuery window resize function not working

Sorry in advance if this is a minor question, but I'm new to javascript. I'm writing code for a webpage with full-width color backgrounds. Essentially, what I'm trying to do is detect the height of the window, and then make sure that the color block is the size of the window. The function works well on page load.
The problem is when I shrink the window, the div height doesn't change with the window size. I get all sorts of errors, like graphics poking out from behind the div.
I think what I'm missing is a way to detect the height of the content within each div and resize the height accordingly.
You can see how it works at http://pressshoppr.com
Here's the code:
$(function(){
var windowH = $(window).height();
if(windowH > wrapperH) {
$('.fullWidthSectionBG').css({'height':($(window).height())+'px'});
$('.fullWidthSectionBGFirst').css({'height':($(window).height())-120+'px'});
}
$(window).resize(function(){
var windowH = $(window).height();
var wrapperH = $('.fullWidthSectionBG').height();
var newH = wrapperH + differenceH;
var truecontentH = $('.fullWidthSection').height();
if(windowH > truecontentH) {
$('.fullWidthSectionBG').css('height', (newH)+'px');
$('.fullWidthSectionBGFirst').css('height', (newH)-120+'px');
}
});
});
I am not sure I totally understand the effect you are going for here, but I would imagine that if your initial bit of code achieves it, all you have to do is reuse exactly that. Treat each resize as if the page had just loaded, and get the results you want, eg:
$(function(){
// encapsulate the code that we know WORKS
function init() {
var windowH = $(window).height();
if(windowH > wrapperH) {
$('.fullWidthSectionBG').css({'height':($(window).height())+'px'});
$('.fullWidthSectionBGFirst').css({'height':($(window).height())-120+'px'});
}
}
// call on page ready
init()
// ...and call again whenever the page is resized
$(window).resize(init)
});

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