PDA

View Full Version : jQuery plugin not working in Firefox?!



pookeyblow
11-18-2009, 06:50 PM
Hi!

I'm using a jQuery plugin called DragScroll (http://plugins.jquery.com/files/jquery.dragscroll.js.txt) so I can drag and scroll just like in google maps.

This works fine in Safari and Opera, but it's not working in Firefox....

You can find the site I'm working on here: bit.ly/297LCa

If you check both Firefox and Safari you will see the problem: I can't drag in Firefox.......

There is also another very similar plugin called ScrollDrag (http://plugins.jquery.com/files/jquery.scrolldrag.js.txt), but I have the same problem with this plugin too! Not working in Firefox..

Does anyone know why this is happening? Maybe I've done something wrong in my html document?

Could really need some help here!

cheers,

pooeky

pookeyblow
11-19-2009, 09:47 AM
Think I found out what the problem is!

This is how my js code looked:

<script type="text/javascript">
$(window).load(function(){
$('body').dragscroll();
});

When I now tried

<script type="text/javascript">
$(window).load(function(){
$('#work').dragscroll();
});

</script>

Looks like you can't use body in firefox? So how can I get the whole page to scroll and not just the div where my image is?

jscheuer1
11-19-2009, 03:28 PM
I'd try:


<script type="text/javascript">
$(function(){
$(document.body).dragscroll();
});
</script>

But, it may not be that you cannot use the body element, rather that the body element is not considered suitable in Firefox.

jscheuer1
11-19-2009, 04:05 PM
That won't work, but this will:


<script type="text/javascript">
jQuery(function($){
$(document.documentElement).imagefit().dragscroll();
});
</script>

pookeyblow
11-19-2009, 04:31 PM
wow that was amazing!! :) :)

but now it's not working in safari! :eek:

almost there! maybe you know why it's not working in safari too? looks like the image disappears sometimes..!

jscheuer1
11-19-2009, 06:15 PM
I don't believe imagefit ever worked in Safari, and that Safari requires document.body. So you could do:


<script type="text/javascript">
jQuery(function($){
if(/(Google)|(Apple)/.test(navigator.vendor)){
$(document.body).dragscroll();
}else{
$(document.documentElement).imagefit().dragscroll();
}
});
</script>

Google Chrome would have the same problem as Safari. I'm not sure what the problem with imagefit is in those browsers. When I have some time, I will look into it.

pookeyblow
11-19-2009, 06:39 PM
Thanks!

I just tried out different things and got it to work by doing this:


<script type="text/javascript">
$(window).load(function(){
if(/(Google)|(Apple)/.test(navigator.vendor)){
$(document.body).imagefit().dragscroll();
}else{
$(document.documentElement).imagefit().dragscroll();
}
});
</script>

Strange eh?!

Is it ok to do it like this?

Link to the site: http://bit.ly/297LCa

jscheuer1
11-19-2009, 06:41 PM
For what you are doing, this should work out:


<script type="text/javascript">
jQuery(function($){
if(/(Google)|(Apple)/.test(navigator.vendor)){
$(document.body).dragscroll();
$('#work img').css('width', '100%');
}else{
$(document.documentElement).imagefit().dragscroll();
}
});
</script>

You may even want to:


<script type="text/javascript">
jQuery(function($){
if(/(Google)|(Apple)/.test(navigator.vendor)){
$(document.body).dragscroll();
$('#work img').css('width', '100%');
}else{
$(document.documentElement).dragscroll();
$('#work').imagefit();
}
});
</script>

pookeyblow
11-19-2009, 06:53 PM
Thanks! First one works!! but couldn't get imagefit to work in the second one when using Firefox or Opera..

Thanks again for all the help!! It's highly appreciated!

jscheuer1
11-20-2009, 01:47 AM
I see what you mean, at least when the page isn't cached in Opera and Firefox. But I think using:


$(document.documentElement).imagefit().dragscroll();

will cause problems with your two other images in some IE browsers. To prevent that, you may add this style to your style section:


