Is there a cross browser way of setting style.float in Javascript? - javascript

Usually, if you need to set a style attribute in JavaScript, you say something like:
element.style.attribute = "value";
There are slight variations but usually the attribute name is a similar, albeit camelcased, version of the HTML attribute name.
The problem for me is that the float attribute doesn't work. Float is a keyword in JavaScript and so style.float makes all the JavaScript for the page break. I looked in MSDN, and it said to use styleFloat like so:
element.style.styleFloat = "value";
That only works in IE. Firefox, Safari, Chrome, Opera - none of them seem to have an answer. Where am I going wrong? There has to be a simple answer to this.

Use cssFloat as in...
element.style.cssFloat = "value";
That works in everything except IE 8 and older, but you can always detect the browser and switch, or just set them both. Unfortuantely, there is no way to set just one style value to work in all browsers.
So to summarize, everyone you need to set the float, just say:
element.style.styleFloat = "value";
element.style.cssFloat = "value";
That should work everywhere.

better:
element.style.styleFloat = element.style.cssFloat = "value";

This is a function sniff approach:
if (typeof elmt.style.cssFloat != "undefined")
elmt.style.cssFloat = "none";
else
elmt.style.styleFloat = "none";
But usually we don't need to bother with this detection. I have tested user2719099's approach with Chrome as below:
elmt.style.cssFloat = elmt.style.styleFloat = "none";
console.log(elmt.style.cssFloat, elmt.style.styleFloat);
And the result is quite good in the console:
none none

Related

Left-hand assignment error for text-decoration

I don't know why this won't work on firefox, but it works on chrome. Here's my code:
var a = document.getElementById("link");
a.style.color = "#0000FF";
//a.style.text-decoration = "none";
The commented line is the error happens in firefox. I suspect it may have to do something with "-" and firefox is treating it like a subtract operator, that is what I thought. Is there any way that I can avoid firefox from treating the dash as a math operator?
The syntax you're looking for is textDecoration :)
http://jsfiddle.net/8PEZX/
a.style.textDecoration = "none";
Most (if not all, I'm just not sure, so I'm saying most :D) hyphenated properties get changed to camelCase in JavaScript.
Also, I just tested it with text-decoration and it didn't work in Chrome, so not sure how yours worked.

Dynamic CSS3 prefix user agent detection

