tomhoppe.com

Racing, Web Development, Photography, and Beer...Stuff that matters.

Saturday, March 22, 2008

Short weekend at Road Atlanta

So it was a short weekend, just the test day, but not in a "bad" way.

Started out the weekend great. Beautiful friday, car was ready, we setup the new EZUP's, and had a fairly pimpy pit area. Bolted on the Hoosiers, and it was time to go testing.

The first session I was bedding in the new BHP brakes, and just getting a feel for the car, nothing too special. I screwed up the DL-1 data acquisition by turning it off while still logging, so I got no data, and no info of how was fast I was going. The 2nd session, I kept the tires the same, but with the bedded in brakes and working DL-1, I put my head down and actually drove. I had a nice surprise as I came off the track and read the data, as I ran some damn good times. I realized my tire pressures were a bit off, and I felt the car could have been loosened up a touch, but it was an awesome second session ever. I really felt "in touch" with the car, and I'm really happy with the purchase. I'm certainly going to be keeping it around for a while!

The 3rd and 4th sessions, I bolted on the Hankooks to give them a shot. I ended up with the same lateral G's in the corners, but I felt that they didn't have as much braking grip as the Hoosiers. I locked up the brakes in 6 on the 2nd lap braking at the same spot as the Hoosiers, and didn't have confidence in them the rest of the session. I was about a second off the Hoosiers, but it was also later in the day, and I probably could have braked later if I tried. In the end, I think the tires are very close to the same. I'm going to end up choosing the Hoosiers for my tire though, as there seem to be a LOT of availability issues with the Hankooks. Even though they offer a more contingency then the Hoosier, what good is having a lot of "Hankook Dollars" if you can't use them because the tires aren't here. Also the trackside support we get from Appalachian Tire for Hoosiers is second to none.

So now we get to the end of my "weekend". I go to registration and come to find out, my comp license wasn't renewed properly. I renewed, but apparently it only got applied to my membership. Dammit! Its also Good Friday, so SCCA is closed and nothing can happen. I'm told that maybe tomorrow they can hunt down someone and get it resolved , but even if they do, I miss qualifying. I'm not about to pay a $600 entry fee to start 2 races from the back of 50 cars on purpose. Also, this fiasco just took the "fun" out of the whole night for me, so I said "fuck it, only 45 mins from the house, I'm going home".

Kind of a shame that SCCA sucks like this, but I guess I had some bad karma or some crap built up. Also looking at the ProIT times for today sucks even more, as I was over 2 seconds faster then the guy that won today. Oh well. Hopefully this won't cost me the season championship, as there are only 5 races left, and 6 count towards year-end. I'll have to have some REAL good luck to do great at the 5 that I'll run.

Labels: ,

Tuesday, March 18, 2008

addDomLoadEvent

Using window.onload for Javascript creates a crappy UI, as it waits for the entire page, including all CSS, JS, and images to load. I avoided as much as possible, but for some things in the day job, we needed to use it. The best example being that we only had access to JS in the head of the page, but needed to immediately client side add some code to the bottom of the page.

For this, we used addLoadEvent and waited till everything was done. Having been fed up with this, I did some a big of searching and found a solution from The Future of the Web, by Jesse Skinner. Jesse's script puts together a cross-browser way to wait for just the DOM to load, instead of all the images and text

This is easy for FF, Safari 3 Beta, and Opera, but a pain for IE and Safari 2. I changed his script slightly to be compatible with https and came up with the below code. Thanks Jesse!

