Aug
15
2010
I was looking into binary search functions lately and decided to comment this JavaScript binary search function I found (original is at http://www.dweebd.com/javascript/binary-search-an-array-in-javascript/) to help ensure that I had a good grasp on everything that was going on in it. Thought it might be useful for others, so I expanded my comments (read: commented the holy hell out of it) for posting here. Enjoy!
<script type="text/javascript">
// Custom sort comparator
function sortNumericAscending(a, b) {
return a - b;
}
// Based off of http://www.dweebd.com/javascript/binary-search-an-array-in-javascript/
// Extend the array object to include a new function to perform a binary search.
// Since a binary search requires the array to be sorted, we can optionally
// pass in the name of the function to do the comparison as well as the value to find.
Array.prototype.binarySearch = function binarySearch(valueToFind, comparator) {
var
// The lower bound of the array, initally set to the true lower bound.
lowerBound = 0,
// The upper bound of the array, initally set to the true upper bound.
upperBound = this.length - 1,
// Stores the median index of the array.
medianIndex,
// Stores the result after we compare the value to find
// with the value at the current median index of the array.
comparisonResult;
// As the loop progresses, the lower and upper bounds
// will halve upon each iteration and eventually meet.
while (lowerBound <= upperBound) {
// Determine and store the median index.
medianIndex = parseInt((lowerBound + upperBound) / 2, 10);
// Check to see if a comparator was passed in.
if (comparator == null) {
// If there was no comparator to use, then use the default comparator.
if (this[medianIndex] == valueToFind) {
// If the comparison shows that the value that's at the current median index of the array
// is equal to the value to find then set the comparison result to zero.
comparisonResult = 0;
}
else {
// If the comparison shows that the value that's at the current median index of the array
// is less than the value to find then set the comparison result to one. If the comparison
// shows that the median array value is greater than the value to find, then set the
// comparison result to negative one.
comparisonResult = (this[medianIndex] < valueToFind) ? 1 : -1;
}
}
else {
// If a comparator was supplied, then use it to determine
// if the value is greater, lesser, or equal to the value to find.
// It is presumed that this comparator is the same that was used to sort the array
comparisonResult = comparator(this[medianIndex], valueToFind);
}
// If the comparison shows that the value that's at the current median index of the array
// is less than the value to find then we know we'll need to look at the top half of this array.
if (comparisonResult < 0) {
// Set the new lower bound to just above the current median index
// so that the next pass will only look at the top half of this array.
lowerBound = medianIndex + 1;
// Since the comparison result did not show that the values were equal
// and we've set up the new bounds of the array to search on next,
// then just disregard the rest of this iteration of the loop and contine with the next iteration.
continue;
}
// If the comparison shows that the value at the current median index of the array
// is greater than the value to find then we know we'll need to look at the bottom half of this array.
if (comparisonResult > 0) {
// Set the new lower bound to just below the current median index
// so that the next pass will only look at the bottom half of this array.
upperBound = medianIndex - 1;
// Since the comparison result did not show that the values were equal
// and we've set up the new bounds of the array to search on next,
// then just disregard the rest of this iteration of the loop and contine with the next iteration.
continue;
}
// We can only get to this point if the comparison result was equal
// so we can return the value found at the last median index of the array.
return this[medianIndex];
}
// If we searched the entire array and didn't locate
// the value to find then just return null.
return null;
};
// Testing the implementation.
var newArray = [0, 3, 10, 4, 1, 2];
// Default sort comparator.
newArray.sort(); // default sort is alphanumeric
document.write("newArray.binarySearch(3)=" + newArray.binarySearch(3));
// Custom sort comparator.
newArray.sort(sortNumericAscending);
document.write("newArray.binarySearch(3, sortNumericAscending)=" + newArray.binarySearch(3, sortNumericAscending));
</script>
I still think there’s a good chance I missed something so if you find anything amiss, please let me know so I can fix.
1 comment | tags: code | posted in JavaScript
Jul
9
2010
This is simple and I’m sure that many have done this (or something similar) already, but I recently had to go through a website and retro-fit all textboxes with jQuery to automatically remove the “self label” value when the user clicks in the box. Instead of doing all of these individually, I came up with this brief jQuery script to add and remove the labels according to the title attribute (which should be there in lieu of a real label for accessibility). Maybe this will be useful to someone else, but at a minimum, I’ll know where to go to grab this again if I need it. =)
$(document).ready(function () {
InitSelfLabelTextboxes();
});
// Sets textboxes to automatically add (and remove) a 'label' text value based on the title attribute.
// Note that the value should still be present initially so people without JS still can see a label.
function InitSelfLabelTextboxes() {
$('input:text').each(function () {
var thisBox = $(this);
var titleVal = thisBox.attr('title');
if (titleVal.length > 0) {
if (thisBox.val().length == 0) thisBox.val(titleVal);
thisBox.focus(function () {
var currentVal = thisBox.val();
if (currentVal == titleVal) thisBox.val('');
});
thisBox.blur(function () {
var currentVal = thisBox.val();
if (currentVal.length == 0) thisBox.val(titleVal);
});
}
});
}
2 comments | tags: Accessibility, jquery, wcag | posted in JavaScript, jquery
Feb
17
2010
As everyone expected, browsing the web on our mobile devices has become steadily more prominent. The browsers available on our phones have become more robust and feel more like desktop browsers, but you know something? They’re not.
Ooh, that’s too rich for my browser
I increasingly find myself using the Opera browser on my HTC Fuze to get stuff done or check things out. Even doing things other than browsing the web will get me there eventually by clicking a link in email or a Twitter update. (That’s also why I think that the Xbox should have a browser, but that’s another story.) Problem is (I think), more and more sites are relying heavily on advanced JavaScript using frameworks like jQuery (which I love btw). I have been continually frustrated trying to view something via Opera mobile and it either runs painfully slow (usually due to some form of AJAX) or it simply does not work. There’s nothing worse than seeing an interesting updated via Twitter, click on the link, and page is loading… loading… You see the infamous spinning spinner graphic, and… nothing. Not going anywhere. Damn.
I think this also explains the prominence of mobile apps as opposed to better-working sites on mobile. I’m glad to see that hugely popular sites like Twitter and Facebook have mobile sites, but they aren’t exactly delivering a rich web experience. Not to mention they aren’t the default if you go to the site on your phone. (You have to know to put “m.facebook.com” into the address bar; I’ll admit, though, that this could be due to mobile browser delivering deceptive user-agent values to the site.) Suffice to say, mobile sites are too stripped-down and desktop sites are too heavy; there seems to be nothing in-between.
Put your website on a diet
Enter Facebook Lite. Could this be the answer?
Site developers need to keep in mind that users may be viewing their “desktop” site via a mobile browser. I think that developing a “lite” version and placing a prominent link to allow users to switch between the two is probably the best answer. At least, that’s the best I can come up with now…
5 comments | tags: Usability | posted in Mobile Web
Feb
5
2010
“This solution requires that you use Internet Explorer. If this page is open in any other Web browser, open it in Internet Explorer.”
This was just too crazy not to post. Got this message from a page on the Symantec site after getting an error from the Symantec Endpoint Protection software we have at the office. What is this, 1990? This harkens back to the days of messages like “This site is optimized for IE at 800×600″. Good riddance to those days!
It did appear that the page worked fine in my Firefox browser, but seriously, WTF? That’s a giant website fail in my book. Inexcusable especially for a big corporation. Wow. Just wow.
6 comments | posted in WTF
Feb
4
2010
I’ve been working on my version of a CSS “reset” file lately trying to achieve a gentler reset than the big ones out there. Specifically, I don’t want to reset everything all the way to zero; I’d just like better control over what those defaults end up being (cross-browser of course).
So, I’ve got almost everything done on my reset when I get to the point of wanting to set the base body font size in the CSS. So, as I have done in the past, I looked to the internet for guidance on what the best practice is. So the internet tells me:
- Set the base body font size to a percentage in the CSS to alleviate Internet Explorer text sizing issues. (yup, knew that already)
- Always use “em” units for your subsequent font sizing. (of course – been doing that for years)
- Your base font size percentage should be… (!)
What? There’s no standard out there among the CSS gurus as to what that base font value should be? I was surprised.
So, time to do my own investigating to determine what my base font size should be. Here’s a list of websites that I checked and their base body font sizes:
Curiously, Twitter, Facebook and Yahoo! all use pixels as their base font size:
- Twitter (0.75em, but overridden to 11px almost everywhere)
- Facebook (11px)
- Yahoo! (13px) use px as the base font size.
I’ve seen the 62.5% value often as a means to set the default browser text size to 1em = 10px. Obviously for those who want to set their fonts in pixel sizes, but know they can’t do it directly. Seems that it would work pretty well. For a long time now, I’ve been using the base font size of 76% as based off of this post by Owen Briggs. Strange that there isn’t more of a consensus among the CSS elite, but I think I’ll stick with Owen’s standard. I mean, anyone who took the trouble to take 264 happy little screenshots on the subject of CSS typography deserves some serious recognition.
I still think that the default sizes for the headings could use some tweaking, but I have a CSS reset demo page as well as having the demo pages available in a zip file.
3 comments | tags: browsers, CSS, reset, typography | posted in Browser Compatibility, CSS, Web Standards