Is there a better way then using jQuery.browser, or equivalents, for determining css 3 prefixes (-moz, -webkit, etc), as it is disencouraged? Since the css is dynamic (the user can do anything with it on runtime), css hacks and style tag hacks can't be considered.
I don't see the issue with using the navigator.userAgent to determine if you need to cater for Webkit / Gecko CSS3 prefixes. Or better yet, just stick with CSS2 until CSS3 becomes a W3C Recommendation.
The reason use of the navigator object is discouraged is because it was used over Object detection when (java)scripting for different browsers, your situation is one where it is fine to use user agent detection, because your'e specifically targeting certain quirks with different rendering engines.
Edit:
Picking up from where cy left off, you can use javascript object detection to detect whether a prefix is used, I made some quick code to do so:
window.onload = function ()
{
CSS3 = {
supported: false,
prefix: ""
};
if (typeof(document.body.style.borderRadius) != 'undefined') {
CSS3.supported = true;
CSS3.prefix = "";
} else if (typeof(document.body.style.MozBorderRadius) != 'undefined') {
CSS3.supported = true;
CSS3.prefix = "-moz-";
} else if (typeof(document.body.style.webkitBorderRadius) != 'undefined') {
CSS3.supported = true;
CSS3.prefix = "-webkit-";
}
if (CSS3.supported)
if (CSS3.prefix == "")
alert("CSS3 is supported in this browser with no prefix required.");
else
alert("CSS3 is supported in this browser with the prefix: '"+CSS3.prefix+"'.");
else
alert("CSS3 is NOT supported in this browser.");
};
Remember to watch out for strange quirks such as -moz-opacity which is only supported in older versions of Firefox but has now been deprecated in favour of opacity, while it still uses the -moz- prefix for other new CSS3 styles.
Array.prototype.slice.call(
document.defaultView.getComputedStyle(document.body, "")
)
.join("")
.match(/(?:-(moz|webkit|ms|khtml)-)/);
Will return an array with two elements. One with dashes and one without dashes, both lowercase, for your convenience.
Array.prototype.slice.call(
document.defaultView.getComputedStyle(document.body, "")
);
Without the browser check will return an array of nearly all the css properties the browser understands. Since it's computed style it won't display shorthand versions, but otherwise I think it gets all of them. It's a quick hop skip and a jump to auto detect whatever you need as only vendor prefixed stuff starts with a dash.
IE9, Chrome, Safari, FF. Opera won't let you slice CSSStyleDeclaration for you can still use the same getComputedStyle code and loop through the properties or test for a specific one. Opera also wanted to be the odd man out and not report the vendor prefix dasherized. Thanks Opera.
Object.keys(CSSStyleDeclaration.prototype)
Works in IE9 and FF and reports the TitleCased (JavaScript) version of the vendor property names. Doesn't work in WebKit as the prototype only reports the methods.
Here's an interesting and very dangerous function I just wrote along these lines:
(function(vp,np){
Object.keys(this).filter(function(p){return vp=vp||p.match(/^(Moz|ms)/)}).forEach(function(op){
this.__defineGetter__(np=op.replace(vp[0], ""), function() { return this[op] });
this.__defineSetter__(np, function(val) { this[op] = val.toString() });
}, this);
}).call(CSSStyleDeclaration.prototype);
I didn't test anything Konquerer.
It's adding in another library, but would Modernizr work for you? It adds CSS classes to the <html> tag that can tell you what the browser supports.
It does muddy up the code a bit, but can certainly be helpful in appropriate situations.
Speculatively: Yes. You can try adding a vendor prefix css rule (that's what they're called), and then test to see if that rule exists. Those vendor-specific rules won't be added to the DOM in browsers in which they're not supported in some cases.
For example, if you try adding a -moz rule in webkit, it won't add to the DOM, and thus jQuery won't be able to detect it.
so,
$('#blah').css('-moz-border-radius','1px');
$('#blah').css('-moz-border-radius') //null in Chrome
Conversely,
$('#blah').css('-webkit-border-radius','1px');
$('#blah').css('-webkit-border-radius'); //returns "" in Chrome
This method works in WebKit browsers; I'm testing to see if it works in others. Pending.
Edit: Sadly, this isn't working in Firefox or Opera, which just returns "" no matter compatibility. Thinking of ways to do this cross-browser...
Final Edit: Andrew Dunn's answer does this in a way that works (at least in FF and Webkit, which is better than my method).
I use ternary operator to have it only in 1 line. If it's not webkit nor gecko, I'll just use the standard property. If it has no support, who really cares then?
var prefix = ('webkitAnimation' in document.body.style) ? '-webkit-' : ('MozAnimation' in document.body.style? '-moz-' : '');
Basically I found Animation is one of the properties never changed. As soon as the browser starts supporting the Draft / Candidate Recommendation of a CSS3 property, it drops the prefix on JS side. So you will need to be careful and take in mind that, before copy-pasting.

Equivalent of "parentNode" in internet explorer

I wrote some code that modifies the images on a webpage. Works with firefox and safari. But tryingto get it to work with Internet explorer has got me stumped. What is the equivalent of "parentNode" in explorer? Or how does one trick it into working?
images = document.getElementsByTagName('img')
parms = {};
for (a=0;a < images.length;a++){
parent = images[a].parentNode; // <-- What to substitute for explorer?
parms[a] = {};
parms[a].bigsrc=parent.getAttribute("href");
parms[a].w_o = images[a].width;
parms[a].h_o = images[a].height;
parms[a].IsBig = false;
parms[a].loaded = false;
images[a].border=0;
parent.setAttribute("href","javascript:MakeBig('"+a+"')");
}
The problem is with the assignment of the parentNode to a var called "parent." This seems to be a reserved word in IE that breaks the code. Change the var name and it should work.
parentNode works fine in IE (except in certain cases, very likely irrelevant here). The error is almost certainly elsewhere in your code.
Are you expecting the parentNode to be an anchor? It looks like you're trying to just wrap the image in a link. If that's correct, what might work as an alternative is adding an onclick to the image itself, and setting a hand cursor. That could create the appearance of the image being a link without you having to care what the parentNode is.

Can you test for browser support for -moz-linear-gradient?

