Javascript and Opera. How come this works on all other browsers but opera?

I’m using a nice little script which replaces the usual file upload input with whatever image you want and then with JS makes sure that an invisible ‘browse’ button is underneath the mouse pointer whenever the mouse is moved over the image you want to use.

Nice :slight_smile:

It works on every browser ie7 ie8 ie9 FF safari chrome but not on opera. On Opera the regular file input appears.

I’ve had a good hoke round the 'net and I know there’s loads of scripts which do similar things. But either they are too complicated for me to figure out how to use them eg uploadify (bit of a newbie) or they do similar things but just not as well - like making the custom image the same size as the file input would be (there’s issues with that too).

here’s the script I’m using - there’s not much to it

How come it doesn’t work in Opera grrrr… Is there anyway to fix it? This is perfect for what I want apart from not working in Opera :frowning:

sorry, here’s some code :frowning:

html:

<label class="cabinet"> 
    <input type="file" class="file" />
</label>

then call:

SI.Files.stylizeAll();

css:

.SI-FILES-STYLIZED label.cabinet
{
    width: 79px;
    height: 22px;
    background: url(btn-choose-file.gif) 0 0 no-repeat;

    display: block;
    overflow: hidden;
    cursor: pointer;
}

.SI-FILES-STYLIZED label.cabinet input.file
{
    position: relative;
    height: 100%;
    width: auto;
    opacity: 0;
    -moz-opacity: 0;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
}

JS:

if (!window.SI) { var SI = {}; };
SI.Files =
{
	htmlClass : 'SI-FILES-STYLIZED',
	fileClass : 'file',
	wrapClass : 'cabinet',
	
	fini : false,
	able : false,
	init : function()
	{
		this.fini = true;
		
		var ie = 0 //@cc_on + @_jscript_version
		if (window.opera || (ie && ie < 5.5) || !document.getElementsByTagName) { return; } // no support for opacity or the DOM
		this.able = true;
		
		var html = document.getElementsByTagName('html')[0];
		html.className += (html.className != '' ? ' ' : '') + this.htmlClass;
	},
	
	stylize : function(elem)
	{
		if (!this.fini) { this.init(); };
		if (!this.able) { return; };
		
		elem.parentNode.file = elem;
		elem.parentNode.onmousemove = function(e)
		{
			if (typeof e == 'undefined') e = window.event;
			if (typeof e.pageY == 'undefined' &&  typeof e.clientX == 'number' && document.documentElement)
			{
				e.pageX = e.clientX + document.documentElement.scrollLeft;
				e.pageY = e.clientY + document.documentElement.scrollTop;
			};

			var ox = oy = 0;
			var elem = this;
			if (elem.offsetParent)
			{
				ox = elem.offsetLeft;
				oy = elem.offsetTop;
				while (elem = elem.offsetParent)
				{
					ox += elem.offsetLeft;
					oy += elem.offsetTop;
				};
			};

			var x = e.pageX - ox;
			var y = e.pageY - oy;
			var w = this.file.offsetWidth;
			var h = this.file.offsetHeight;

			this.file.style.top		= y - (h / 2)  + 'px';
			this.file.style.left	= x - (w - 30) + 'px';
		};
	},
	
	stylizeById : function(id)
	{
		this.stylize(document.getElementById(id));
	},
	
	stylizeAll : function()
	{
		if (!this.fini) { this.init(); };
		if (!this.able) { return; };
		
		var inputs = document.getElementsByTagName('input');
		for (var i = 0; i < inputs.length; i++)
		{
			var input = inputs[i];
			if (input.type == 'file' && input.className.indexOf(this.fileClass) != -1 && input.parentNode.className.indexOf(this.wrapClass) != -1)
			{
				this.stylize(input);
			};
		};
	}
};

The various browsers put limits on how they allow you to change the appearance of form fields.The only form fields able to be styled across all browsers are input text fields and textareas.

Also Opera has an option in the settings for whether or not form styles should be applied at all.

yes i d not know what is wrong with opera, it should be updated or fixed
many of my opera visitor can not load many important js like jQuery and others
google code solves some of my problems

There’s nothing wrong with Opera. It is the most standards compliant of all the browsers. Most of the other browsers allow you to do things that shouldn’t be permitted as they interfere with your visitor’s use of their own browser. Opera ensures that the person who owns the browser has the final say.

jQuery works perfectly well with Opera. If your particular code isn’t working with Opera then the problem is in your code and not jQuery.

Google should be the last place you look for JavaScript code as none of their staff have the slightest clue what JavaScript is. What the Google sites use as JavaScript is garbage and only by telling your browser to disable JavaScript for any site that contains google in the domain name do you have the slightest chance of any of their sites actually working.

Hey guys, thanks for the replies. Not much in the way of suggestions there but still some nice (but brief) reading material and the opportunity to interact with other people is always welcome.

Are we saying that basically there’s nothing I can do to make an image be the thing that you click to get a dialog to open in all browsers? Is there any other alternative? I was looking at having a modal window open when you click the image which then has a file input in it. But thats more clicks and I think I’d need a form within aform to do that? Not too sure, bit of a newb.

Any suggestions?

The file input is actually the one that the page author has the least control over. It is also the one that has the most differences between browsers.

Of course your visitors will be used to the way forms look in their browser and so any changes you try to make are just likely to confuse them.

Opera has an option to turn all styling of form fields off so that the browser owner can be certain that all forms will look the way they expect them to.