Get offsetTop & IE - javascript

I am trying to get the offsetTop in IE but this simply doesn't work like I want to it.
var miniMap = $('#miniMap'),
parnts = miniMap.parents(),
l = parnts.length,
i, setVpos,
setHPos = $('#showMap').position().left;
for (i = 0; i < l; i += 1) {
if (parnts[i].className === 'smallBox') {
if (isIE) {
setVpos = parnts[i].offsetTop; // returns the wrong value
}
else {
setVpos = parnts[i].offsetTop; // works as it should
}
}
}
As you can see I am using jQuery. I could of course use the jQuery offset/position().top && .each:
parnts.each(function() {
if ($(this).hasClass('smallBox')) {
setVpos = $(this).position().top;
} ....
.. BUT, I've heard ".each" is much slower than using a for loop. Also I am really curious and would love to know what you guys used before jQuery :-)
My problem is when doing it with a for loop I can't use the jQuery obj => position().left won't work.
I've Googled and found the following:
document.getElementById("elementID").offsetLeft // all other
document.all.elementID.offsetLeft // IE only
I figured perhaps this could work:
if (isIE) {
setVpos = document.all.parnts[i].offsetTop;
}
.. but it didn't. So now I'm asking you guys for help instead.
Any suggestion? Thanks on beforehand!

You clearly have a reference to the jQuery library, so why aren't you using it to get the offset? Using jQuery, you should have no need for any variables such as isIE. The biggest benefit of using a library is cross-browser compatibility. Here's how you could do it...
var off = $(parnts[i]).offset();
alert(off.top);
offset on jQuery API

I think you'll find that IE gives a very different answer when offset() is used as opposed to other browsers . Perhaps you should try to run you code before you psot an answer.

Related

jQuery doesn't work in Internet Explorer 8 ("this" returns DOM instead of jq)

I am facing a strange problem and can't find any solution.
jQuery (any version, from 1.7.* to 1.10.*) fails in Internet Explorer 8. All plugins (from bootstrap) and the jQuery library fall with an error:
Object doesn't support this property or method
Screenshot from debugger:
Digging in plugins code, like this:
$.fn.alert = function (option) {
return this.each(function () {
//...
})
}
shows the problem: this keyword points to HTMLDomObject, not on a jQuery object.
What can cause such a weird error?
Only in Internet Explorer 8!
Some other code or plugin may be loading another JavaScript library and that calling code may not be taking care of jQuery.noConflict(). This has happened to me several times. In the meantime, to make your code work, you can also do the following:
//If 'this' is pointing to a HTMLDomObject
var obj = $(this)
I've found a piece of code, that caused this problem. I still don't understand, how it could break all jQuery in such way and why it was breaking at all (again, it worked perfectly in all browsers but Internet Explorer 8), but changing the for in iterator to $.each() made errors to disappear.
for (var i in $postsPortions) {
var $p = $($postsPortions.get(i));
var offset = $p.offset();
if (offset && Math.abs(offset.top - scrollTop) < 100) {
var year = $p.data('year');
var season = $p.data('season');
window.location.hash = year + '/' + season;
$milestones.removeClass('active');
$milestones.filter('.year_' + year + '.season_' + season).addClass('active');
return;
}
if (i >= ($postsPortions.length - 1)) return;
}
When you use jQuery.each method, "this" (in callback) points to DOM element, not to jQuery wrapper. As follows, you have to wrap "this" in jQuery object:
$elements.each(function(){
var $this = $(this);
// do something with $this ...
});

ID Parsing then using as Selector

So I have this funny little problem, where I want to parse the IDs of images. Nothing too complicated... but weirdly enough, my code doesn't seem to work properly. It's weirdddd. Could any care to explain this? I feel blind for not being able to see the error myself.
Here's a snippet of the relevant code that fails to work:
//Toggling images using img-index variable.
img-index = 0;
img-src[0] = $("#ppsfb").attr("id");
img-src[1] = $("#gty").attr("id");
$("#cycle").click(function(){
//Since img-index is just a counter.
if (img-index < 2){
img-index = img-index + 1;
} else {img-index = 0;}
$(img-src[img-index]).fadeIn(1000);
});
img-src is not a valid identifier in JavaScript. That's likely why this is failing.
Check out this fiddle and note the Unexpected token - error
img-index is not a valid variable name in JavaScript, you probably want to use img_index or imgIndex. Also, calling attr('id') on something that comes from an ID selector is pointless, $("#ppsfb").attr("id") is 'ppsfb' or nothing. You're probably better off storing whole jQuery objects in img_src too, your $(img-src[img-index]) wouldn't do what you wanted it to do even after fixing the naming problem. Furthermore, you probably want to hide or fadeout the current image before showing the new one.
img_index = 0;
img_src[0] = $('#ppsfb');
img_src[1] = $('#gty');
$("#cycle").click(function(){
img_src[img_index].hide() // Or .fadeOut or ...
if(img_index < 2)
img_index = img_index + 1;
else
img_index = 0;
img_src[img_index].fadeIn(1000);
});
Presumably you have the positioning, stacking, etc. already sorted out.

jQuery that works in Firefox but not in IE

Ok guys/girls.
Below is some jQuery that runs in Firefox but no IE. I have no idea why it craps out in one and not the other.
Anyone??
function SwapTextAssetforPOS() {
$("*").each(function () {
if ($(this).children().length == 0) {
$(this).text($(this).text().replace('Assets', 'POS'));
$(this).text($(this).text().replace('Asset', 'POS'));
$(this).text($(this).text().replace('assets', 'POS'));
$(this).text($(this).text().replace('asset', 'POS'));
}
});
}
Sorry folks - the error that I get is:-
SCRIPT65535: Unexpected call to method or property access.
jquery-1.6.min.js, line 16 character 60352
EDIT:------------------------------------------------------------------------------------
Ok so an update - I removed the * selector and IE no longer blows up, my issue now is that I cant figure how to get it to do the replace on the element. I have the following code to ping up all the text elements in the object:
function SwapTextAssetforPOS() {
var containerElementByID = $("#assetDetailContents");
containerElementByID.children().children().each(function () {
var $this = $(this);
alert($this.text());
});
This chucks me up an alert for every bit of text, however some is contained within a table, some is within a span, and some is just there. I have no control over a majority of this stuff so my new question is how do I get the previous replace to work using this type of selector. -- I can believe how painful this is..
Cheers again
I see the problem in my IE browser. When you do the $("*").each... it takes every single element in the page (including title, script, etc). When you do .text(), looks like it fails for some elements in IE for which .text() doesn't make sense. Replace "*" for "div" and it should work for the divs for example.Maybe you could do something like if ($(this).text()) {$(this).text($(this).text().replace('Assets', 'POS'));} to make sure the text() is defined for that element.
Still, going through the whole DOM is overkill. Can you add a class to the elements that can have the text?, like class="replaceable" so you could just do a $(".replaceable").text(...
Ok folks - so firstly thanks for the help.
I have resolved the issue by cobbling a number of suggestions together and by doing a little bit of investigative work.
In a nutshell IE was crapping out when it ran up against an tag. I no not why but this is where it fell over every time.
function SwapTextAssetforPOS() {
var overlaycon = $("#jq-selectionHelper").find("*:not(img)"); //This line simply looks at the div surrounding the template and returns (to an array I believe) every element therein except for img tag
//as this breaks in IE when tying to do the replace text stuff below.
overlaycon.each(function () {
var $this = $(this);
if ($this.children().length == 0) {
$this.text($(this).text().replace('Assets', 'POS'));
$this.text($(this).text().replace('Asset', 'POS'));
$this.text($(this).text().replace('assets', 'POS'));
$this.text($(this).text().replace('asset', 'POS'));
}
});
}
This code runs and I believe is a lot more efficient than my original offering. Any further suggestions for performance re-factoring are welcome but thank the lord this is now working.
Thanks again for all the help.
Regards
This code has no problem as seen here . I tested in IE and FF both works fine
http://jsfiddle.net/wKWRC/
You should use F12 developer tool for IE and see what error you are getting that way others can know what exact problem is . You can debug script and see where you are getting error . IE is sensitive to javascript errors and its possible there is some error before you are calling this function .
http://msdn.microsoft.com/en-us/library/gg699336%28v=vs.85%29.aspx
Just a hunch but you might be running out of memory in IE.
First, using $('*') is never advisable, its better that you narrow it down with a selector like $('p').
Also, every time you call $(this) you create a new jQuery object, so if there are a lot of elements on your page you're making 9 objects every time.
The convention is to set $this = $(this) at the begining of the function so you only use one object.
function SwapTextAssetforPOS() {
$("*").each(function () {
var $this = $(this);
if ($this.children().length == 0) {
$this.text($this.text().replace('Assets', 'POS'));
$this.text($this.text().replace('Asset', 'POS'));
$this.text($this.text().replace('assets', 'POS'));
$this.text($this.text().replace('asset', 'POS'));
}
});
}
try it like this
for (var i = 0, replacements = ['Assets','assets','asset','Asset']; i < 4; i++)
$("*:contains('" + replacements[i] +"')").map(function() { this.innerHTML = this.innerHTML.replace(/asset(s){0,1}/igm, 'POS'); })

how can i pass a parameters to a function to get current Style

Good day,
I wonder how to get currentStyle in IE, passing parameters to an function argument like this:
function test(el,value){
return document.getElementById(el).currentStyle[value];
}
if i'd use a similar function to get Style from Firefox, Chrome and so on, it would result.
using a function like this:
function test(el,value){
return getComputedStyle(document.getElementById(obj))[value];
}
, where value is the element property like backgroundColor, i.e:
alert(test('ObjectId','backgroundColor'));
....
it would return backgroundColor in FF, Chrome.. but not in Internet Explorer
What r possibles solutions..?
Thnx..
please i'm not looking for a jQuery soluction...
Here what I use to retrieve a style property value
function getStyle(el,sProp,toInt){
var elem = el;
if (elem.currentStyle) {
return toInt
? parseInt(elem.currentStyle[sProp],10)
: elem.currentStyle[sProp] || 0;
} else if (window.getComputedStyle) {
var compStyle = window.getComputedStyle(elem, null)[sProp];
return toInt ? parseInt(compStyle,10) : compStyle || 0;
}
return String(elem.style[sProp]||0);
}
This is (sadly) very complex.
I have written a browser independent resolver but I can't share it with you.
Unless you are writing your own framework I have to ask, why do you want to be able to resolve everything?
Is there a specific property (or some properties) you want? Because that could be a lot easier.
If you just want the background color then .style.backgroundColor is probably sufficient.
Also, there is a bug in your example script:
alert(test('ObjectId'),'backgroundColor');
Should be:
alert(test('ObjectId','backgroundColor'));
Not the first time I made the same mistake ;) - took me half a day to find it

How to use feature detection to know if browser supports border-radius? (Including IE9)

I've seen plenty of examples for detecting support for border radius using something like:
var cssAttributeNames = ['BorderRadius', 'MozBorderRadius', 'WebkitBorderRadius', 'OBorderRadius', 'KhtmlBorderRadius'];
for (var i = 0; i < cssAttributeNames.length; i++) {
var attributeName = cssAttributeNames[i];
if (window.document.body.style[attributeName] !== undefined) {
this._useCss = true;
break;
}
}
But this doesn't seem to work for IE9, which does support border-radius. Am I missing something?
Got it - the detection array needs 'borderRadius' added - it's case-sensitive.
Modernizr is a Javascript library used to detect HTML5 features (including border-radius), so if you're looking for a ready made solution, check that out.

Categories

Resources