#infobox img, #topcontrol img {
width: 48px!important;
}

pookeyblow
11-20-2009, 11:07 AM
thanks.. I'm trying to make the "info box" align with the bottom of the browser too. I thought I could use this:
bottom: 0px; to fix that?

jscheuer1
11-20-2009, 01:54 PM
You already did and it already does. If there is some question about that in your mind as there was in mine at first, consider the main image. I noticed that your test3.jpg image was taller than it appears to be due to a large amount of blank space in it as viewed in an image editor:

3019

pookeyblow
11-20-2009, 07:09 PM
test.3 is just a test like the name says. I'm going to add more (or just 1 long) images with work on the page later.

I was asking the other question because I can't place the box at the bottom like I want to. Looks like a 5px gap between the div and the browser window..

jscheuer1
11-20-2009, 09:20 PM
Add this style as shown:


#infobox img, #topcontrol img {
width: 48px!important;
vertical-align: bottom;
}

pookeyblow
11-21-2009, 02:24 PM
thanks a lot!

pookeyblow
11-22-2009, 08:15 PM
It seems to be a problem in Firefox:

When you enter the site for the first time, the image will load, but looks very squeezed.

Do you have any idea why this is happening?

jscheuer1
11-22-2009, 09:35 PM
Not precisely, though glancing at the imagefit code, it looks poorly thought out. However, for what you are doing, you don't need imagefit at all. I'd just get rid of it. Add this (highlighted) to your style section:


<style type="text/css">

#infobox {
position: fixed;
left: 50px;
bottom: 0px;
}
#infobox img, #topcontrol img {
width: 48px!important;
vertical-align: bottom;
}

#body {cursor: move;}

#work img {
width: 100%;
}
</style>

And make your init:


<script type="text/javascript">
jQuery(function($){
if(/(Google)|(Apple)/.test(navigator.vendor)){
$(document.body).dragscroll();
}else{
$(document.documentElement).dragscroll();
}
});
</script>

This would replace (what I think you are currently using):


<script type="text/javascript">
jQuery(function($){
if(/(Google)|(Apple)/.test(navigator.vendor)){
$(document.body).dragscroll();
$('#work img').css('width', '100%');
}else{
$(document.body.documentElement).imagefit().dragscroll();
}
});
</script>

pookeyblow
12-04-2009, 01:20 AM
I have a follow up question to the "width: 100%;" code:

Is it possible to avoid the images from being scaled larger than they are?

This would be nice cause if you have a really large screen the layout will look too big and weird. And if the images aren't big enough for the screen, they will look "blurry".

any advices here will be great help!

jscheuer1
12-04-2009, 06:16 AM
Good point. BTW, I just looked at:

http://dirtyhans.net/work/

and this code on it in particular:


<script type="text/javascript">
$(function () {
$('work_').hide();//hide all the images on the page
});

var i = 0;//initialize
var int=0;//Internet Explorer Fix
$(window).bind("load", function() {//The load event will only fire if the entire page or document is fully loaded
var int = setInterval("doThis(i)",500);//500 is the fade in speed in milliseconds
});

function doThis() {
var images = $('img').length;//count the number of images on the page
if (i >= images) {// Loop the images
clearInterval(int);//When it reaches the last image the loop ends
}
$('work:hidden').eq(0).fadeIn(500);//fades in the hidden images one by one
i++;//add 1 to the count
}
</script>

It apparently does nothing. Aside from this error:


Warning: Unknown pseudo-class or pseudo-element 'hidden'.
Source File: http://dirtyhans.net/work/
Line: 0

which in conjunction with the rest of that code causes an endless loop. The word int is reserved, you should use something else.

I would scrap that code though, or thoroughly revamp it.

To answer your question, you might do something like:


(function($){
$(window).bind('load', function(){
$('#work img').each(function(){
var i = new Image(), im = this;
i.onload = function(){
if(i.width < im.offsetWidth){
im.style.width = i.width + 'px';
}
};
i.src = im.src;
});
});
})(jQuery);

Untested. If your images are display none, either as set in style or by script (including by the jQuery .hide() and other methods that set display none as part of their work), this will not work in some browsers. You may however set the images visibility to hidden if you want to carry this out without the images being seen at first. just remember to return them to visibility visible when you are done.

jscheuer1
12-04-2009, 06:42 AM
OK, I tested it out and it works. So does this version, which also does the hiding and revealing I was talking about:


(function($){
document.write('<style type="text/css">#work img {visibility:hidden;position:absolute;top:-90000px;left:-90000px;}<\/style>');
$(window).bind('load', function(){
$('#work img').each(function(){
var i = new Image(), im = this;
i.onload = function(){
if(i.width < im.offsetWidth){
im.style.width = i.width + 'px';
}
$(im).css({position: 'static', visibility: 'visible'});
};
i.src = im.src;
});
});
})(jQuery);

pookeyblow
12-04-2009, 09:37 AM
I was just testing out this (http://dinolatoga.com/2009/04/26/how-to-create-a-visual-image-preloader-using-jquery/) plugin. I want something similar.

Thanks for the help, but I seem to have a problem.

1.
It looks like the images are being loaded similar to what I want but it goes really fast? I would like more ease on the fading/animation and also a loader (animated gif). It also doesn't look like the images are showing up "as I scroll", but that's not necessary.

2.
I'm not sure if your code solved my original question. Should I do something to my CSS? Not sure if I fully understood. Scales like before (css code).

I've added the code you gave me to the site so you can test it by yourself. I've probably done something wrong?

I'm on a Mac and using Firefox 3.5.5 and Safari 4.0.3.

cheers

jscheuer1
12-04-2009, 02:28 PM
I've not attempted to do anything like that fade in images with preloading placeholder script. It might be able to be used with what I wrote, it might not, I'll look into it later. In any event, this wasn't (for the reasons already stated in my post about it) working:


<script type="text/javascript">
$(function () {
$('work_').hide();//hide all the images on the page
});

var i = 0;//initialize
var int=0;//Internet Explorer Fix
$(window).bind("load", function() {//The load event will only fire if the entire page or document is fully loaded
var int = setInterval("doThis(i)",500);//500 is the fade in speed in milliseconds
});

function doThis() {
var images = $('img').length;//count the number of images on the page
if (i >= images) {// Loop the images
clearInterval(int);//When it reaches the last image the loop ends
}
$('work:hidden').eq(0).fadeIn(500);//fades in the hidden images one by one
i++;//add 1 to the count
}
</script>

Now, as to:


I'm not sure if your code solved my original question. Should I do something to my CSS? Not sure if I fully understood. Scales like before (css code)

I'm not even sure what you mean by "my original question". What my code does do though is solve:


Is it possible to avoid the images from being scaled larger than they are?

pookeyblow
12-04-2009, 03:28 PM
Ok I see.

Well, the problem right now is that I still have:


#work img {
width: 100%;
}
in my css. I think this code is making it still possible to scale the images larger than they are.

If I now remove this code, I'm not able to scale at all!

I want to be able to scale like in:


#work img {
width: 100%;
}
but make the images stop scaling when they reach their original size. Right now this is not working for me.

If you check my site (bit.ly/297LCa), you can see what I'm talking about!

