I'm trying to create code that requires the least number of bytes and that works for all browsers including IE 7.
In this example, the program calls dosomething('x1') and dosomething('x2').
If I have code like this:
var items,item,index,count;
items=Array('x1','x2');
count=items.length;
for (index=0;index<count;index++){
item=items[index];
dosomething(item);
}
Could I reduce it to this and have it still function exactly the same in all browsers:
var a=Array('x1','x2'),c=a.length,i;
for (i=0;i<c;i++){
f(a[i]);
}
I understand I changed the variable names and calling function name but my goal is to use the least number of bytes possible in the code to make the code execute.
I'm just not sure if declaring a variable equal to a property of a value from a previous variable in the same list of declarations would actually return correct results.
In other words, does var a=Array('x1','x2'),c=a.length... work, or do I have to specifically do var a=Array('x1','x2');var c=a.length; to make it work in all browsers including IE 7?
This is what the Google Closure Compiler service returned:
var a,b,c,d;a=["x1","x2"];d=a.length;for(c=0;c<d;c++)b=a[c],dosomething(b);
You can find many different Javascript compressors online to automate the process you are hand coding now. Yet, it's always good to understand how they work as it helps to write code that is better compressed.
As for IE, you can test your code by changing the emulations settings in the IE debugger panel. Just press F12, click the Emulation tab, and adjust the document mode to 7 (IE7).
Hope this is enough to get you started in the right direction.
You can use Array.map from IE 9
var items = Array('x1','x2');
items.map(dosomething(item));
Related
we are facing a pretty strange problem in our web aplication on IE11 (other IE versions work fine).
The application is based on SmartGWT ( http://www.smartclient.com/product/smartgwt.jsp ) - GWT wrapper on SmartClient javascript framework.
IE11 goes into never ending cycles.
It happens very randomly and we have no steps to reproduce it. The complexity of our application makes it impossible to post a sample of the code.
Most often it happens when users work with the application, then they minimize the browser window and after some time they restore it and try to continue working.
The never ending cycles are caused by strange comparison results, when expression 'true === true' results in false.
The comparison code is:
$wnd.isc.isA.Canvas(obj) === true
The code is executed in scope of iframe containing javascript compiled by GWT.
$wnd is the main(top) window of the web application where the SmartClient javascripts are loaded.
The isc.isACanvas(..) is a method returning true or false, depending on whether the object passed as parameter is of Canvas type - Canvas is a special class from SmartClient framework not the HTML Canvas element.
isc.isA.Canvas = function (object) {
return (object != null && object._isA_Canvas);
}
_isA_Canvas is set on object to true (boolean true not 'true' as a string) when the object is being created.
I have added some testing code to the part where the problematic comparison is used - here's a simplified version:
var trueCheckCount = 0;
function isCreated(id){
var obj = $wnd.window[id]; // objects are stored in window by id
var comparisonResult = $wnd.isc.isA.Canvas(obj) === true;
if (!comparisonResult ) {
if ($wnd.isc.isA.Canvas(obj) == true) {
alert("TRUE != TRUE (was OK: " + trueCheckCount + "x before)");
} else {
trueCheckCount++;
}
}
return comparisonResult;
}
In different test runs, the alert was shown after different number of passes. E.g. on the first run it passed 358 698 times, on the second run it passed 330 125 times …
Does anybody have any idea what could be the problem?
How can 'true !== true' ever happen?
Environment:
IE11 (Windows7/8)
SmartGWT: v9.0p_2014-03-02/LGPL Development Only (built 2014-03-02)
GWT: 2.4
Some additional debugging information can be seen on screenshot:
https://drive.google.com/file/d/0B8h18b-AMFzXa3NZZ2dOX2txb1k/edit?usp=sharing
The problem was caused by a bug in IE11.
MS released the fix. It's included in December Internet Explorer Cumulative Update KB3008923.
Installing this update solved our problem.
The technical details we got were:
The bug in question is related to reclaiming of JIT functions and cross-site thunks.
A function with a cross-site thunk is getting reclaimed.
We then change the entryPoint to the InterpreterThunk, losing the cross-site thunk in the process.
Marshalling isn't done when calling this function.
In the repro in question, we end up with a Boolean True object from a different scriptContext, which doesn't match the one in the current scriptContext when comparing with ===.
The problem is 99% in SmartGWT. I recommend you to report this issue to the SmartGWT team and use the latest GWT compiler of course. We dealt with SmartGWT before and from my experience I should say it was a pretty buggy library back then.
You have two issues in your debug code that could be giving you a false impression of the issue:
if ($wnd.isc.isA.Canvas(obj) == true) {
alert("TRUE != TRUE (was OK: " + trueCheckCount + "x before)");
} else {
Firstly, you're doing a double-equal comparison here, where earlier you'd done a === comparison. These are different, and will give different results if the variable being tested is not a boolean.
So for example, if $wnd.isc.isA.Canvas(obj) is outputting an integer 1 or something like that rather than true, then you would get exactly the problem you're describing.
Rather than doing another comparison why not get an accurate picture of the contents of the variable by using JSON.stringify
console.log(JSON.stringify($wnd.isc.isA.Canvas(obj)));
This will show you exactly what the value is, which should then show you fairly clearly why the comparisons aren't doing what you expect.
Secondly, using an alert() box to show errors is not a good idea, especially in a complex application. You should always use console.log() for debugging rather than alert(), because alert() can cause some JS code to alter its behaviour, which can make debugging really difficult.
This is because alert() blocks JS execution while it's displaying, which means that any event handlers or other asyncronous code that get triggered during that time can end up running out of the expected sequence.
I don't think this is necessarily the issue for you here, given the code sample provided, but if you have any Ajax calls, setInterval()s or other similar async code anywhere then you really do need to avoid using alert() for debugging purposes.
Hope that helps.
following code works properly
draw([['Rice',20,28,38],['Paddy',31,38,55],]);
but when i try using external variable like
var val1=20;
var val2=30;
var val3=40;
draw([['Rice',val1,val2,val3],['Paddy',31,38,55],]);
It wont work.
Just showing that your example code works fine using the Firebug console. Can you post more of your code? Your stripped-down example is probably missing something else that's causing a problem.
What is your draw() function doing? Could something in that function be breaking?
EDIT: Another problem could be the trailing comma after your second array. That will throw an error in Internet Explorer.
alert([['Rice',val1,val2,val3],['Paddy',31,38,55],]);
should be:
alert([['Rice',val1,val2,val3],['Paddy',31,38,55]]);
That may solve your issue (though you also have that in your 'working' example, but I thought it worth mentioning).
Your code snippets are not equivalent -- the second one has different values (['Rice',20,30,40] vs ['Rice',20,28,38]). Other than that, they are equivalent and should have the same effects.
I would like to know if there is anything wrong with the below statement.
document.getElementById(monthId).options[document.getElementById(monthId).selectedIndex].value
Am asking this because, sometimes it seems to work fine and the rest of the time, it throws up an error - Object doesn't support this property or method.
BTW, monthId is the clientID of the dropdown present in a gridview in an asp.net page.
Thanks!
If no value is selected in the dropdown list, selectedIndex would be -1.
It's hard to evaluate without some more code as context. But without sanity checks around this line of code I would expect it to fail with an index out of bounds type exception when there is no selected index.
I tend to error check when using getElementById. I would expect that that is where your problem is.
Try this, and then test it in a debugger, but I will put an alert in.
var elem = document.getElementById(monthId);
if (elem.options) {
options[document.getElementById(monthId).selectedIndex].value
} else {
alert("elem doesn't have an options property");
}
You may want to not assume that the value property exists either, and do the same basic thing as I did here.
Once you get it working smoothly, where you know what is going to happen, you can start to remove the unneeded variables and go back to your original line, but for debugging, it is simpler to have one operation on each line and use separate variables, so that the debugger can show you what is happening.
You may want to understand the difference between undefined and null, and there are various pages on this topic but this one isn't too bad.
http://weblogs.asp.net/bleroy/archive/2005/02/15/Three-common-mistakes-in-JavaScript-2F00-EcmaScript.aspx
You can debug your problem by adding a breakpoint to your code in IE development tools, Firebug, Opera dragonfly or Chrome development tools and check your values.
Or you could add alert statements to check your values. Personally i think the code goes awry when selectedIndex is -1 (selectedIndex = -1 would occur when nothing is selected).
Check for yourself:
alert(document.getElementById(monthId)); // Returns null if nothing is found
alert(document.getElementById(monthId).selectedIndex); // If the selectedIndex is below 0 it could cause your error
document.getElementById(monthId).options[document.getElementById(monthId).selectedIndex].value
HI,
I am trying to dynamically add a form to a tab in Ext-js. (the tab has already been rendered). fyi, i am using I am using Ext 2.2.
the error occurs when during the tab.add function:
ie:
function tabactivate(tab) {
var newItem= new Ext.FormPanel(.....);
**tab.add(newItem)**; //ERRORS HERE
tab.doLayout();
}
I get this error on line 247 of ext-all-debug.js
which is
range = el.ownerDocument.createRange();
the error is (Object doesn't support this property or method.)
This works fine in Firefox but breaks in IE8.
Does anyone know a workaround for this ?
Thanks
This sounds very similar to an issue I had with ExtJS 2.2 and IE.
It seems like a lot of places in the Ext code that you see code like this:
var td = document.createElement("td");
this.tr.insertBefore(td, this.tr.childNodes[index]);
When in fact that doesn't work on IE because "this.tr.childNodes([0])" does not yet exist.
My workaround was to override the prototype (in my case insertButton() in Ext.Toolbar) to check for the existence of this.tr.childNodes([0]), using a different function or creating it if it didn't exist.
I hope that I'm correct that this is the problem you are running into.
So i found an old string that had the solution for me.
http://www.extjs.com/forum/showthread.php?t=7912&highlight=createRange
Essentially, when i was instantiating empty tabs, i had my html property set to this:
html: ' ',
once i either took the property out completely or i changed to
html: '<span></span>'
it stopped breaking.
Thanks
IE (even 8) doesn't support the document.createRange() method.
You can try var supportsDOMRanges = document.implementation.hasFeature("Range", "2.0"); to see whether a browser supports DOM ranges per the standard.
if you open the page:
http://www.rhino.com/shop/product/the-monkees-the-birds-the-bees-the-monkees-boxed-set
you will see at the bottom of the page, a next and previous buttons, these are navigation buttons, they work fine in firefox but in ie the style is removed from the page when they are clicked!. please advise on what might be the cause of the problem. i have already spent hours debugging :(
When I debug it on IE8, I see a runtime error here:
cd=new Date();
Most likely this does not accord with this piece of HTML:
<li id="cd" class="">CD</li>
IE 'helpfully' launches elements with an id as global variables. So cd is actually a <li> element, and IE doesn't like it if you assign new Date() to it. It would be perfectly fine if IE would treat cd as a normal local variable, but it does not, hence the runtime error.
This piece of code is inside a anonymous function which is really nasty (shown below). But the solution is simple: just write proper functions, and declare your variables. If the anonymous function would have used one line in the top declaring variables like this:
var cd, dc, ...other variable names... ;
it would have worked just fine, because then the cd variable inside the function would have referred to the local variable, not the global cd element which IE thinks referes to the li element with id="cd".
Now it is entirely possible that this is just one of many problems with this page. But I am assuming the first error encountered by IE stopped execution of the remainder of your script, which why some of it diddn't work.
function anonymous(t, z, y) {
dc=new Date('1/1/2000');f=15;ne=8;
if(dc.getDay()!=6||dc.getMonth()!=0){
return'Data Not Available'
}else{;
z=parseInt(z);
if(y=='2009'){f=8;ne=1};
gmar=new Date('3/1/'+y);
dsts=f-gmar.getDay();
gnov=new Date('11/1/'+y);
dste=ne-gnov.getDay();
spr=new Date('3/'+dsts+'/'+y);
fl=new Date('11/'+dste+'/'+y);
cd=new Date();
if(cd>spr&&cd<fl){
z=z+1
}else{
z=z
};
utc=cd.getTime()+(cd.getTimezoneOffset()*60000);
tz=new Date(utc + (3600000*z));
thisy=tz.getFullYear();
var days=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
if(thisy!=y){
return'Data Not Available'
}else{;
thish=tz.getHours();
thismin=tz.getMinutes();
thisd=tz.getDay();
var dow=days[thisd];var ap='AM';var dt='Weekday';
var mint='00';
if(thismin>30){mint='30'}
if(thish>=12){ap='PM';thish=thish-12};
if (thish==0){thish=12};
if(thisd==6||thisd==0){dt='Weekend'};
var timestring=thish+':'+mint+ap;
var daystring=dow;
var endstring=dt;
if(t=='h'){
return timestring}
if(t=='d'){
return daystring};if(t=='w'){return endstring}}};
}
Now debugging where this is comming from is a bit of a prob. My callstack reads:
anonymous JScript
s_doPlugins JScript
anonymous function JScript
global code JScript
The top one is where the actual error occurs.
The root where this is all happening is here:
/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
var s_code=s.t();if(s_code)document.write(s_code)
Somehow, from here, s_doPlugins is called which contains the actual call to the anonymous function that is causing the trouble. It looks like s_doPlugins is located in s_code.js. If I step through that, I find that the trouble is in this line:
s.prop9=s.getTimeParting('h','-5','2008'); // Set hour
which is line 38 of s_code.js. With a little bit more poking around, I find it is actuall this plugin:
/*
* Plugin: getTimeParting 1.3 - Set timeparting values based on time zone
*/
s.getTimeParting=new Function("t","z","y",""
+"dc=new Date('1/1/2000');f=15;ne=8;if(dc.getDay()!=6||"
...more crap here...
This is at line 95 in s_code.js
As a quick fix i would probably comment out all calls to s.getTimeParting() in s_doPlugins() in s_code.js and see if that fixes your problem. Then, the long and hard but noble taks remains of churning something sensible out of this mess :))
I found this infuriating and discovered that the problem was my site using a div with the ID "utc", which clashes with the s_code JS. 'UTC' is time-related so I can only assume that there's sloppy JS relying on it being something else if present at all!
With 2021 soon upon us, I wanted to resurface an issue with older versions of the getTimeParting plug-in that made quite the stir at the beginning of this year. If you took the easy route and edited the plug-in code instead of upgrading to the latest version, you'll want to make sure that you make those same edits again before January 1.
More information on this topic can be found in this forum thread: