Oct 17 2010

JavaScript innerHTML v. outerHTML / DOM Engine Epic Fails

I was messing around with  javascript today and I recognized one major issue when updating the innerHTML of an object versus the outerHTML.  Namely, that objects updated with HTML content via outerHTML do not allow subsequent access to interior objects within that HTML content.  The DOM engine (at least in Firefox) will not recognize the interior elements when outerHTML is used, but WILL if innerHTML is used.

The Scenario

Suppose you have just created a div object dynamically in javascript.  In other words, you’ve created a div object in code versus its existence in the actual HTML document.  For example, this code:

var o = document.createElement(“div”);

Would create this type of HTML:

<div></div>

Next, imagine that you have a string of HTML that you would like to make up this <div> element.  For the sake of argument, pretend you have a variable ‘html’ and this contains the HTML you would like to make up everything of your new dynamically created <div> object including the tag itself:

var html = “<div id=’mydiv’ a=’1′ b=’2′><img src=’foo.jpg border=’0′ width=’5′ height=’5′ /></div>”;

At this point one may be tempted to make a call such as this:

o.innerHTML = html; // do not actually do this

This would be wrong to do, however, since that would result in the following HTML being created for o:

<div><div id=’mydiv’ a=’1′ b=’2′><img id=’myimg’ src=’foo.jpg border=’0′ width=’5′ height=’5′ /></div></div>

The better option (at least logically) would be to update the outerHTML of o which is supposed to replace the entire HTML contents of o including the tag itself:

o.outerHTML = html; // this should work… but

This does actually work, and and the DOM engine actually updates the entire o object with the appropriate content.  If that’s all you need, then you’re set.

But, there is a problem if you need to do more… If you need to access your <img> object programmatically a few lines after you’ve created o (note the <img> object is now  part of the <div>’s content) then you’re shit out of luck.  Any attempts to do the following will return a null object:

var i = document.getElementById(“myimg”);  // if you’ve used outerHTML the DOM engine won’t know ‘myimg’ exists yet

If you try to do this, after using outerHTML, the DOM engine will not recognize ‘myimg’ as having been created yet.  The DOM engine WILL, however, recognize ‘myimg’ as having been created if you use innerHTML!  So what gives!?

Whatever the problem is, my solution was to create my <div> object programmatically, have my HTML content just be the <img> tag itself, and then to update the innerHTML as the image.  THEN you need to programmatically update the attributes of the <div> object.  It’s a pain, I know, especially if you’ve streamed HTML content from an AJAX call, etc.  Anyway, a final solution would be something like this:

var html = “<img src=’foo.jpg border=’0′ width=’5′ height=’5′ />”;
var o = document.createElement(“div”);
o.innerHTML = html;
o.setAttribute(“a”, “1″);
o.setAttribute(“b”, “2″);
o.id = “mydiv”;
document.getElementById(“myimg”).src=”bar.jpg”;

I spent a good two hours dissecting the innards of Firefox’s DOM and just came up with, “Why?”  Anyway, I hope this helps people.


Jun 6 2009

Thank God

I’ve been debating what to write for my next blog post for some time.  There have been a few inarticulate ideas kicking around, but nothing inspiring enough to get me in front of the computer.  Then, this morning, it hit me.  I’m thankful for so many things in my life — not in a Thanksgiving-I-am-thankful-for sort of way — but sincerely thankful that certain things in my life are the way they are.  Here is a list (open to tweaking) in no particular order.

Thank God…

  1. I’m not married.
  2. I don’t have a kid.
  3. I have a mom and dad who love me.
  4. I have great friends.
  5. I’m a male.
  6. I’m intelligent.
  7. I’m creative.
  8. I’m my own boss.
  9. I went to college and graduated in 4 years.
  10. I’m going to law school.
  11. I’ve been to Ireland.
  12. I’ve loved at least one person in my life.
  13. I have my awesome car.
  14. I’m not a virgin.
  15. I have no disability.
  16. I am able to run.
  17. I am healthy.
  18. I make/have enough money to pay my bills even in this economy.
  19. Obama is our president.
  20. I have a sense of humor.
  21. I got through a difficult time with alcohol.
  22. I’m not a religious fanatic (not that religion is bad).
  23. I can keep a conversation going.
  24. My sarcasm sometimes goes unnoticed.
  25. I’m artistic.
  26. I can solve a Rubik’s cube.
  27. I can still take the derivative of an equation.
  28. I look really good with a tan.
  29. I don’t take shit from people.
  30. For computers and the entire IT industry.
  31. For movies and the entire movie industry (minus the MPAA — suck my balls)

