[jQuery] Re: How to define/access public functions for a plugin?
You could consider modifying your plugin to follow the jQuery UI Widget format. This takes advantage of the widget factory, which provides ways to access the methods and properties in 2 ways: 1) Through the element the plugin is applied to, eg: $(#myElement).smartList(selectedValue) 2) Or by getting an 'instance' of the widget, eg: var myList = $(#myElement).data(smartList); var val = myList.getSelectedValue(); If you don't want to go this route, then you need to return an 'instance object' instead of a jQuery object. This means your plugin is not 'chainable' - ie, it must be the last method called on the object. To return an instance, create an object with pointers to your public properties and methods... return { options: options // property , getSelectedValue: getSelectedValue // method , insetItem: internalMethodName } There are a few ideas to get you started. /Kevin On Jan 4, 5:08 am, mehdi mehdi.mous...@gmail.com wrote: Hi, I've just developed a plugin that mimics the combo box control, albeit it's a special one. That's being defined as follows: (function($) { $.fn.extend({ smartList: function(settings) { //prepare settings, blah blah blah... return this.each(function() { //whatever code goes here... }); } }); })(jQuery); You know, to use this plugin, I could easily write the following JavaScript code: var $myList = $('myElement').smartList(); No problem so far. Now, I need to define and access some functions that's specific to the smartList. say, e.g., getSelectedValue, insertItem, and the like. The problem is that I've got no idea how to address such a thing in JavaScript. i.e., I need to write things like: $myList.getSelectedValue(); $myList.insetItem('foo', 'bar'); But this isn't possible, since the $myList variable is a jQuery object. So I just defined some functions, say, $.smartList.getSelectedValue and the like... but in this approach, I've to pass the jQuery object to this functions as a mandatory parameter and this really sucks. i.e., I need to get the selected value of $myList this way: var value = $.smartList.getSelectedValue($myList); Is there any better approach to address such a thing? Any help would be highly appreciated, TIA, Mehdi
[jQuery] Re: Prevent jagged text in IE
@Dave If this problem has a good fix, it should be fixed. There are several cases that will break differently in IE when this proposed fix is applied. It's not achieving consistent cross-browser behavior. There may be a solution out there still, and if someone has one they should post it. I haven't tested it, but did suggest an 'extra check' for opacity in the sample I gave. Assuming jQuery reports the curCSS correctly, this would seems to address the 'snap' issue you described... if ($E.css('filter') $E.css('opacity')==1) FYI, I ran across another example of this issue today. I created a test page with both a static and popup ui.datepicker. When seen side- by-side in IE7, the popup (animated) datepicker text is obviously not anti-aliased as the static version is... http://layout.jquery-dev.net/demos/datepicker.html All UI Widgets using animation look poorer than necessary when used in *the most common browser in the world*. So if this won't be addressed in the jQuery core, then every UI widget using animated elements should be patched to address it. Such a simple, common problem should not be allowed to affect UI Widgets IMO. /Kevin On Sep 30, 2:46 pm, Dave Methvin dave.meth...@gmail.com wrote: I'm not sure why this 'fix' should be added to fadeOut? It seems most applicable to fadeIn and fadeTo. Whoops, right. So the problem would be that in IE only, .fadeTo (slow, 1) makes the element completely visible and then pops to 50% opacity based on the stylesheet when the element's filter property is removed. There is no way to fix anti-aliasing if the user *chooses* to use opacity since this is a browser issue, If the user chooses to set a 50% opacity in the stylesheet that should work properly in IE as well, right? A fix for antialiasing shouldn't break something that currently works properly across browsers. Calling it an IE-bug doesn't make it go away. This is a cross browser issue, pure and simple. If this problem has a good fix, it should be fixed. There are several cases that will break differently in IE when this proposed fix is applied. It's not achieving consistent cross-browser behavior. There may be a solution out there still, and if someone has one they should post it.
[jQuery] Re: LI.offset and LI.position() gives erratic results
I have reposted this in the DEV forum... http://groups.google.com/group/jquery-dev/browse_thread/thread/16bd78710291bc93?hl=en#
[jQuery] Re: keeping table header fix
I create a lot of web-application list-screens with fixed-headers. I prefer to *not* work with a THEAD for this purpose because it is too limiting for complex page layouts. Instead, I create TWO tables - one for the headers and one for the content. This works well as long as you use table-layout:fixed and set specific column widths - I use a combo of fixed and percentage widths so that the tables will always auto-size to fill the page-width. Here is a simple example... div style=overflow-y: scroll; table style=table-layout: fixed col style=width: 10ex; col style=width: 20ex; col width=30% col width=70% col style=width: 24px; tr tdColumn 1/td tdColumn 2/td tdColumn 3/td tdColumn 4/td tdColumn 5/td /tr /table /div div style=overflow-y: scroll; height: 300px; table style=table-layout: fixed col style=width: 10ex; col style=width: 20ex; col width=30% col width=70% col style=width: 24px; tr tdData 1.1/td tdData 1.2/td tdData 1.3/td tdData 1.4/td tdData 1.5/td /tr tr tdData 2.1/td tdData 2.2/td tdData 2.3/td tdData 2.4/td tdData 2.5/td /tr tr tdData 3.1/td tdData 3.2/td tdData 3.3/td tdData 3.4/td tdData 3.5/td /tr /table /div Note that you need to set BOTH the header and content tables to overflow-y:scroll so that both containers have a scrollbar - even though the headers will not actually scroll. Without matching scrollbar, percentage column-widths would not line-up correctly. For IE, you can color the header-scrollbar with CSS so it is essentially 'invisible'. You can use any page-structure you want to control the height of the scrolling list. Separating the header markup from the list-markup provides a lot more options. This is compatible with a table-sorter because the 'list' is in a table by itself, so it is *impossible* for sorting or striping to affect your headers. It is also useful for Ajax - you can replace the entire data-table for maximum rendering speed. FYI, using table-layout:fixed also makes pages with large tables load MUCH FASTER because the browser does not have to wait for all the content to load before starting to render the table. The bigger the table, the more noticeable this improvement is. Hope that helps. /Kevin On Oct 2, 5:03 pm, lcplben b...@sellmycalls.com wrote: On Sep 16, 2:16 am, macsig sigbac...@gmail.com wrote: Hello guys, I'd like to know if there is a way to keep a table header fixed on top of a div while I scroll the table rows. I have a div high 200px and the table itself is around 300px so when I scroll down I'd like to always see the header on top. I already use for the table tablesorter so the solution must be compatible with that plug-in.
[jQuery] LI.offset and LI.position() gives erratic results
I am getting erratic results when trying to get the position of a LI element. Every browser gives different results - only IE7 seems to get it right... I have a navbar UL element nested a few levels deep within DIVs that provide page structure. The UL is also nested within a SPAN (inline- block) so the UL element can be centered within DIV#Nav1. A stripped- down version of the HTML is shown at bottom. The LI elements trigger a custom drop-down menu onHover. I use simple math to calculate the positioning of the DIV that acts as a menu... var $LI = $(this) // LI element , tabOffset = $LI.offset() , menuTop = tabOffset.top + $LI.outerHeight() , menuLeft = Math.floor(tabOffset.left) ; In IE7, this works perfectly - exactly as you would expect. But every other browser has one or more issues... Internet Explorer 7 $LI.offset().left = CORRECT $LI.offset().top = CORRECT $LI.position().top = 0 - CORRECT Chrome 3.0.195.21 $LI.offset().left = the Left-edge of the parent UL element! $LI.offset().top = CORRECT $LI.position().top = 0 - CORRECT FireFox 3.5 $LI.offset().left = the Right-edge of the parent UL element $LI.offset().top = too small by 15px $LI.position().top = -15 -- wrong, the LI has NO top-margin Opera 9.64 $LI.offset().left = the Right-edge of the parent UL element $LI.offset().top = CORRECT $LI.position().top = -19, even though offset().top is correct Only IE gets $LI.offset().left correct. Only IE and Chrome get $LI.position().top right (0), but IE, Chrome and Opera all get $LI.offset().top correct, even though Opera gets $LI.position().top wrong (-19). Only FireFox gets everything wrong! Can anyone shed any light on these discrepancies? I will spend the time to create and post a test page if no one can offer any clues, but I have not done so yet. Thanks in advance. /Kevin !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01//EN http://www.w3.org/TR/html4/strict.dtd; DIV id=Layout-Header DIV class=layout-header DIV id=TopNavbar class=navbar DIV id=Nav1 SPAN class=center UL class=tabs LIA href=/rentalsRentals/A/LI LIA href=/linensLinens/A/LI LIA href=/servicesServices/A/LI LIA href=/plannerPlanner/A/LI LIA href=/galleryGallery/A/LI LIA href=/communityCommunity/A/LI LIA href=/aboutAbout Us/A/LI /UL /SPAN /DIV /DIV /DIV /DIV
[jQuery] Re: Prevent jagged text in IE
@Dave with the fix, fades out but then pops to 50% opacity I'm not sure why this 'fix' should be added to fadeOut? It seems most applicable to fadeIn and fadeTo. But whatever the case, a little extra code could handle edge-cases -- something like... if (jQuery.browser.msie $(this).css('opacity')==1) this.style.removeAttribute('filter') Or for the politically correct... var $E = $(this); if ($E.css('filter') $E.css('opacity')==1) this.style.removeAttribute('filter') There is no way to fix anti-aliasing if the user *chooses* to use opacity since this is a browser issue, but it is *other 99%* that is the issue. There are many 'effects' used in jQuery that trigger the problem, so it should handle these *common scenarios*. Calling it an IE-bug doesn't make it go away. This is a a cross browser issue, pure and simple. /Kevin On Sep 29, 7:34 am, Dave Methvin dave.meth...@gmail.com wrote: This is a nice simple solution to a common cross-browser issue, so wouldn't it be reasonable for this to be added to the standard jQuery animate method? The extra size is minimal. That solution assumes no opacity was specified in a stylesheet. style #glory { opacity: 0.5; filter: alpha(opacity = 50); } /style script // with the fix, fades out but then pops to 50% opacity $(#glory).fadeOut(); /script
[jQuery] Re: Prevent jagged text in IE
If browser-detection can't be used, then subsititute code to detect the filter attribute instead. The exact syntax is not important... I believe jQuery SHOULD handle this cross-browser animation issue because it is common to the majority of users. It is clearly a deficiency when jQuery's own contributors have to override core methods to address it. The choices are: A) Update jQuery to handle this issue natively, or; B) Continue using hacks for animations in the world's most common browser. I'm interested in opinions on this, particularly from the regular jQuery contributors. /Kevin On Sep 27, 4:20 am, ryan.j ryan.joyce...@googlemail.com wrote: browser sniffing is already deprecated in favour of feature sniffing, it's unlikely code using it will be added.
[jQuery] Re: Prevent jagged text in IE
@Rick if (jQuery.browser.msie) this.style.removeAttribute('filter'); This is a nice simple solution to a common cross-browser issue, so wouldn't it be reasonable for this to be added to the standard jQuery animate method? The extra size is minimal. /Kevin On Sep 25, 5:17 pm, Rick Faircloth r...@whitestonemedia.com wrote: I include a reference to a file with this jQuery code in every page to solve that problem, Dave. Best solution I've found so far. I got it from someone, somewhere, but don't remember who. Rick jQuery.fn.fadeIn = function(speed, callback) { return this.animate({opacity: 'show'}, 750, function() { if (jQuery.browser.msie) this.style.removeAttribute('filter'); if (jQuery.isFunction(callback)) callback(); }); }; jQuery.fn.fadeOut = function(speed, callback) { return this.animate({opacity: 'hide'}, 750, function() { if (jQuery.browser.msie) this.style.removeAttribute('filter'); if (jQuery.isFunction(callback)) callback(); }); }; jQuery.fn.fadeTo = function(speed,to,callback) { return this.animate({opacity: to}, 750, function() { if (to == 1 jQuery.browser.msie) this.style.removeAttribute('filter'); if (jQuery.isFunction(callback)) callback(); }); };
[jQuery] Re: Way to convert DOM event to jQuery event?
If you need data for multiple fields, then a 3rd option is to create a single hash/data object for the page and writing all your data into that. This makes your data easy to read and debug, and is highly efficient because you don't have to 'parse' anything... var Record = { foo: db-value-1 , bar: db-value-2 , baz: db-value-3 } Then you can use *either* jQuery or inline events to access this data... $(document).ready(function() { $(#myID).click(function() { alert( foo = + Record.foo ); return false; }); }); You could use the fieldnames as keys in your data object to make it generic... var Record = { myID1: db-value-1 , myID2: db-value-2 , myID3: db-value-3 ... } $(document).ready(function() { $(a.linkType).click(function() { alert( this.id + = + Record[ this.id ] ); return false; }); }); /Kevin On Sep 23, 5:57 pm, Ricardo Tomasi ricardob...@gmail.com wrote: Do you really need to output this data embedded in the HTML? Does it have any meaning/purpose without Javascript? There are two simple non- hackish ways you can do it: 1: load data later via XHR, use an element identifier to bind it 2: output metadata in the class attribute - it's valid, and not against the specification - the class attribute is not specifically meant for presentation, the specs say For general purpose processing by user agents. ex: class=link { foo: 'bar', amp: 'bamp', x: [1,2,3] }. It's easy to create your own parser for that: $.fn.mdata = function(){ return window[eval](( + this[0].className.match(/{.*}/) + )); }; $('a').mdata() == Object foo:'bar' etc.. It will work as long as you use valid JSON. cheers, Ricardo
[jQuery] Re: event-binding to dynamically created elements... (JSP vs JS problem......)
Good points by Josh. However this selector example... $('img[class=thumb]).mouseover ...can be written simpler as $(img.thumb).mouseover It's faster in most browsers to select-by-class than to iterate elements and 'read attributes'. jQuery may process both syntaxes the same (?), but using the img.thumb syntax *guarantees* the most optimized handling. This is a strange code sample. Why 'add' a class on mouseover, but not remove it on mouseout? If you want to add/remove the 'dim' class, then use jQuery's hover method to combine both events... $(img.thumb).hover( function () { $(this).addClass('dim'); , function () { $(this).removeClass('dim'); ); If you *don't* want to remove the class, then this function only needs to run 'once', because the class only needs to be added on the FIRST mouseover event. In this case, use jQuery's .one() (one-time) method... $(img.thumb).one(mouseover, function () { $(this).addClass('dim'); ); /Kevin On Aug 30, 1:02 am, Josh Powell seas...@gmail.com wrote: for (i = 1; i 5; i++) { $('#thumb' + i).bind('mouseover',function(event) { $(this).addClass('dim'); }); } The 'i' you've called here is a global variable, in a for loop always put a var in front of it to have local scope (to the function, not block) for (var i = 1; i 5; i++) { $('#thumb' + i).bind('mouseover',function(event) { $(this).addClass('dim'); }); } but... more importantly, reframe your thoughts on javascript/jquery programming to let the selectors do the iteration for you. $('img[class=thumb]).mouseover(function () { $(this).addClass('dim'); }); snip / Josh Powell
[jQuery] Re: JSON data manipulation
Hi Glenn, Create an array and 'push' each hash of plot data onto it. When the loop is complete, pass the now complete array... $.getJSON('/Graph/HearthRateDataJSON', , function(data) { var data= [ ]; $.each(data, function(entryindex, entry) { data.push( { Name: entry['Name'], Serie: entry['Serie'] } ); }); Plot( data ); }); /Kevin On Aug 29, 7:31 am, Depechie glenn.versweyv...@gmail.com wrote: Hello guys. My question has actually more to do with jqPlot ( graph library for jQuery ), but I'm still asking it here, because it concerns json data manipulation through jquery. I'm not a javascript nor JQuery programmer, I'm just in a learning process. So my question. To plot something through jqPlot the syntax should be: plot = $.jqplot('chart', [line1, line2, line3], { ... } With line1, line2 and line3 as array variables! My current JSON data is: [{Name:series1,Serie:[[1,4],[2,25],[3,7],[4,14]]}, {Name:series2,Serie:[[1,13],[2,5],[3,7],[4,20]]}] And in my .js file I've put this: $.getJSON('/Graph/HearthRateDataJSON', , function(data) { $.each(data, function(entryindex, entry) { Plot(entry['Serie'], entry['Name']); }); }); Problem now is that the graph will only plot the 'last' serie, because the graph itself needs all data at once! And not like I did going through each JSON record and plot the line. So any thoughts on how to use the $.each to put all data in one variable to get jqPlot to plot all series? Thanks Glenn
[jQuery] Re: JSON data manipulation
OOPS, I didn't formatted the data correctly for passing to Plot() - sorry, didn't read carefully. But the premise is the same - create an array by looping your data, and then pass the array when done. /Kevin On Aug 30, 9:04 am, Kevin Dalman kevin.dal...@gmail.com wrote: Hi Glenn, Create an array and 'push' each hash of plot data onto it. When the loop is complete, pass the now complete array... $.getJSON('/Graph/HearthRateDataJSON', , function(data) { var data= [ ]; $.each(data, function(entryindex, entry) { data.push( { Name: entry['Name'], Serie: entry['Serie'] } ); }); Plot( data ); }); /Kevin On Aug 29, 7:31 am, Depechie glenn.versweyv...@gmail.com wrote: Hello guys. My question has actually more to do with jqPlot ( graph library for jQuery ), but I'm still asking it here, because it concerns json data manipulation through jquery. I'm not a javascript nor JQuery programmer, I'm just in a learning process. So my question. To plot something through jqPlot the syntax should be: plot = $.jqplot('chart', [line1, line2, line3], { ... } With line1, line2 and line3 as array variables! My current JSON data is: [{Name:series1,Serie:[[1,4],[2,25],[3,7],[4,14]]}, {Name:series2,Serie:[[1,13],[2,5],[3,7],[4,20]]}] And in my .js file I've put this: $.getJSON('/Graph/HearthRateDataJSON', , function(data) { $.each(data, function(entryindex, entry) { Plot(entry['Serie'], entry['Name']); }); }); Problem now is that the graph will only plot the 'last' serie, because the graph itself needs all data at once! And not like I did going through each JSON record and plot the line. So any thoughts on how to use the $.each to put all data in one variable to get jqPlot to plot all series? Thanks Glenn- Hide quoted text - - Show quoted text -
[jQuery] Re: Modify iframe with jquery
If you cannot change the scrolling by modifying the iframe, then do it by modifying the document inside the iframe. I don't remember the syntax for accessing the document/body elements inside an iframe, so I'll just use pseudo-code here. You should be able to find the correct syntax easily... $(#iframe)[0].document.$(body).css({ overflow: hidden; }); This will work as long as the iframe content is in the same domain as your parent page. If it is in a different domain, then browser security will prevent you from accessing the document inside the iframe. /Kevin On May 14, 1:56 pm, ripple ripple...@yahoo.com wrote: Thanks, but it's not the contents of the iframe that I'm looking for. It's altering the behavior(scrolling) of the iframe that i am trying to achieve. --- On Thu, 5/14/09, waseem sabjee waseemsab...@gmail.com wrote: From: waseem sabjee waseemsab...@gmail.com Subject: [jQuery] Re: Modify iframe with jquery To: jquery-en@googlegroups.com Date: Thursday, May 14, 2009, 4:48 PM $(#iframeid).contents.find(#elementid); $(#iframeid).contents.find(#elementid).text(); $(#iframeid).contents.find(#elementid).html(); I used this earlier today with some php where a wysiwyg editor had its html contents embedded in a Iframe and i hate to post the raw html to a database. worked like a charm. On Thu, May 14, 2009 at 10:43 PM, ripple ripple...@yahoo.com wrote: I have an iframe in a page that scrolls on initial load, but after clicking a link and loading a different page I have to remove the scroll(scrolling=no). When the 2nd page loads I set the attr on the the iframe to scrolling=no. $('#iframe').attr('scrolling','no'); But, This does not seem to work. Does anyone know? Is the iframe more of a static object after initial creation and load? Can it's parameters (except for src) not be changed? Thanks
[jQuery] Re: state of the art for corner rounding?
I have not tried DD Roundies yet - it's on my todo list. Hoever I am using a jquery plug-in called 'Cornerz' that is working very well for me. It uses Canvas/VML for corners, but does not require any additional plug-ins: http://labs.parkerfox.co.uk/cornerz/ This plug-in does *not* automatically pick-up -moz-border-radius settings from CSS, but I have written an intermediate function that does. This accomplishes exactly what you are asking - with the exception that you still need to add the cornerz class to the elements you want rounded in IE to avoid having to check the CSS of every element on the page! I submitted this function to the plug-in's forum... http://groups.google.com/group/cornerz/browse_thread/thread/2f0639e7c7fa349c?hl=en# I'd be interested to learn how whether DD Roundies is significantly better or not. /Kevin On May 2, 9:45 am, Jack Killpatrick j...@ihwy.com wrote: bump. Anyone eval'd the corner plugins recently enough to have an opinion? Thx. Jack Jack Killpatrick wrote: Hi All, I have a half dozen bookmarks for rounded corner plugins, but am wondering if there's a state of the art plugin kicking any booty on that these days? What I'd *really* like is to just be able to set -moz border radiuses in CSS and have a plugin magically use those to create rounded corners in IE and Safari (IE mainly... using excanvas or something with it is fine, too). Any advice? For the project I'm working on now I don't need to have lines at the border (ie: no border:1px solid black or anything). Thanks, Jack- Hide quoted text - - Show quoted text -
[jQuery] Re: fadein thumbnails when loaded
Hi Rick, Karl's suggestion seems the most elegant (assuming it works OK). Here is some sample code for what he is suggesting -- in HEAD or a stylesheet... body.js #media-gallery ul li img { /* opacity *may* work better than display:none */ opacity: 0.01; filter: alpha(opacity=1); } And in your JS... $(function() { $(#media-gallery ul img).fadeIn(2000); }); Then add this JS to your HTML - immediately after the BODY tag... body script type=text/javascript document.documentElement.className = js; -OR- $('body').addClass(js); /script In theory, the images will only be hidden (1% opacity) if Javascript is enabled, because otherwise BODY will not have the 'js' class, therefore your CSS rule will not have any effect. Since you are adding the class *before* the images are added to the DOM, they should load transparent. And because they are not 'hidden' (display:none), the images will still take up their normal space when loading, instead of making the page 'jump' they they are made visible. /Kevin On Apr 28, 4:26 am, Rick Faircloth r...@whitestonemedia.com wrote: In the head you can do this: script type=text/javascript document.documentElement.className = 'js';/script Then you can set styles for elements as descendants of .js. Karl...will you explain a little more about what this means and perhaps give an example of its implementation? Or is there a blog or tutorial somewhere? Thanks, Rick
[jQuery] Re: fadein thumbnails when loaded
Here is a variation on Eric's idea. But in this example, instead of writing the CSS rule via Javascript, write a rule to *negate it* inside a noscript tag. -- in HEAD or a stylesheet... #media-gallery ul li img { /* opacity *may* work better than display:none */ opacity: 0.01; filter: alpha(opacity=1); } Then in the HEAD of you page, add a STYLE block inside a NOSCRIPT block... noscript style type=text/css #media-gallery ul li img { /* UNDO the opacity rule set previously */ opacity: 1; filter: alpha(opacity=100); } /style /noscript Just one more idea. /Kevin On Apr 29, 9:58 am, Kevin Dalman kevin.dal...@gmail.com wrote: Hi Rick, Karl's suggestion seems the most elegant (assuming it works OK).
[jQuery] Re: $('#foo p') or $('p', $('#foo'))
For anyone interested, here is the updated set of 'tests' for the test page I posted previously. This is the test-set John is currently using: // Test # 1 start = new Date(); $Test = $(#div+ myDiv + p); end = new Date(); a_Selectors.push('$(#div'+ myDiv +' p)'); a_Times.push(end - start); // Test # 2 start = new Date(); $Test = $(p, #div+ myDiv); end = new Date(); a_Selectors.push('$(p, #div'+ myDiv +')'); a_Times.push(end - start); // Test # 3 start = new Date(); $Test = $(#div+ myDiv).find(p); end = new Date(); a_Selectors.push('$(#div'+ myDiv +').find(p)'); a_Times.push(end - start); // Test # 4 start = new Date(); $Test = $(#div+ myDiv + p); end = new Date(); a_Selectors.push('$(#div'+ myDiv +' p)'); a_Times.push(end - start); // Test # 5 start = new Date(); $Test = $(#div+ myDiv).children(p); end = new Date(); a_Selectors.push('$(#div'+ myDiv +').children(p)'); a_Times.push(end - start); // Test # 6 start = new Date(); $Test = $($(#div+ myDiv)[0].childNodes).filter(p); end = new Date(); a_Selectors.push('$( $(#div'+ myDiv +')[0].childNodes ).filter (p)'); a_Times.push(end - start); If you created your own test page, just copy-n-paste these tests into it. NOTE that setting: 'c_divs=1000' and 'c_paras=500' (as John is using) makes the page very slow to load because it has to generate all these elements. So for quick tests, reduce these numbers to 100 each. But if you find something interesting, try cranking the numbers up again - it magnifies the speed differences between the tests. /Kevin On Feb 25, 6:48 pm, RobG rg...@iinet.net.au wrote: On Feb 26, 11:22 am, John Resig jere...@gmail.com wrote: The benchmark is getElementById().getElementsByTagName() - why not inlcude that in the test? Add the following below test 3: // Test # 4 start = new Date(); $Test = document.getElementById('div' + myDiv).getElementsByTagName('p'); end = new Date(); a_Selectors.push('getEBI().getEBTName()'); a_Times.push(end - start); -- Rob
[jQuery] Re: $('#foo p') or $('p', $('#foo'))
John wrote: You should always use $(#foo).find(p) in favor of $ (p, $(#foo)) I'm trying to extrapolate some general concepts from this 'rule'... First, I *assume* these two statements are identical in performance: $(p, $(#foo)) == $(p, #foo) If so, then does it matter what the scope selector is? What if the scope is *not an ID*, and therefore not as fast to find, like:: $(div.myClass).find(p) in favor of $(p, div.myClass) ??? If this is still true, then my understanding is that $(a).find(b) syntax is ALWAYS faster than $(a, b)??? IF it is true that find() is always faster - or at least equal - to specifying a scope selector/element, then it would seem that jQuery should simply use the find() flow internally when a scope selector is specfied. In other words, when a scope selector/element is specified, find this element first and then 'call' the same method used for find () - ie: *** internally *** $(p, $(#foo)) == $(#foo).find(p) I can't think of any excepts to this - the result should always be identical? If so, and performance is equal or superior, then *why not* do this internally so the two statements above essentially become 100% identical? It would just be two ways of expressing the same thing, which is how it appears to users. Am I off-base here? If so, which assumuption above breaks down? Even if there is a good reason to treat the syntax differently internally, I'm still interested to know if I should avoid using scope selectors in favor of find() ***under all conditions*** - or only under specific conditions? /Kevin On Feb 24, 5:58 pm, John Resig jere...@gmail.com wrote: I want to point out a couple things: 1) You should always use $(#foo).find(p) in favor of $(p, $ (#foo)) - the second one ends up executing $(...) 3 times total - only to arrive at the same result as doing $(#foo).find(p). 2) I generally dislike saying that there's one good way to do a selector (especially with one that has such bad syntax, as above) - especially since it may not always be that way. In fact, I've already filed a bug and I'll be looking in to this issue, possibly resolving it tonight or tomorrow - at which point the advice will be false again.http://dev.jquery.com/ticket/4236 My recommendation is to always write the simplest, easiest to understand, expression: jQuery will try to do the rest to optimize it. --John On Feb 24, 10:23 am, Stephan Veigl stephan.ve...@gmail.com wrote: Hi Karl, $('#foo').find('p') and $('p', $('#foo')) are approximately of the same speed. I've put the test code on JSBin, so everybody can play around with it and try other combinations :-)http://jsbin.com/ifemo by(e) Stephan 2009/2/24 Karl Swedberg k...@englishrules.com: Hi Stephan, Thanks for doing this testing! Would you mind profiling $('#foo').find('p') as well? I suspect it will be roughly equivalent to $('p', $('#foo')) Cheers, --Karl Karl Swedberg www.englishrules.com www.learningjquery.com On Feb 24, 2009, at 8:28 AM, Stephan Veigl wrote: Hi, I've done some profiling on this, and $(p, $(#foo)) is faster than $(#foo p) in both jQuery 1.2.6 and 1.3.2. the test HTML consists of 100 ps in a foo div and 900 ps in a bar div. However the factor differs dramatically: In 1.2.6 the speedup from $(p, $(#foo)) to $(#foo p) was between 1.5x (FF) and 2x (IE), while for 1.3.2 the speedup is 20x (FF) and 15x (IE). $(p, $(#foo)) is faster in 1.3.2, by a factor of 1.5 (both FF and IE), while $(#foo p) is _slower_ in 1.3.2 by 8.5x (FF) and 4.6x (IE). Even with an empty bar div $(p, $(#foo)) is faster by a factor up to 3x. Conclusion: If you have an ID selector, first get the element by it's ID and use it as scope for further selects. by(e) Stephan 2009/2/23 ricardobeat ricardob...@gmail.com: up to jQuery 1.2.6 that's how the selector engine worked (from the top down/left to right). The approach used in Sizzle (bottom up/right to left) has both benefits and downsides - it can be much faster on large DOMs and some situations, but slower on short queries. I'm sure someone can explain that in better detail. Anyway, in modern browsers most of the work is being delegated to the native querySelectorAll function, as so selector performance will become more of a browser makers' concern. - ricardo On Feb 23, 1:08 pm, Peter Bengtsson pete...@gmail.com wrote: I watched the John Resig presentation too and learned that CSS selectors always work from right to left. That would mean that doing this:: $('#foo p') Would extract all p tags and from that list subselect those who belong to #foo. Suppose you have 1000 p tags of them only 100 are inside #foo you'll have wasted 900 loops. Surely $('#foo') is the fastest lookup possible. Doing it this way will effectively limit the scope of the $('p') search and you will
[jQuery] Re: $('#foo p') or $('p', $('#foo'))
FYI, I built a quick test page for this. As previously noted, the differences in v1.2.6 are relatively small - about 2x as long for one syntax over the other. But with 1.3.2 - Wow! - 60x longer! jQuery version used = 1.3.2 Total number of DIVs = 100 Paragraphs per DIV = 50 --- $(#div50 p) = 574ms $(p, #div50) = 8ms $(#div50).find(p) = 9ms For anyone interested, below is *the complete test-page* so you can do your own testing - just copy and paste. No external files are required. Since the HTML is all generated by script, you can easily modify the number of divs and number of paragraphs per div just by changing the vars. You can also add as many test-cases for comparison as you want. It's all pretty self-explanitory. !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01//EN http://www.w3.org/ TR/html4/strict.dtd HTML HEAD META http-equiv=Content-Type content=text/html; charset=utf-8 TITLEjQuery Speed Test/TITLE STYLE type=text/css body { font-family:Arial, Helvetica, sans-serif; font-size: 80%; color: #FFF; background: #000; margin: 15px; } div { border: 1px solid #FF0; padding:5px 20px; margin: 1ex 0; } p { margin: 0; } div#Output { font-size: 1.25em; color: #000; background: #FFF; border: 3px solid #999; margin-bottom: 15px; } div#Output p { margin: 1ex 0; } /STYLE SCRIPT type=text/javascript src=http://code.jquery.com/jquery- latest.js/SCRIPT SCRIPT type=text/javascript $(document).ready(function(){ var c_divs = 100 , c_paras = 50 , myDiv = Math.floor(c_divs/2) , $Output = $(#Output) , $DIV , $Test , start, end , a_Selectors = [] , a_Times = [] ; $DIV = $(div/); for (var i=1; i = c_paras; i++) $DIV.append(p/).append( i ); for (var i=1; i = c_divs; i++) $DIV.clone(false).appendTo(document.body).attr(id,div+i); // Test # 1 start = new Date(); $Test = $(#div+ myDiv + p); end = new Date(); a_Selectors.push('$(#div'+ myDiv +' p)'); a_Times.push(end - start); // Test # 2 start = new Date(); $Test = $(p, #div+ myDiv); end = new Date(); a_Selectors.push('$(p, #div'+ myDiv +')'); a_Times.push(end - start); // Test # 3 start = new Date(); $Test = $(#div+ myDiv).find(p); end = new Date(); a_Selectors.push('$(#div'+ myDiv +').find(p)'); a_Times.push(end - start); // Write the Results $Output.html( pjQuery version used nbsp; = + $DIV.jquery +/p + pTotal number of DIVs = + c_divs +/p + pParagraphs per DIV nbsp; = + c_paras +/p + hr / ); var c = a_Selectors.length; for (var i=0; i c; i++) $Output.append(p+ a_Selectors[i] + = + a_Times[i] +ms / p); }); /SCRIPT /HEAD BODY DIV id=OutputWorking.../DIV /BODY /HTML
[jQuery] Re: $('#foo p') or $('p', $('#foo'))
That's a fantastic improvement. But now I have a new challenge - keep reading... To see if there really is a difference between the 2nd and 3rd options, or whether it is just 'variance', I cranked up the DIVs Ps and tried both versions again: ALL tests below are in FireFox 3.0.6 jQuery version used = 1.3.2 Total number of DIVs = 1000 Paragraphs per DIV = 500 --- $(#div500 p) = 15916ms $(p, #div500) = 32ms $(#div500).find(p) = 2ms jQuery version used = 1.3.3pre Total number of DIVs = 1000 Paragraphs per DIV = 500 --- $(#div500 p) = 48ms $(p, #div500) = 4ms $(#div500).find(p) = 4ms The last two tests seem identical, but the first syntax is still 0- times slower in 1.3.3. I though the 1st syntax might be slower because it handles *a range of possible syntaxes*, like $(#div500 p). So I add 2 new syntaxes and ran the test again... jQuery version used = 1.3.3pre Total number of DIVs = 1000 Paragraphs per DIV = 500 --- $(#div500 p) = 34ms $(p, #div500) = 2ms $(#div500).find(p) = 3ms $(#div500 p) = 16396ms $(#div500).children(p) = 32ms WOW! Check out the last 2 tests, John. Syntax #4 takes 512-times longer than #5! I think this code needs a little TLC too ;) It was also interesting that $(#div500).children(p) is 10-times slower than $(#div500).find(p). So I added one final test using childNodes and filter() to see if I could beat .children()... jQuery version used = 1.3.3pre Total number of DIVs = 1000 Paragraphs per DIV = 500 --- $(#div500 p) = 55 ms $(p, #div500) = 2 ms $(#div500).find(p) = 3 ms $(#div500 p) = 14802 ms $(#div500).children(p) = 32 ms $( $(#div500)[0].childNodes ).filter(p) = 19 ms The last (childNodes) test gathers the same elements in half the time. The 32ms performance of children(p) is very good, but perhaps there is still room for improvement? /Kevin On Feb 25, 1:30 pm, John Resig jere...@gmail.com wrote: To follow-up from my post yesterday, here are the new numbers, for 1.3.3 (work in progress, naturally):http://ejohn.org/files/jquery1.3.3/id.html jQuery version used = 1.3.3pre Total number of DIVs = 100 Paragraphs per DIV = 50 --- $(#div50 p) = 2ms $(p, #div50) = 0ms $(#div50).find(p) = 1ms --John
[jQuery] Re: $('#foo p') or $('p', $('#foo'))
@John: I found a little bug in your v1.3.3 test version... This selector works fine in FireFox, but bombs out in IE7... $(#div50 p) IE7 -- Object doesn't support this property or method But this works fine: $(#div50 p) NOTE that I'm pulling v1.3.3 directly from your personal copy (jquery1.3.3/dist/jquery.js). I realize this is just a test version, but thought you'd like to know. /Kevin On Feb 25, 4:21 pm, John Resig jere...@gmail.com wrote: WOW! Check out the last 2 tests, John. Syntax #4 takes 512-times longer than #5! I think this code needs a little TLC too ;) It was also interesting that $(#div500).children(p) is 10-times slower than $(#div500).find(p). So I added one final test using childNodes and filter() to see if I could beat .children()... Oh right, this is a regression to what I just did - I can tweak that. I'll look in to it tonight. --John
[jQuery] Re: Optimize large DOM inserts
I identified why the $(table /).append syntax is so extremely slow in the sample page. It actually has nothing to do with being a 'second DOM append' as was assumed. Here is what I learned from my testing... This is the HTML mark-up for the tests: BODY DIV id=container/DIV TABLE id=Table/TABLE /BODY I generated the same 'html' var from Mike's test page - containing 2000 table-rows. The loop used is irrelevant to these tests because the times shown below are for the DOM insertion *only*. First, here is the original append-code from Mike's sample page... $('#container').append( $('tabletbody/tbody/table').append(html) ); // run-time: 7.5 sec Note the extreme slowness of the insertion - over 7 seconds! But by just *moving* the tbody tags, it becomes 20-times faster... $('#container').append( $('table/table').append('tbody'+ html +'/tbody') ); // run-time: 0.36 sec If we reduce it to a single command, it becomes 35-times faster... $('#container').append( 'tabletbody'+ html +'/tbody/table' ); // run-time: 0.24 sec BTW, the speed is the same whether .html() or .append() is used. If the existing table is used instead, we gain only a few ms. $('#Table').append('tbody'+ html +'/tbody'); // run-time: 0.22 sec To see if it makes a difference appending to a table that's 'not empty', I appended the same 2000 rows *10-times* (to keep the math simple) html = 'tbody'+ html +'/tbody'; $('#Table') .append( html ) .append( html ) .append( html ) .append( html ) .append( html ) .append( html ) .append( html ) .append( html ) .append( html ) .append( html ) ; // run-time: 2.23 sec The run-time to append 10-times is *exactly* 10-times as long as appending the first time. This means it makes no difference whether the table is 'empty' or already has content. So, in my tests, there is *no benefit* to appending an entire table to an empty container. You get identical performance (in IE7) by appending the new rows to a table - as long as they are wrapped in a tbody. If the rows are not inside a tbody, then they are appended one- by-one! This is why the syntax used by Mike was so extremely slow. It actually had nothing to do with appending 2 elements, which I knew could not account for a 3000% difference! I dynamically generate table rows A LOT. My current web-app appends a 7-row tbody as a 'new record'. But I do not use loops to generate html. Instead I use a hidden 'template tbody' that I clone. This has all the events for the form-fields pre-attached. All I do is rename all the fields after cloning the template, and before appending it to the target table. This method is much easier to read and update than a hundred lines of html-generating script. Plus I actually use the same mark-up to generate the existing records onLoad (via JSP), so there is zero code duplication. I wanted to identify the cause of the slow append in Mike's sample because I never see this in my applications. Now that I understand what was happening, I see that appending a tbody is actually extremely efficient - in fact, even faster than writing a new table! This is good news because I cannot regenerate the entire table each time - I must append new rows/records to an existing table. I thought I'd share these results because appending a tbody (or a single row) provides many more options than writing an entire table. And now I know there is no performance difference - at least not in IE7. Thanks to Mike for providing a starting points for these tests, in addition to his loop-optimization tips. /Kevin
[jQuery] Re: Optimize large DOM inserts
Rick, based on what I've learned from testing, you have another option now... Here is a modified version of Mike's code - without generating the table. function populateDutyTable(response) { var currentDay = ''; var rows = response.QGETDUTYSCHEDULE.DATA; var out = [], o = -1; out[++o] = 'tbody'; // CHANGED for( var row, i = -1; row = rows[++i]; ) { var day = row[1]; if( currentDay != day ) { currentDay = day; out[++o] = 'trtd class=cell-day'; out[++o] = row[1]; out[++o] = '/tdtd class=cell-date'; out[++o] = row[2]; out[++o] = '/tdtd class=cell-blank colspan=5nbsp;/td/tr'; } out[++o] = 'trtd class=cell-blank-daynbsp;/tdtd class=cell-blank-datenbsp;/tdtd class=cell-am-am'; out[++o] = row[3]; out[++o] = '/tdtd class=cell-position'; out[++o] = row[4]; out[++o] = '/tdtd colspan=3Cell Content/td/tr'; } out[++o] = '/tbody'; // CHANGED $('#scheduleBody').append( out.join('') ); // CHANGED } A container around the table is no longer required because wrapping the rows in a tbody achieves the same performance as wrapping them in a table. Plus, you could now add rows without regenerating the entire table. This provides more options with no penalty. For example, now you could hard-code the table with column headers - for example... table id=scheduleBody thead tr thID/th thDay/th thDate/th thName/th /tr /thead /table This is cleaner and faster than adding column headers inside your Javascript loop. I suggest you try both methods, Rick. Use a timer (like MIike's sample pages) to confirm whether both are equally fast. Based on my tests, you may find appending to the table even faster, with cleaner markup as a bonus. Ciao, /Kevin On Feb 7, 3:20 pm, Rick Faircloth r...@whitestonemedia.com wrote: Hey, thanks Michael for taking the time to provide the explanation and the re-write. I'll put this into place and see how it performs. I'm sure it'll be *much* better! Rick
[jQuery] Re: Newb question about accessing a form's inputs
Unless jQuery 1.3 has made vast improvement in the name=Xxx functionality, it is *horrendously slow*! I use a custom function to access form-fields - $F(fieldName) - which is up to 1000-times faster on large pages in my web-application. But this method is dependant on other custom methods, so I cannot provide it here as a stand-alone plug-in.. I wish/hope jQuery will soon provide an efficient way to access form- fields 'by name' because using IDs on form-fields is a clumsy hack that I refuse to use except in special cases. On complex, dynamically generated form pages, it clutters the code and requires extra logic to add sequential IDs to things like radio buttons. So this is not a proper solution to a common need. /Kevin On Feb 6, 2:27 pm, James james.gp@gmail.com wrote: Without using IDs, you can use: var myVar = $(input[name=myHiddenInput]).val(); On Feb 6, 10:54 am, james noahk...@gmail.com wrote: Hi, If I have a form: form name=myForm method=post action=myAction.php onsubmit=javascript:doStuff() input type=hidden name=myHiddenInput/ input type=text name=myNonHiddenText/ input type=submit value=submit /form What is the equivalent JQuery syntax for the following? function doStuff() { document.myForm.myHiddenInput.value = 'some dynamic var'; return true; } Thanks in advance, James- Hide quoted text - - Show quoted text -
[jQuery] Re: Optimize large DOM inserts
These test pages DO NOT accurately compare the speed of array.join() VS string+= The biggest speed difference between the two is REALLY that one uses $(table/table) and one doesn't. If this is removed from the 'slow' page, the load-speed goes from 8.7 sec to 1.5 sec. This is still 6-times longer than the fast version - but no longer 30-times longer! Conversely, I changed the 'fast' page to use the append syntax (after removing table and tbody from the array): $('#container').append( $('table/table').append( out.join('') ) ); This changed the 'fast' load from 0.24 sec to 7.3 sec! So even the 'fast loop' page performed 30-times slower when the element-append method is used! There was another code difference as well - the fast page uses $ ('#container').html() and the slow-page $('#container').append(). However, since the container is empty, it does not cause any significant speed difference. So for a TRUE loop-speed comparison, the code for the 'slow version' should be: var html = 'tabletbody'; $.each( rows, function( iRow, row ) { html += 'trtd' + row.text + '/td/tr'; }); html += '/tbody/table'; $('#container').html( html ); This now uses the same html() syntax as the fast version, isolating the difference between the pages to ONLY the 2 loops. Now there is less than a 1.3 sec difference - instead of 8+ seconds. Now it becomes clear that the biggest lesson here is that append (table/table) is a much bigger problem than the loop code. This is important to know because it would apply even if there were NO loop at all! Thanks for bringing both these details to my attention. I do a lot of dynamic HTML generation, so it's helpful to know what to watch out for. /Kevin On Feb 5, 7:25 pm, Michael Geary m...@mg.to wrote: ...there is not much room for improvement left. You just know that when you say that, someone will come along with a 20x-40x improvement. ;-) http://mg.to/test/loop1.html http://mg.to/test/loop2.html Try them in IE, where the performance is the worst and matters the most. On my test machine, the first one runs about 6.3 seconds and the second one about 0.13 seconds. -Mike From: Ricardo Tomasi Concatenating into a string is already much faster than appending in each loop, there is not much room for improvement left. What you can do improve user experience though is split that into a recursive function over a setTimeout, so that the browser doesn't freeze and you can display a nice loading animation. On Feb 5, 5:03 pm, James james.gp@gmail.com wrote: I need tips on optimizing a large DOM insert to lessen the freeze on the browser. Scenario: I receive a large amount of JSON 'data' through AJAX from a database (sorted the way I want viewed), and loop through them to add to a JS string, and insert that chunk of string into a tbody of a table. Then, I run a plug-in that formats the table (with pagination, etc.). Simplified sample code: var html = ''; $.each(data, function(i, row) { html += 'trtddata from json/td/tr';}); $(tbody).append(html); $(table).formatTable(); formatTable() requires that the table has to be completed before it can be executed. Is there any way I can optimize this better? I think I've read somewhere that making a string too long is not good, but I've also read that updating the DOM on each iteration is even worst. Any advice would be appreciated!- Hide quoted text - - Show quoted text -
[jQuery] Re: Can JQuery solve the iframe height=100% problem?
Hi Dave, You've probably long-since moved on from this, but I stumbled across this topic again, so thought I'd answer anyway... There are lots of examples on the Layout website for creating a 'layout' around an iframe - use one of these as a starting point... http://layout.jquery-dev.net/demos/frames.html http://layout.jquery-dev.net/samples/iframe_south.html Or use ANY demos as a starting point and just drop in your iframe: http://layout.jquery-dev.net/demos.html The UI/Layout website itself uses iframes for some pages so it can wrap content from other sites, like: http://layout.jquery-dev.net/discuss.html Rather than use the iframe itself as a layout 'pane', you could also put the iframe 'inside' a regular pane-div. Since the pane-div has a width and height set, all you need is: iframe width=100% height=100% ... This will auto-size the iframe to fit within the inner-dimensions of the pane - ie, inside the padding. The Layout widget provides virtually unlimited options for auto-sizing iframes and wrapping other content around it - like headers, footers, sidebars, etc. If you want to use Layout, then first check out the website documentation. If you need more assistance, use the dedicated discussion group... http://layout.jquery-dev.net/discuss.html HOWEVER, a page-layout may not be suitable to your needs because it a 'Javascript' solution, so users MUST have JS enabled or else your page will not look as you want. So depending on your need, you may find a pure CSS solutions preferable, even if it is does require some ugly nesting. Hope that helps. /Kevin On Jan 28, 11:39 am, laredotorn...@zipmail.com laredotorn...@zipmail.com wrote: Hi Kevin, I really appreciate your help with all this. Unfortunately, I added what you had suggested ... script type=text/javascript $(document).ready(function() { $(body).layout({ closable: false , resizable: false , spacing_open: 0 , center_paneSelector: #fileTreeIframe }); }); /script iframe id=fileTreeIframe class=ui-layout-center style=border:0px none #ff; src=file_tree.php border=0 width=100% scroll=auto/iframe and even included the normal script instaed of the .min.js file ... script type=text/javascript src=../scripts/jquery.layout.js/ script but sadly still now luck (screen shot is as before). There are no JS errors on the page. Do I have to give every element on my page a class name like you mention above, or should it be enough to only name the iframe? Thanks, - Dave
[jQuery] Re: Can JQuery solve the iframe height=100% problem?
If you are going to apply a specific iframe height via script... $('#myIframe').css({height:$(this).parent('td').height()}); ...You MUST bind an event to window.resize to *re-size* the iframe whenever the browser window is resized. /Kevin On Jan 30, 10:58 am, jquertil til...@gmail.com wrote: I think you're going down the wrong path - you shouldnt need to script anything to get a CSS attribute to work. usually when I run into this problem it is because somewhere in my document tree there is a parent lement that has no height attribute set. So if you have html someDiv anotherDiv table tr td iframe every one of the elements should have a parent with height set At least this is how I usually end up solving the dreaded height 100% problem whenever I come to it. Alternatively, you can try $('#myIframe').css({height:$(this).parent('td').height()});
[jQuery] Re: Optimize large DOM inserts
Mike, sorry if my post sounded like criticism - it was not intended that way. However the representation of the test pages is misleading - by accident I'm sure. The majority of the performance difference between the 2 pages is *solely* the difference between these 2 syntax $(#container).append( $(table/table).append( trtdHello/td/tr ) ); $(#container).append( tabletrtdHello/td/tr/table ); Or alternately... $(#container).html( tabletrtdHello/td/tr/table ); The syntax differences above are responsible for 85% of the speed difference between the pages - 7-times more than the loop-optimization is. Yet none of the points you repeated above are related to this issue. BOTH syntax only do a single DOM append - they just do it differently. And the 'loop' is irrelevant to this 85% difference - a simple string will still produce the same result. If you replace the code in your 'slow page' with the sample I gave in my last post - using .html( html ) - you'll see that the speed improves 7-fold -- with no change to the string-concatenation loop or anything else. Since this is 85% of the speed difference, this is proper way to comparison of the issues you raised. (You could also use $(table/table) in BOTH pages, but then the 'fast page' takes over 7 seconds!) So the loop-optimization produces only a 6-times speed improvement in IE - not 30-times. This.is still a significant improvement by itself, but I think it important to understand that $(table/table) is *really* the big culprit here. In fact, I think this is something that should be brought to the jQuery team's attention... Why is this syntax so slower? Ciao, /Kevin On Feb 7, 1:41 pm, Michael Geary m...@mg.to wrote: No need to shout. :-) I never claimed that these pages reflect only the difference between the array join and string concatenation. On the contrary, in my other message in this thread I listed all of the factors that make the code faster: * Explicit for loop (and the fastest kind of for loop) - no function callback for each row. * Builds an array of string fragments and then joins it, instead of string concatenation. * Builds the array with out[++o] = ... instead of the more obvious out.push(...) (faster in IE). * Instead of inserting a large number of sibling DOM elements (the TRs) together, inserts only a single DOM element (the TABLE). Now it is very useful to know how much of the performance improvement is due to each of these individual tricks, and thank you for doing that testing. My purpose in posting was to combine all of the optimizations to create the fastest possible code. -Mike From: Kevin Dalman These test pages DO NOT accurately compare the speed of array.join() VS string+= The biggest speed difference between the two is REALLY that one uses $(table/table) and one doesn't. If this is removed from the 'slow' page, the load-speed goes from 8.7 sec to 1.5 sec. This is still 6-times longer than the fast version - but no longer 30-times longer! Conversely, I changed the 'fast' page to use the append syntax (after removing table and tbody from the array): $('#container').append( $('table/table').append( out.join('') ) ); This changed the 'fast' load from 0.24 sec to 7.3 sec! So even the 'fast loop' page performed 30-times slower when the element-append method is used! There was another code difference as well - the fast page uses $ ('#container').html() and the slow-page $('#container').append(). However, since the container is empty, it does not cause any significant speed difference. So for a TRUE loop-speed comparison, the code for the 'slow version' should be: var html = 'tabletbody'; $.each( rows, function( iRow, row ) { html += 'trtd' + row.text + '/td/tr'; }); html += '/tbody/table'; $('#container').html( html ); This now uses the same html() syntax as the fast version, isolating the difference between the pages to ONLY the 2 loops. Now there is less than a 1.3 sec difference - instead of 8+ seconds. Now it becomes clear that the biggest lesson here is that append (table/table) is a much bigger problem than the loop code. This is important to know because it would apply even if there were NO loop at all! Thanks for bringing both these details to my attention. I do a lot of dynamic HTML generation, so it's helpful to know what to watch out for. /Kevin On Feb 5, 7:25 pm, Michael Geary m...@mg.to wrote: ...there is not much room for improvement left. You just know that when you say that, someone will come along with a 20x-40x improvement. ;-) http://mg.to/test/loop1.html http://mg.to/test/loop2.html Try them in IE, where the performance is the worst and matters the most. On my test machine, the first one runs about 6.3 seconds and the second one about 0.13 seconds. -Mike From: Ricardo Tomasi Concatenating into a string is already much faster than
[jQuery] Re: Reversing the SlideUp and SlideDown functions to slide from the bottom and not the top
Use the effects in jQuery-UI when you need more than basic slideUp/ slideDown. Using show hide with the appropriate options will allow you to slide in any direction. You also have a lot more effects to choose from then just 'slide' To open by sliding 'up', and close in reverse... $E.show( 'slide', {direction: 'up'} ); $E.hide( 'slide', {direction: 'up'} ); To use a 'drop' effect instead of 'slide'... $E.show( 'drop', {direction: 'up'} ); $E.hide( 'drop', {direction: 'up'} ); You can find details in the jQuery docs: http://docs.jquery.com/UI/Effects /Kevin On Jan 27, 8:07 pm, ryjohnson ry.john...@gmail.com wrote: I saw this was posted before, but there was never a solution posted. I want to use the Toggle function but have it slide up from the bottom of the div instead of the top, I have tried searching through all the plugins, and even tried writing my own but have had no luck. If there's anyone who can help me I would be extremely grateful.
[jQuery] Re: Can JQuery solve the iframe height=100% problem?
HI Dave, You can find all the info in the Layout documentation and examples, but here is a quick answer... The widget needs to 'find' the iframe. The default method is to give the element a ui-layout class, like this... iframe id=fileTreeIframe class=ui-layout-center ... OR, since the iframe has an ID, you can tell the widget to use that... script type=text/javascript $(document).ready(function() { $(body).layout({ closable: false , resizable: false , spacing_open: 0 , center_paneSelector: #fileTreeIframe }); }); /script /Kevin On Jan 27, 8:35 am, laredotorn...@zipmail.com laredotorn...@zipmail.com wrote: Hi Kevin, How do I apply this expansion to the iframe specifically? I included this on my page ... script type=text/javascript src=../scriptsjquery.layout.min.js/ script script type=text/javascript $(document).ready(function() { $(body).layout({ closable: false , resizable: false , spacing_open: 0 }); }); /script iframe id=fileTreeIframe style=border:0px none #ff; src=file_tree.php border=0 width=100% scroll=auto/iframe but still no love! ...http://screencast.com/t/aJxegNZmv - Dave On Jan 26, 12:27 pm, Kevin Dalman kevin.dal...@gmail.com wrote: Hi Dave, This plugin may be more than you need, but... The UI/Layout widget will automatically position and size an iframe (or other element) to fill the entire page, OR allow for a header, footer, or sidebars. The code and markup are dead-simple. Here is an example with a page-banner and an iframe. Everything is done for you, including eliminating the 'body scrollbar'... $(document).ready(function(){ $(body).layout({ closable: false , resizable: false , spacing_open: 0 }); }); DIV class=ui-layout-north [Banner here] /DIV IFRAME class=ui-layout-center src=myIframe.html ... That's it! I recommend setting an iframe width height for non- Javascript browsers, but it's not necessary for Layout. Plus you must set your preferred iframe options, like scrolling, border, padding, etc. Plug-in website:http://layout.jquery-dev.net Simple iframe demo:http://layout.jquery-dev.net/demos/frames.html The Layout website itself used iframe pages with a 'banner', like: http://layout.jquery-dev.net/discuss.html Hope this helps. /Kevin On Jan 26, 6:55 am, laredotorn...@zipmail.com laredotorn...@zipmail.com wrote: My iframe is also hard-coded. But here is what I get when I do console.log statements ... $('#fileTreeIframe').load( function() { var $ifbody = $(this).contents().find ( 'body' ); console.log($ifbody); // Outputs Object length=1 0=body prevObject=Object jquery=1.2.6 $ifbody.css( 'height','auto' ); console.log($ifbody.height()); // Outputs 0 $(this).height( $ifbody.height() ); }); Obviously the troubling thing here is that height is outputting zero. Can you provide the HTML that surrounds your hard-coded iframe? There must be something else I'm not setting in the CSS or HTML. Thanks, - Dave On Jan 25, 1:53 pm, dbzz j...@briskey.net wrote: i have the iframe hardcoded in the html. if you are adding it to the dom with js, it won't get the load event binding. you might try livequery or something like it. On Jan 25, 10:21 am, laredotorn...@zipmail.com laredotorn...@zipmail.com wrote: Hi dbzz, I tried the code you provided, but went from this ... http://screencast.com/t/W8lOtgKO to the iframe disappearing entirely ... http://screencast.com/t/jCTjOLhpeX I put your code in a $(document).ready() block (below). Are there any other modifications I should make to get it to display at 100%? $(document).ready(function() { $('#fileTreeIframe').load( function() { var $ifbody = $(this).contents().find ( 'body' ); $ifbody.css( 'height','auto' ); $(this).height( $ifbody.height() ); }); }); Thanks, - Dave- Hide quoted text - - Show quoted text -- Hide quoted text - - Show quoted text -- Hide quoted text - - Show quoted text -- Hide quoted text - - Show quoted text -
[jQuery] Re: Can jQuery calculate CSS Width/Height
Thanks Matt, but that does not work. As my example shows, the element may have a percentage width, or it could be 'auto' (which it would be if not specifically set). What I need is the 'pixel' measurement that would replicate its current size. In other words, if it currently is width:90%; and I replace it with width:985px;, the width *would not change* (assuming 985 is the pixel equivalent). On Jan 26, 3:03 pm, Matt matt.critch...@gmail.com wrote: $('#Test').css('width') ? On Jan 26, 11:46 am, Kevin Dalman kevin.dal...@gmail.com wrote: jQuery has innerHeight/Width and outerHeight/Width methods, but is there a method that can return a 'CSS Height/Width'. A CSS width is the width that would be applied via CSS to achieve a given 'outer width'. This value will differ depending on the box model and other older browser idiosyncracies. Here is an example... DIV#Test { width: 90%; height: auto; padding: 7px; margin: 11px; border: 3px solid #000; } DIV id=Test line1 BR line 2 BR line 3 /DIV Now I want to increase the DIV width height by 1-pixel. To do so, I need the current 'pixel width/height' that is equivent to its current size. AFAIK, $(#Test).innerWidth() will not address this. Is there another dimension method that can? I already have a custom function to calculate this, but I'm wondering if I am missing something in jQuery that would simplify my code? If not, I may suggest such a method for jQuery, but want to be sure it doesn't already exist! Does anyone have knowledge of this? /Kevin- Hide quoted text - - Show quoted text -
[jQuery] Can jQuery calculate CSS Width/Height
jQuery has innerHeight/Width and outerHeight/Width methods, but is there a method that can return a 'CSS Height/Width'. A CSS width is the width that would be applied via CSS to achieve a given 'outer width'. This value will differ depending on the box model and other older browser idiosyncracies. Here is an example... DIV#Test { width: 90%; height: auto; padding: 7px; margin: 11px; border: 3px solid #000; } DIV id=Test line1 BR line 2 BR line 3 /DIV Now I want to increase the DIV width height by 1-pixel. To do so, I need the current 'pixel width/height' that is equivent to its current size. AFAIK, $(#Test).innerWidth() will not address this. Is there another dimension method that can? I already have a custom function to calculate this, but I'm wondering if I am missing something in jQuery that would simplify my code? If not, I may suggest such a method for jQuery, but want to be sure it doesn't already exist! Does anyone have knowledge of this? /Kevin
[jQuery] Re: Can JQuery solve the iframe height=100% problem?
Hi Dave, This plugin may be more than you need, but... The UI/Layout widget will automatically position and size an iframe (or other element) to fill the entire page, OR allow for a header, footer, or sidebars. The code and markup are dead-simple. Here is an example with a page-banner and an iframe. Everything is done for you, including eliminating the 'body scrollbar'... $(document).ready(function(){ $(body).layout({ closable: false , resizable: false , spacing_open: 0 }); }); DIV class=ui-layout-north [Banner here] /DIV IFRAME class=ui-layout-center src=myIframe.html ... That's it! I recommend setting an iframe width height for non- Javascript browsers, but it's not necessary for Layout. Plus you must set your preferred iframe options, like scrolling, border, padding, etc. Plug-in website: http://layout.jquery-dev.net Simple iframe demo: http://layout.jquery-dev.net/demos/frames.html The Layout website itself used iframe pages with a 'banner', like: http://layout.jquery-dev.net/discuss.html Hope this helps. /Kevin On Jan 26, 6:55 am, laredotorn...@zipmail.com laredotorn...@zipmail.com wrote: My iframe is also hard-coded. But here is what I get when I do console.log statements ... $('#fileTreeIframe').load( function() { var $ifbody = $(this).contents().find ( 'body' ); console.log($ifbody); // Outputs Object length=1 0=body prevObject=Object jquery=1.2.6 $ifbody.css( 'height','auto' ); console.log($ifbody.height()); // Outputs 0 $(this).height( $ifbody.height() ); }); Obviously the troubling thing here is that height is outputting zero. Can you provide the HTML that surrounds your hard-coded iframe? There must be something else I'm not setting in the CSS or HTML. Thanks, - Dave On Jan 25, 1:53 pm, dbzz j...@briskey.net wrote: i have the iframe hardcoded in the html. if you are adding it to the dom with js, it won't get the load event binding. you might try livequery or something like it. On Jan 25, 10:21 am, laredotorn...@zipmail.com laredotorn...@zipmail.com wrote: Hi dbzz, I tried the code you provided, but went from this ... http://screencast.com/t/W8lOtgKO to the iframe disappearing entirely ... http://screencast.com/t/jCTjOLhpeX I put your code in a $(document).ready() block (below). Are there any other modifications I should make to get it to display at 100%? $(document).ready(function() { $('#fileTreeIframe').load( function() { var $ifbody = $(this).contents().find ( 'body' ); $ifbody.css( 'height','auto' ); $(this).height( $ifbody.height() ); }); }); Thanks, - Dave- Hide quoted text - - Show quoted text -- Hide quoted text - - Show quoted text -
[jQuery] Re: Can JQuery solve the iframe height=100% problem?
(Sorry if this is a duplicate post) Hi Dave, This plugin may be more than you need, but... The UI/Layout widget will automatically position and size an iframe (or other element) to fill the entire page, OR allow for a header, footer, or sidebars. The code and markup are dead-simple. Here is an example with a page-banner and an iframe. Everything is done for you, including eliminating the 'body scrollbar'... $(document).ready(function(){ $(body).layout({ closable: false , resizable: false , spacing_open: 0 }); }); DIV class=ui-layout-north [Banner here] /DIV IFRAME class=ui-layout-center src=myIframe.html ... That's it! I recommend setting an iframe width height for non- Javascript browsers, but it's not necessary for Layout. Plus you must set your preferred iframe options, like scrolling, border, padding, etc. Plug-in website: http://layout.jquery-dev.net Simple iframe demo: http://layout.jquery-dev.net/demos/frames.html The Layout website itself used iframe pages with a 'banner', like: http://layout.jquery-dev.net/discuss.html Hope this helps. /Kevin On Jan 24, 5:15 pm, laredotorn...@zipmail.com laredotorn...@zipmail.com wrote: Hi, I'm trying to get my iframe to occupy 100% of its parent block element. But the height=100% attribute in CSS isn't doing the trick. Here's my HTML td width=177 height=100% valign=top class=content- ruleiframe id=fileTreeIframe style=border:0px none #ff; src=file_tree.php border=0 width=100% scroll=auto/iframe/ td and the CSS ... iframe { display:block; height:100%; width:100%; border:none; } It doesn't look good right now --http://screencast.com/t/mIzGnUikC. Can JQuery help me make my iframe occupy 100% of its parent element? Thanks, - Dave