jQuery that works in Firefox but not in IE - javascript

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

Related

IE refuse to change array elements into text

I have problem with my javascript code working on IE. I think I know exactly why it is working wrong, although I dont know how to change it.
Let me explain:
My code consist of small part of code inside $(document).ready() and a lot of inside $ajax.success(). The first part works normally, then I thought I have problem with ajax - that it simply dont work on IE. The error was:
Script65535 unexpected call to method or property access.
Jquery - 1.7.2.min.js line 5847, character 5
And line 5847 is APPEND function!!! It simply must work!
5844 append: function() {
5845 return this.domManip(arguments, true, function( elem ) {
5846 if ( this.nodeType === 1 ) {
5847 this.appendChild( elem );
5848 }
5849 });
5850 }
Then I found on google, that IE have problems when the multi-dimension array is changed to text. And only two appends in my ajax.success() function appends the content of arrays!
$('.display_info_here').append(tab_szablony[i][lang_number-2].toUpperCase()+'</br></br>');
I tried to change the array to text in another way, but it didnt worked
var arrr = tab_szablony[i][lang_number-2];
$('.display_info_here').append(arrr.toUpperCase()+'</br></br>');
It works on IE 9+, but not in 8 :(
Thanks for any help :)

IE Issue with Javascript Regex replacement

r = r.replace(/<TR><TD><\/TD><\/TR>/gi, rider_html);
...does not work in IE but works in all other browsers.
Any ideas or alternatives?
I've come to the conclusion that the variable r must not have the value in it you expect because the regex replacement should work fine if there is actually a match. You can see in this jsFiddle that the replace works fine if "r" actually has a match in it.
This is the code from fiddle and it shows the proper replacement in IE.
var r = "aa<TR><TD></TD></TR>bb";
var rider_html = " foo ";
r = r.replace(/<TR><TD><\/TD><\/TR>/gi, rider_html);
alert(r);
So, we can't really go further to diagnose without knowing what the value of "r" is and where it came from or knowing something more specific about the version of IE that you're running in (in which case you can just try the fiddle in that version yourself).
If r came from the HTML of the document, then string matching on it is a bad thing because IE does not keep the original HTML around. Instead it reconstitutes it when needed from the parsed page and it puts some things in different order (like attributes), different or no quotes around attributes, different capitalization, different spacing, etc...
You could do something like this:
var rows = document.getElementsByTagName('tr');
for (var i = 0; i < rows.length; i++) {
var children = rows[i].children;
if (children.length === 1 && children[0].nodeName.toLowerCase() === 'td') {
children[0].innerHTML = someHTMLdata
}
}
Note that this sets the value of the table cell, rather than replacing the whole row. If you want to do something other than this, you'll have to use DOM methods rather than innerHTML and specify exactly what you actually want.

JavaScript & string length: why is this simple function slow as hell?

i'm implementing a charcounter in the UI, so a user can see how many characters are left for input.
To count, i use this simple function:
function typerCount(source, layerID)
{
outPanel = GetElementByID(layerID);
outPanel.innerHTML = source.value.length.toString();
}
source contains the field which values we want to meassure
layerID contains the element ID of the object we want to put the result in (a span or div)
outPanel is just a temporary var
If i activate this function, while typing the machine really slows down and i can see that FF is using one core at 100%. you can't write fluently because it hangs after each block of few letters.
The problem, it seems, may be the value.length() function call in the second line?
Regards
I can't tell you why it's that slow, there's just not enough code in your example to determine that. If you want to count characters in a textarea and limit input to n characters, check this jsfiddle. It's fast enough to type without obstruction.
It could be having problems with outPanel. Every time you call that function, it will look up that DOM node. If you are targeting the same DOM node, that's very expensive for the browser if it's doing that every single time you type a character.
Also, this is too verbose:
source.value.length.toString();
This is sufficient:
source.value.length;
JavaScript is dynamic. It doesn't need the conversion to a string.
I doubt your problem is with the use of innerHTML or getElementById().
I would try to isolate the problem by removing parts of the function and seeing how the cpu is used. For instance, try it all these ways:
var len;
function typerCount(source, layerID)
{
len = source.value.length;
}
function typerCount(source, layerID)
{
len = source.value.length.toString();
}
function typerCount(source, layerID)
{
outPanel = GetElementByID(layerID);
outPanel.innerHTML = "test";
}
As artyom.stv mentioned in the comments, cache the result of your GetElementByID call. Also, as a side note, what is GetElementByID doing? Is it doing anything else other than calling document.getElementById?
How would you cache this you say?
var outPanelsById = {};
function getOutPanelById(id) {
var panel = outPanelsById[id];
if (!panel) {
panel = document.getElementById(id);
outPanelsById[id] = panel;
}
return panel;
};
function typerCount(source, layerId) {
var panel = getOutPanelById(layerId);
panel.innerHTML = source.value.length.toString();
};
I'm thinking there has to be something else going on though, as even getElementById calls are extremely fast in FF.
Also, what is "source"? Is it a DOMElement? Or is it something else?