Jan 10 2009

The iPhone’s best app that isn’t really an app

My life is owned by Google.  Seriously.  I use Gmail as my only email program and their calendar as my only calendar.  I’ve also recently decided to use their documents software instead of Word/Excel.  Having Google maintain my digital life has made things a lot easier.

So when I got my new iPhone a few weeks ago I was eager to setup my Gmail account.  Just as I expected it was painless and easy.

Then I moved on to my calendar which I thought would be just as easy.  Unfortunately it wasn’t.  I was hoping that the iPhone would support a pull architecture for iCal synchronization — basically allowing me to tell the iPhone that it’s time to sync between the iPhone and my Google calendar.  A lot of calendar software packages support the iCal standard, and Google calendar allows you to export your calendar in this format.  Naturally I thought this would be supported on the iPhone, but it wasn’t.

I then searched online to find what I was looking for.  I found a syncing program that works with the iCal standard, but only with the iCalendar application in OSX.  Since I run XP on my machine this wasn’t any help.  I then found an application that said it could do what I needed, called NemuSync, but it required that I jailbreak my iPhone — something I wasn’t looking to do.

Just as I was about to give up I found the answer to all of my problems.  It was called NuevaSync and it has been the best thing I’ve ever setup for my iPhone.  NuevaSync is free, and allows you to setup an account with them that bridges information on your iPhone with Google’s calendar without ever having to install an app.  On a more technical level, they offer a Microsoft Exchange layer to push syncing between your iPhone and Google’s calendar.

Because Exchange is a push architecture you never have to worry about activating a sync request — it’s done automatically when you add a new event in your calendar either on your iPhone or on your Calendar webpage.  So let’s say you’re on the road and enter an event on your iPhone.  By the time you get home and log on to your Google calendar it will already be there.  NuevaSync is a real-time ongoing syncing of your iPhone calendar and Google calendar.

I was so happy when I found this out that I emailed their staff to thank them for the service.  They could easily charge $99 a year for this service and I would have paid.  It’s so seamless and translucent that I literally had to write a blog article singing its praises.

If you’re an iPhone person and use Google calendar you must setup an account today.


Dec 11 2008

Slim & Jumbo’s Goes Christmas

I recently updated a client website to be more festive for the holidays.  I can’t stop laughing at how over the top, and awesome, it is.  Check it out by visiting Slim & Jumbo’s website.


Nov 23 2008

All Your Web Are Belong To Us

I ran across this video while on http://www.worksmart-emarketing.com/ and thought it was awesome.  Enjoy.


Nov 21 2008

New Google Search Features are Awesome!

If you have a Gmail/Google account you MUST go login now.  Then open another window and do a normal Google search.  See anything different in the result listing?

There are a couple of new icons along each search result that allow YOU to vote/score/rank results higher/lower, remove results that you’ll never care about or need, and to comment on results.  You can also add a link that you always want to appear for the phrase you searched for.  Want “cats.com” to come up as your second result when you search for dogs?  You can make it happen now!

AWESOME!

I have thought for a long time how great it would be to simply remove a result listing you know you’ll never need, but they go even further.  These features make it easy to find repetitive information very quickly and to tailor it to your needs.

You also know Google’s taking all that feedback and making their system even smarter.  If a thousand people hide a result, or a thousand people promote a result to a higher rank, that will have an effect on future searches for everyone.  It’s ingenious!

While the commenting feature is very much like the old “Note This” feature which was bulky and mostly unusable, the commenting feature is super easy and intuitive.  I WISH they kept the “Note This” feature, however, for personal use so you can maintain individual notes on a website that don’t become public.

Anyway, I felt the need to let more people know about it because it’s slick.  And of course Google integrate these new features in an unobtrusive way — they’re known for that.

Kudos to Google!


Nov 12 2008

Up all night…

It’s morning and I’ve been up all night working on a website.  The large Dunkin’ Donuts coffee I drank a few hours ago, and the Coke I chugged within the last hour has left me wide awake.  Yet the sight of daybreak is a good cue that maybe I should try and get a few hours of sleep before “waking up.”

I’m really glad I didn’t buy one of those 5 hour energy drinks… I’m not even sure if those work.

Anyway, good night (err… morning)!

AG


Nov 10 2008

Facebook Profile Image Hacking