.
addDOMLoadEvent = (function(){
    // create event function stack
    var load_events = [],safari_timer,done,exec,script;
 
 var init = function () {
            done = true;

            // kill the timer
            clearInterval(safari_timer);

            // execute each function in the stack in the order they were added
            while (exec = load_events.shift())
                exec();

            if (script) script.onreadystatechange = '';
        }

    return function (func) {
        // if the init function was already ran, just run this function now and stop
        if (done) return func();

        if (!load_events[0]) {
            // for Mozilla/Opera9
            if (document.addEventListener)
                document.addEventListener("DOMContentLoaded", init, false);
    
   /*@cc_on @*/
   /*@if (@_win32)
   var proto = "src='javascript:void(0)'";
   if (location.protocol == "https:") proto = "src=//0";
   document.write("<scr"+"ipt id=__ie_onload defer " + proto + "><\/scr"+"ipt>");
   var script = document.getElementById("__ie_onload");
   script.onreadystatechange = function() {
    if (this.readyState == "complete") {
     init()
    }
   };
   /*@end @*/

            if (/WebKit/i.test(navigator.userAgent)) { // sniff
                safari_timer = setInterval(function() {
                    if (/loaded|complete/.test(document.readyState))
                        init(); // call the onload handler
                }, 10);
            }

            old_onload = window.onload;
            window.onload = function() {
                init();
                if (old_onload) old_onload();
            };
        }

        load_events.push(func);
    }
})();

Labels: ,

Drag and drop Javascript

I found a great overview of drag and drop by Quirksmode today, and I wanted to make sure I didn't lose it or forget about it. Its a great explanation of drag and drop through JS with code examples, demos, and exactly how it does what. I only had a few minutes to look through it but it looks awesome.

Labels: ,

Dynamically adding CSS through Javascript

I found this little tip by accident while surfing the web to solve a different problem. Thanks to the Yahoo User Interface Blog for the solution!

When adding in a piece of HTML dynamically, what do you do with the styles for it? In the past, I usually included the styles in a global or page specific stylesheet where I knew the HTML would show up. The current snippet I was writing through, was going to add some code in random places throughout a 4000+ page website as well as some partner sites, so it needed to come with its own CSS. FF allows you nicely to just embed a <style> tag anywhere in a page with your styles and be done with it. IE and Safari, not so much.

What I found on the YUI Blog was the cssText property of the stylesheet property. This allows for a cross browser way for us to insert a string of css into a style element in the head. Beautiful! Just create your css as a string and pass it into the addCSS function below.

function addCss(cssCode) {
var styleElement = document.createElement("style");
  styleElement.type = "text/css";
  if (styleElement.styleSheet) {
    styleElement.styleSheet.cssText = cssCode;
  } else {
    styleElement.appendChild(document.createTextNode(cssCode));
  }
  document.getElementsByTagName("head")[0].appendChild(styleElement);
}

Labels: , ,

Monday, March 17, 2008

Mini Cooper!

So we got a Mini Cooper! Cathy wanted to cut out the almost $600/month payment on the 4Runner and something with better gas mileage. This guy was meant to be an ITB race car, but after looking at the costs, we decided to postpone that build, and have Cat daily drive it

So far its pretty cool. We took it in to get detailed as the interior was kinda messy. Going to get the plate for it tomorrow and Cat can start driving Friday.

Labels: , , ,

Monday, March 10, 2008

Cross Sub Domain Javascript (Ajax, Iframe, etc)

So we've been dealing with an issue at work with cross sub domain JS. Basically, JS believes that even a subdomain such as img.yourdomain.com is a different domain from www.yourdomain.com. Because of that, AJAX across pages from those two subdomains will not work. Also if you have an iframe from one to another, you will not be able to refence JS vars or functions back and forth.

After a good bit of digging, I discovered a way around this. This involves setting up an iframe html on one domain and then calling that iframe from the page on the other subdomain. You have to set the document.domain to the same thing on both the parent page and its iframe, in order for them to talk to each other.

document.domain = "yourdomain.com"

Once that is set, the two pages now think they are on the same domain.

For example, for pulling in text, setup your page on www.yourdomain.com and set document.domain to yourdomain.com. If you are trying to pull in an html page using Ajax from img.yourdomain.com, setup a page that, will become the iframe, to do the ajax pull. After that pull is complete set the document.domain to yourdomain.com. In your page on www. create an iframe which has the src set to your page on img. Since document.domain is set, any functions on the parent page are available to be called via the iframe. Lets say you want to put your newly "ajaxed" html into a div on the parent page, you can do that via "parent.getElementById('yourDivName').innerHTML = Response.Text".