Javascript/jQuery function yields undefined in <IE8

A short while back I asked a question here about how I could calculate when a heading was longer than one line within a given container, and subsequently wrap each of these lines in a <span>:
Use Javascript/jQuery to determine where a heading breaks to the next line?
I chose an answer which worked great for me, at least until I checked in IE7 and IE6, in which all the headings handled by this script rendered as
"undefinedundefinedundefinedundefinedundefinedundefined[...]"
on the page. As I'm not really a JavaScript person (that's why I asked such a question in the first place), it's really tough for me to figure out where the problem is. I assumed an undefined variable or something, but I just can't seem to grasp it.
Can anyone help?
I'll repeat the code here, but please refer to the link above for context:
$(function(){
$h = $('.fixed').find('h3');
$h.each(function(i,e){
var txt = $(e).text();
$th = $('<h3 />').prependTo($(e).parent());
var lh = $(e).text('X').height();
$(e).text('');
while (txt.length > 0) {
$th.text($th.text() + txt[0]);
txt = txt.slice(1);
if (($th.height() > lh) || (txt.length <= 0)) {
var shc = $th.text().split(' ');
var ph = shc.slice(0,-1).join(' ')+' ';
if (txt.length <= 0) { ph += shc.pop(); }
$('<span />').text(ph).appendTo($(e));
$th.text(shc.pop());
}
}
$th.remove();
})
});
You need to change
$th.text($th.text() + txt[0]);
to be
$th.text($th.text() + txt.charAt(0));
IE<8 doesn't accept string positions through array indexes ;)
The styling doesn't work, but that'll be a CSS issue which I couldn't fix before leaving. But everything is wrapped in spans :)
Nothing jumps out at me. But, since you mentioned in your comment to your question that you see "undefined" in Firebug, I would start there. Even though those browsers are failing gracefully, the fact that you see undefined there is your first hint to finding the problem for the harder-to-diagnose IE6/7. I would use Firebug and either breakpoint in the function, or use some console.log() calls to document what the values that you are working with are each step of the way. Once you start seeing undefined... you have likely found your problem.

How to find jQuery DropDownCheckList selected items - jQuery Syntax Problem

I'm working on an ASP.Net webpage which will use the jQuery Dropdown Checklist (http://code.google.com/p/dropdown-check-list/). I'm fairly inexperienced with JavaScript and completely new to jQuery.
What I want to do is collect the values of the selected items every time a checkbox is checked/unchecked.
Here's what I have so far:
var values = "";
$("#s1").change(function () {
$("#s1").dropdownchecklist(function(selector) {
for (i = 0; i < selector.options.length; i++) {
if (selector.options[i].selected && (selector.options[i].value != "")) {
if (values != "") values += ",";
values += selector.options[i].value;
}
}
});
});
I think the problem is in the 3rd line, but I'm not sure exactly what is wrong.
If anyone could point me in the right direction, I'd appreciate it. Thanks in advance.
Response to zod...
Thanks that was pretty much exactly what I needed. However, I still have some kind of syntactic error. Here's my code:
var values = "";
$("#s1").change(function () {
$("#s1 option:selected").each(function () {
if (values != "") values += ",";
values += $(this).value();
});
alert(values);
});
When I run it, the jQuery Dropdown Checklist looks like a regular list, so I must still have something wrong.
This is somewhat off-topic, but are there any tools that make working with JavaScript and jQuery any easier? I've been spoiled working with Visual Studio and using its debugger and intellisense. Is there anything like that for JavaScript and jQuery?
Response to Ender...
Wow. I like your solution. Yeah, I tend to over-complicate things.
I'm not sure what I did wrong when I tried zod's solution, it probably also works, but I think I'll go with the simpler one.
Thanks for you help.
You don't need to get anywhere near as fancy as you are. Inside your .change() event, simply access the .val() of the select to get the values of the checked items. Like this:
$(function() {
$("#s1").dropdownchecklist();
$('#s1').change(function() {
alert($(this).val());
});
});
See a live demo here: http://jsfiddle.net/Ender/ZsMc4/
Did you try .change()
check this
http://api.jquery.com/change/
http://www.texotela.co.uk/code/jquery/select/

Categories

Resources