Any savvy web developer who uses Facebook knows that you can pretty easily hack the image URL from the website by replacing the “s” (or sometimes “t”) in front of the image name with an “n” to get the full sized image.  For example http://profile.ak.facebook.com/v230/494/97/s58600109_2901.jpg gives a medium sized version of my profile pic whereas http://profile.ak.facebook.com/v230/494/97/n58600109_2901.jpg gives the actual size.

The trick is handy when you come across a person who’s not a friend, but you still want to view their full sized photo.

The problem is, of course, that this can be construed as a privacy violation since you’re circumventing the intended protection Facebook affords its members when they limit profile viewing.  I’m not going to debate what should, and should not, be allowed on the site — I am, however, going to make a simple suggestion on how Facebook can improve their profile image viewing, and prevent this type of hack.

The problem right now (unless I’m greatly mistaken and some Facebook developer can correct me) is that everytime we update our profile pic 3 versions are saved: a thumb, a small and a normal — T, S and N respecitvely.  That means there are 3 seperate jpg images on their servers which can be accessed by anyone with the internet who knows their URL.  As stated above this creates a concern for privacy.  The fact that Facebook creates 3 seperate images isn’t a problem; in fact they probably do this to rely on speed boosts from caching.  It’s not even a problem that they’re all named the same thing except for a one letter difference; although changing the name of each file would solve the problem.  This, however, would create a great deal of confusion if a human ever had to deal with the images, and could potentially require another 2 columns in a database.  The problem really boils down to whether the URL is hidden from hackers to prevent possible manipulation.

Truthfully, there are only 2 pieces of information Facebook needs to know in order to render a profile pic.  They are 1) the user id and 2) what flavor of the profile pic they need to render (ie. thumb, small or normal).  We also know that PHP can stream jpg image data as it’s script output.  So it’s then totally reasonable to propose that we can then use a URL for an image such: profilePicRenderer.php?profile=58600109&flavor=s

The profilePicRenderer.php page would then interpret this and stream the appropriate profile pic to the page as a jpg image.  If someone were to look at the source code of the rendered HTML they’d only see the profilePicRenderer.php URL.  Furthermore, since Facebook would be hitting their server (which they’d have to do anyway to return a jpg image in their current system) they’d have the added benefit of being able to do some privacy checking.  They can ask and answer the following: Is a person logged in who is trying to stream this jpg?  Is a person a friend of this person?  Do they have rights to view this image?  All the important privacy checks could be accounted for in a few CPU processing cycles.  True, performance might be hit, but the images would still be cached once the user “suffers” the first time.  A decent price to pay for peace of mind.

The only problem I could foresee is a caching issue.  Right now evertyime a user changes their profile pic the image name changes.  This in turn tells the browser to immediately download the new image and store that in the cache as well.  I think, note that I’m not sure, that we could get around this by always including a special string in our profilePicRenderer.php request which could look something like this: profilePicRenderer.php?profile=58600109&flavor=s&cacheTrick=23fj23kjf

The cacheTrick variable would be maintained on the server, and associated with the profile pic, but not the same name as the profile pic itself (since this is what we’re trying to avoid!).  This way each time a profile pic was changed by a user it would also create a new cacheTrick variable and this could be used to signal the browser that the cached image is old.


Nov 7 2008

HTML Form Tags

The <form> tag in HTML is used to wrap data elements (textboxes, checkboxes, radio buttons, etc.) on a webpage to prepare them for submission to the server. Nearly every form you fill out on a website uses a tag of some sort. But there’s one cosmetic issue that plagues tags, they don’t ever display in true inline!

When you wrap data elements with a tag you will probably see that there is additional whitespace above and below the and </form> tags when you’re viewing the actual website. This is because the <form> tag doesn’t respect true inline styling when it is rendered (or rather the browser doesn’t treat tags with true inline styling). This can sometimes be annoying when you’re attempting to layout a precise spacing scheme for a website you’re working on.

The best solution is to include a style attribute in the tag specifying a display element as inline. So you may want to do this:

<form action=”test.php” method=”post” style=”display:inline”>

form elements here

</form>

This will get around the cosmetic issue of the extra whitespace on both sides, and gives the developer ultimate control in spacing choices.


Jun 7 2007

Google Image Search Face Hack

Doing a Google image search? Want to only show images with faces in them?

Add “&imgtype=face” to the end of your URL and hit enter. 

The results will now be filtered by images only containing faces.