I would like to use feature detection to tell whether the user's version of Firefox supports the CSS style value -moz-linear-gradient. (This was added in Gecko 1.9.2. Version 3.6 of Firefox uses this.)
I can't use document.body.style.mozLinearGradient (or something similar) because -moz-linear-gradient is not a style property but a style value.
Does anyone know how to test for this without using version numbers?
I'm not sure how, but Modernizr (a nice little feature-detection script) appears to do it.
I guess you could create an (offscreen?) element, set that as it's style, and then poke around in the DOM to see if the browser successfully applied it?
Just assign it as style value and check afterwards if it is there.
Kickoff example:
function supportsMozLinearGradient() {
var element = document.getElementsByTagName('script')[0]; // Just grab an "invisible" element.
var oldstyle = element.style.background; // Backup old style.
try {
element.style.background = '-moz-linear-gradient(top, black, white)';
} catch(e) {
// Ignore failures.
}
var supports = element.style.background.indexOf('-moz-linear-gradient') > -1; // Did it accept?
element.style.background = oldstyle; // Restore old style.
return supports;
}
You should check for -moz-background-size (which was introduced in Firefox v3.6). The inference won't be picked up by other browsers since the property is prefixed.
if ('MozBackgroundSize' in document.body.style)
This is how MooTools detects Gecko (Firefox) engine (I'm "paraphrasing" slightly)
gecko = (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18)
So if it's FF it'll return 19 or 18, I believe 19 is 3.x and 18 is 2.x
And apparently FF3.6 stopped supporting document.getBoxObjectFor, so to detect 3.6 I basically do
isFF36 = gecko && !document.getBoxObjectFor
Works like a charm from a few tests I did.
If you're not using MooTools you can probably combine the two into one statement that would return something like false or 'ff' or 'f36' but I'm too lazy to work through that logic :)

childNodes not working in Firefox and Chrome but working in IE

I have a gridview in its 3rd cell, there is textbox control, I am calling javascript function on onchange.
Can some body tell me why this is not working in Firefox and Chrome but working in IE
grd.rows[rowindex].cells[3].childNodes[0].value
It return correct value in IE but not in Chrome and firefox (In FF and Chrome it return undefined)?
Please also suggest me solution to handle this problem.
Edit
alert(grd.rows[ri].cells[3].childNodes[0].value);//IE value=correct value, FF and chrome value=undfined
alert(grd.rows[ri].cells[3].childNodes[1].value);//IE value=undfined, FF and Chrome value= correct value
Thanks
I believe that this is because IE ignores text nodes that only contain newlines and tabs. Personally I prefer they be ignored but I would rather have consistency across the browsers.
<p><!-- This comment represents a text node.
--><em>text</em>
</p>
Try out this. I have same problem and this problem is resolved by just replace "childNodes" with "children"
alert(grd.rows[ri].cells[3].children[0].value);
try
grd.rows[rowindex].cells[3].childNodes[1].value
or the best, look at table in integrated Developer tool
#ChaosPandion:
Hey friend don't use this type of check for childNodes.
The counting of childNodes varies. Some browsers include empty textNodes, some do not. In this sort of operation as I believe you are describing, it is better to use the parent's getElementsByTagName() method. That way the number of chidren and index of each child you are looking for will be consistent.
OR
just check your browser's name.
if it is IE then as it neglects empty textnode, the childNode in it is less by one number than other browsers.
for eg.
var isIE = navigator.appName;
if (isIE == "Microsoft Internet Explorer") {
var removeProductID = document.getElementById(obj.childNodes[0].id).getAttribute("abc");
}
else {
var removeProductID = document.getElementById(obj.childNodes[1].id).getAttribute("abc");
}
Hope this helps. Enjoy coding.
If you are looking for the text, use grd.rows[rowindex].cells[3].childNodes[0].data for non-IE browsers.
Getting text value of an Element Node
var oCell = grd.rows[rowindex].cells[3];
alert(oCell.textContent || oCell.innerText)
Getting text value of a Text Node (less safe compared to previous)
var oText = grd.rows[rowindex].cells[3].childNodes[0];
alert(oCell.data || oCell.value)
As ChaosPandion says, IE ignores white-space text-nodes. The following should work cross-browser:
var cell = grd.rows[rowindex].cells[3];
for (var textbox=cell.firstChild; textbox.nodeType!==1; textbox=textbox.nextSibling);
alert(textbox.value);
However, you say you are calling the function on onchange.
Presumably that means the onchange event for the textbox in question.
In that case the event argument in your event handler should have a pointer to the textbox.
Look at the target or srcElement property. e.g.
function onChange(e) {
e = e || window.event;
var textbox = e.target || e.srcElement;
alert(textbox.value);
}
try getElementsByTagName() instead of ChildNodes. it will be working for FF , chrome and for IE as well.

Categories