If you are pulling in XML, you can setup the page/iframe relationship the same as above. That iframe will make the ajax call to the XML on img.yourdomain.com and do something with it, lets say turn it into an array. Once that is completed, set the document.domain on the iframe page. At this point, the parent page can access that array on its iframe via "iframeName.arrayName". Alternatively you can have an array read on the parent page for this information and pass it to the parent from the iframe via "parent.arrayName = iframeArray".

Labels: ,

Friday, March 7, 2008

Cross browser, self closing popup window

If you want to a cross browser way to have your popup self close

onsomething="window.opener=self;window.close();"

This works in most browsers, but doesn't work in FF 2.0 unless the window was in fact popped up. The window.opener=self fools most browsers, but FF is smarter :-)

I know its bad usability, but the context I used it in, was that a window was popping up a poll. On submitting that poll, the poll popup would close itself and the results on the opener were updated. The code for that is below. I put that code on the submit button onclick. I had to name the opener window in order for it to work. This way if there is an opener, it will try to target "jjCalendar" as the forms target. If that name doesn't exist, it will just open a new window.

onclick="if (window.opener){form.target='jjCalendar';}"

Labels: ,

Wednesday, March 5, 2008

House Update....

So along with all the race car fun, we've also started to really work on the house. When we moved in over 6 months ago, we knew the house was in need of repainting on the inside, but we just didn't realize how much of a pain that is.

So far, we've completed the master bedroom and the trim in the upstairs hallway, as well as the 2nd spare bedroom. Painting turns into a real hassle when you not only have to do 2 coats on the walls, but 3 coats (including primer) on the oak stained trim, and also paint the ceiling.

We got motivated the other day and realized that if we do the living room, and lose the TV for a while in doing so, we'll get a lot more done on the house. Otherwise, its just too easy to get lost in front of the 50" big screen.

I'll have some in progress pics of the living room tonight. We ran the speaker and subwoofer wire from a box behind the TV, under the crawlspace, and into the rear walls. Looks very pro. I'm looking forward to hooking the surround up and watching a movie!

Labels: ,

Race Car Update

A little update on the race car. Its coming along together fairly well.

Here are the things I've done so far over the "winter" to get it ready.

  • The right front brake line was busted, so I installed 4 new ones. Also new pads from BHP Brakes and fresh rotors all around.
  • New harness as the one I bought with the car was expired
  • Got the seat mounted up closer.
  • Installed the quick release for the steering wheel
  • Wired up the DL1 data aq to the ignition, so it will turn on with the key
  • Got the right side net installed. Figured I'd get one as they seem to up the safety
  • Painted/cleaned up the interior. Touched up some rock spots and rough patches. Looks like new
  • Nut and bolted the car. Went through and made sure nothing will fall off
  • Switched to 800F/1200R springs, and sent to Koni 28s off to get inspected and revalved
  • Flushed all the fluids: oil/brakes/trans/radiator

Now the car is sitting around on jackstands and waiting for me to borrow some shocks and springs to take it to Maaco to get the paint finished. Also need to get some stickers from KC at http://www.rallydecals.com to complete the look.

I'm excited as hell to start the season on March 21st at Road Atlanta!

Some pictures of the nice finished interior, and rough looking (for now) exterior.

Labels: , ,

Tuesday, March 4, 2008

So now that I've got a "blog"

Now that I have a "blog" I guess I'll start posting a little bit of stuff here.

Primarily, I'm going to use this to keep track of my racing addiction, but I also want to use this to retain some of the neat code snippets and other info that I learn over time.

Most recently, I started playing around and discovering jQuery. What a sweet library. Its fairly compact, and as they imply, it makes DOM manipulation very easy. I wrote a few scripts of my own for JS motion and fading, but I realized that I'm trying to reinvent the wheel here and decided to use jQuery's instead.

I also happened upon thickbox (Thanks Corey!) and really liked it. It does basically what lightbox does, but less code and less "crap". There are a few features of lightbox that I liked, so I wrote my own versions of them on top of thickbox. I'm going to use my version of it on here to revamp my very poorly setup photo gallery, and also through my blog for images.

Labels: ,