jscheuer1
12-04-2009, 04:23 PM
I have no idea what you are talking about. My screen is only 1440px wide (available browser window slightly to significantly less, depending on the how big the browser's view port is). Your narrowest image in the work area is 1500px wide. So of course they will all take up the full width here. How wide is your screen?

Anyways, I tested your page with an image 250px wide, and it did not get stretched.

Additionally, I was able to correct the issues with the other script and combine it with mine. Replace:


<script type="text/javascript">
(function($){
document.write('<style type="text/css">#work img {visibility:hidden;position:absolute;top:-90000px;left:-90000px;}<\/style>');
$(window).bind('load', function(){
$('#work img').each(function(){
var i = new Image(), im = this;
i.onload = function(){
if(i.width < im.offsetWidth){
im.style.width = i.width + 'px';
}
$(im).css({position: 'static', visibility: 'visible'});
};
i.src = im.src;
});
});
})(jQuery);
</script>

with:


<script type="text/javascript">
(function($){ //as page is loading
var imgs = '#work img', //set selector for images
timer = 500 //500 is pause before initial and subsequent (if any) fade ins (milliseconds)
document.write('<style type="text/css">' + imgs + ' {visibility:hidden;position:absolute;top:-90000px;left:-90000px;}<\/style>');
$(window).bind('load', function(){ //This is the previous load event referred to below
$(imgs).each(function(){
var i = new Image(), im = this;
i.onload = function(){
if(i.width < im.offsetWidth){
im.style.width = i.width + 'px';
}
$(im).hide().css({position: 'static', visibility: 'visible'});
};
i.src = im.src;
});
});

$(function(){ //delayed until document parsed
function doThis(){
var imgHidden = $(imgs + ':hidden');
if(imgHidden){
imgHidden.eq(0).fadeIn(timer, doThis);
}
}
$(window).bind("load", function(){ //This load event will fire after the previous one
setTimeout(doThis, timer);
});
});
})(jQuery);
</script>

You must still have individual containers for each image, as before:


<div class="work_image" align="top"><img src="img/test_01.jpg" border="0"/></div>
<div class="work_image" align="top"><img src="img/test_02.jpg" border="0"/></div>
<div class="work_image" align="top"><img src="img/test_03.jpg" border="0"/></div>

So just keep that part.

pookeyblow
12-04-2009, 05:20 PM
thank you!

I found out what is happening. I just tested the images in 600px width.

1.
If you enter the site, and your browser window is larger than the images, they will not be stretched. But if you try to scale them down, nothing will happen.

2.
If you enter the site, and your browser window is smaller than the images, it works like I've always wanted it to work, except that you can scale them larger than their own size. Try to resize your browser window so that it's smaller than the images. Refresh and see what's happening!

jscheuer1
12-04-2009, 05:34 PM
Gotta run for now, but I think I understand what you mean without looking. What we need to do is take a part of the code I wrote, perhaps modified slightly, and make it a subroutine that can fire on resize.

I'll get back to you on that when I have the time.

jscheuer1
12-05-2009, 06:30 PM
OK, I've tested this thoroughly, but I'm not entirely happy with one compromise I seemed to have to make with it. I'm dubbing this version 1.1 beta (it should fulfill your requirements though):


<script type="text/javascript">

/* jQuery Fit Images w/Fade in 2009 John Davenport Scheuer
version 1.1 beta, 5/Dec/2009
as first seen in http://www.dynamicdrive.com/forums/
username: jscheuer1 - This Notice Must Remain for Legal Use
*/

(function($){ //as page is loading
var imgs = '#work img', //set selector for images
timer = 500, //500 to whatever - pause before initial and subsequent (if any) fade ins (milliseconds)

//////////////////// Stop Editing ////////////////////

htm = $('html'), win = $(window);
timer = Math.max(500, timer),
stylePrefix = '<style type="text/css">',
styleSuffix = ' {width:100%;visibility:hidden;position:absolute;top:-90000px;left:-90000px;}<\/style>';
document.write(stylePrefix + imgs + styleSuffix);
function resizeImages(im, load){
var i = new Image();
i.onload = function(){
im.style.width = this.width < im.offsetWidth? this.width + 'px' : im.offsetWidth + 'px';
load();
}
i.src = im.src;
}
win.bind('load', function(){ //This is the first load event referred to below
htm.css('overflowY', 'scroll');
$(imgs).each(function(i, im){
resizeImages(im, function(){$(im).hide().css({position: 'static', visibility: 'visible'});});
});
});

$(function(){ //delayed until document parsed
function doThis(){
var imgHidden = $(imgs + ':hidden');
if(imgHidden.length){
imgHidden.eq(0).fadeIn(timer, doThis);
}else{
win.bind('resize', function(){
$(imgs).css({visibility: 'hidden', width: '100%'}).each(function(i, im){
resizeImages(im, function(){im.style.visibility = 'visible';});
});
});
htm.css('overflowY', '');
}
}
win.bind('load', function(){ //This load event will fire after the first one
setTimeout(doThis, timer);
});
});
})(jQuery);
</script>

pookeyblow
12-05-2009, 07:16 PM
Hey thanks for continuing on with this project!

I've tested it in both Firefox and Safari on my mac.

Safari:
Seems to work like we want, but when resizing the page turns white and you can't see the resizing itself.

Firefox:
Seems to work good here too, but the vertical scrollbar shows up from time to time when you scroll. The resizing could have been smoother.


What I think could be better is being able to see the image getting resized. A smooth resizing just like the width:100% css code.

Other than that, awesome!!!

jscheuer1
12-05-2009, 08:18 PM
Well, you know, most of the resizing could be handled with max-width set to the images true width in conjunction with width: 100%.

Most browsers support this. Only IE 6 and less do not. So they can have the flickering screens onresize. The rest no longer need to.

As to the vertical scrollbar (are you sure you don't mean horizontal scrollbar?) showing up in any browser, in any case there is no longer anything about the script that can influence that, unless - and this is for IE 6 and less only, you set things oddly for the HTML element and it gets changed by this script. At least I think not. If you have a problem, take away this script and set no width for the images, I bet you will still have the same scrollbar issues. So here is the updated max-width version:


<script type="text/javascript">

/* jQuery Fit Images w/Fade in 2009 John Davenport Scheuer
version 1.2 beta, 5/Dec/2009
as first seen in http://www.dynamicdrive.com/forums/
username: jscheuer1 - This Notice Must Remain for Legal Use
*/

(function($){ //as page is loading
var imgs = '#work img', //set selector for images
timer = 500, //500 to whatever - pause before initial and subsequent (if any) fade ins (milliseconds)

//////////////////// Stop Editing ////////////////////

htm = $('html'), win = $(window), max = typeof htm[0].style.maxWidth === 'string', timer = Math.max(500, timer),
htmSave = htm.css('overflowY'), stylePrefix = '<style type="text/css">',
styleSuffix = ' {width:100%;visibility:hidden;position:absolute;top:-90000px;left:-90000px;}<\/style>';
document.write(stylePrefix + imgs + styleSuffix);
function resizeImages(im, load){
var i = new Image();
i.onload = function(){
if(max){
im.style.maxWidth = this.width + 'px';
}else{
im.style.width = this.width < im.offsetWidth? this.width + 'px' : im.offsetWidth + 'px';
}
load();
}
i.src = im.src;
}
win.bind('load', function(){ //This is the first load event referred to below
if(!max){
htm.css('overflowY', 'scroll');
}
$(imgs).each(function(i, im){
resizeImages(im, function(){$(im).hide().css({position: 'static', visibility: 'visible'});});
});
});

$(function(){ //delayed until document parsed
function doThis(){
var imgHidden = $(imgs + ':hidden');
if(imgHidden.length){
imgHidden.eq(0).fadeIn(timer, doThis);
return;
}else if(!max){
win.bind('resize', function(){
$(imgs).css({visibilty: 'hidden', width: '100%'}).each(function(i, im){
resizeImages(im, function(){im.style.visibility = 'visible';});
});
});
htm.css('overflowY', htmSave);
}
}
win.bind('load', function(){ //This load event will fire after the first one
setTimeout(doThis, timer);
});
});
})(jQuery);
</script>

In IE 6 and less, if you are already taking control of the HTML element's overflow properties you may want to remove the two highlighted sections.

pookeyblow
12-18-2009, 12:03 AM
Hi again!

This works very good, but I'm wondering if it's possible to improve the image quality in Firefox when images are scaled? In Safari and Chrome it looks great, but in FireFox it can be really "blurry" at times.

Another question: what do I have to do to add a spinning gif graphic to each image that goes away when the images fade in? Add it as a background image?

jscheuer1
12-18-2009, 05:18 AM
I'll have to think about that last question a bit. But as to the first question, there is nothing you can do. The latest version of Firefox is very good at scaling images, at least on the PC, I don't know about on a Mac. Still, no browser is likely to be perfect at this. Some certainly are better than others. I think all will continue to improve. There was a time when none of them were any good. The only thing I can suggest in this regard is for IE 7 and later. It has a style that turns on bicubic interpolation for scaled images:


img {
-ms-interpolation-mode: bicubic;
}

No other browsers have such a thing. They do what the do in this regard, and that's it.

Added Later -

OK, I thought about this loading image thing. To do that you need a loading image, probably an animated .gif image, call it loading.gif.
Use this updated version of the script:


/* jQuery Fit Images w/Fade in ©2009 John Davenport Scheuer
version 1.3 beta, 18/Dec/2009
as first seen in http://www.dynamicdrive.com/forums/
username: jscheuer1 - This Notice Must Remain for Legal Use
*/

(function($){ //as page is loading
var imgs = '#work img', //set selector for images
imwrap = '.work_image', //set selector for image wrappers
loading = 'loading.gif', //set loading image
timer = 500, //500 to whatever - pause before initial and subsequent (if any) fade ins (milliseconds)

//////////////////// Stop Editing ////////////////////

win = $(window), max = typeof $('html')[0].style.maxWidth === 'string',
timer = Math.max(500, timer), stylePrefix = '<style type="text/css">',
imStyle = ' {width:100%;visibility:hidden;position:absolute;top:-90000px;left:-90000px;}',
wrapStyle = ' {background: url(' + loading + ') no-repeat center;display:block;visibility:hidden;}',
styleSuffix = '<\/style>';
document.write([stylePrefix, imgs, imStyle, imwrap, wrapStyle, styleSuffix].join(''));
function resizeImages(im, load){
var i = new Image();
i.onload = function(){
if(max){
im.style.maxWidth = this.width + 'px';
}else{
im.style.width = this.width < im.offsetWidth? this.width + 'px' : im.offsetWidth + 'px';
}
$(im).parent().css({height: i.height + 'px', visibility: 'visible'});
load();
}
i.src = im.src;
}
win.bind('load', function(){ //This is the first load event referred to below
$(imgs).each(function(i, im){
resizeImages(im, function(){$(im).hide().css({position: 'static', visibility: 'visible'});});
});
});

$(function(){ //delayed until document parsed
function doThis(){
var imgHidden = $(imgs + ':hidden');
if(imgHidden.length){
imgHidden.eq(0).fadeIn(timer, doThis).parent().css('height', '');
return;
}else if(!max){
win.bind('resize', function(){
$(imgs).css({visibilty: 'hidden', width: '100%'}).each(function(i, im){
resizeImages(im, function(){im.style.visibility = 'visible';});
});
});
}
}
win.bind('load', function(){ //This load event will fire after the first one
setTimeout(doThis, timer);
});
});
})(jQuery);

Besides the highlighted additions/changes, I removed that messiness about overflow as I realized that the default overflow in those browsers without max-width was fine, and that a custom one would be as well.

pookeyblow
12-18-2009, 12:11 PM
Great!, but this creates space between the images when scaling the site. Any ways to avoid this? Has this something to do with the imStyle?

btw, how can I hide the loading.gif after imgages loaded?

jscheuer1
12-18-2009, 01:24 PM
I'm not seeing any spaces, or the loading image. You haven't updated the live page. To see the loading image the .work_image class has to be display:block, otherwise it has no native height property and probably cannot be made to display its background. The loading image should be covered by the image when the image appears, which happened here in tests, where also I saw no spaces, though I'm not certain what you mean by that. I'm not sure what or even if, but probably something(s) else about your style and/or markup is causing what you are observing. I would need to see it live to have the best chance of working that out.

I just saw the thing about the spaces, I added:


.parent().css('height', '')

In the wrong spot. I will go back and correct that in my previous post.