Browser-side Isomorphic Javascript

Jun 3, 2015

With the advent of Node, there has been discussion of isomorphic Javascript.  The general idea behind this is code written for server-side purposes can also be used for UI purposes. The problem with this notion is, it doesn’t account for browser UI/middleware considerations in the browser.

As client-side development progresses and software as a service (SaaS) and single-page applications (SPAs) become more common, UI developers continue to program based on user interactions with the view layer and the underlying logic gets woven into the UI code, littering data logic with DOM related code, which tightly couples the UI code to the data code, creating complicated, unmanageable software.

What ends up happening is code gets duplicated to serve the same purpose, and then the code gets out of sync. Bugs creep in and pretty soon the software starts getting cracks in the facade. Even frameworks that are intended to avoid this kind of behavior, like Angular, are built in a way that allows for divergent code.  Let’s have a look at a snipped of code that could diverge quite quickly, in Angular.


<!-- This is in the view somewhere -->
<input type="text" id="weird-id" ng-required="true" ng-pattern="^abc\d{3,5}$" />


//This is data validation somewhere before submission
function validateId(value){
    return value.match(/^abc\d{3,5}$/) !== null;
}

Obviously there was some cutting and pasting that went on here.

What happens when the requirements are changed? Will this developer remember that the regex needs to be changed in two locations? Will this developer even still be working for the same company?

Even if this is remembered once, it is almost guaranteed to be forgotten about. This is especially heinous because there are clearly two different concerns being served here. One place the UI is handling input validation so the user can get immediate feedback, the other is likely to be related to handling validation before data is sent to a service somewhere.

It is not obvious even from this simple example that DRY could be applied here. Of course it can, but the solution is not completely obvious. Since this is not a post about Angular validation, I will leave the Angular-specific details as an exercise for the reader. Instead, let’s take a look at a more general solution.

Obviously the script handling the validation is pretty general so we’re probably safe to start there. Let’s keep it. That means all we really need is validation for the UI. Let’s have a look at something that would give us the behavior we want:

function attachIdValidator(element){
    element.addEventListener('change', function(event){
        var inputValue = element.value,
            validValue = validateId(inputValue),
            elementHasError = element.classList.contains('error');

        if(!validValue && !elementHasError) {
            element.classList.add('error');
        } else if(validValue) {
            element.classList.remove('error');
        }
    });
}

Now our element has the same validation attached that our outgoing data will use to ensure everything is on the up and up. Honestly, though, this is a fine first pass, but you and I both know this isn’t the only validator you are going to use to handle your user inputs. Why don’t we do a little more cleanup and write something we can really get some mileage out of.

function setErrorState(element, validInput){
    if(!validInput && element.classList.contains('error'){
        element.classList.add('error');
    } else if(validInput){
        element.classList.remove('error');
    }
}

function attachValidator(element, validator){
    element.addEventListener('change', function(event){
        var inputValue = element.value,
            validValue = validator(inputValue);

        setErrorState(element, validValue);
    });
}

//Applying our new logic would look like this:
attachValidator(document.getElementById('weird-id'), validateId);

Now, that’s what I call DRY code. Now we have taken one piece of logic, isolated it and applied it in the places we need it. Sure it took a little extra code to get us there, but you can see the difference it makes. Now if someone comes along later and says “gosh, it would be great if the ID values could start with efg instead of abc,” anyone who is currently working with the code can go and update the validation logic and it will update the requirements everywhere.

What’s even better is, now we have a UI validator that we can apply any kind of validation logic and not need to continue writing and rewriting UI logic to handle all of that mess. Extra special bonus is this entire thing is written in vanilla Javascript, so it’s extra small, tight and as fast as we could make it.

When you do this in your code, go ahead and pat yourself on the back. You deserve it.

In the end, what people are really talking about when they say isomorphism, what they really mean is “don’t repeat yourself.” When that’s the goal, then isomorphism doesn’t have to be limited to client/server applications. Take the lesson and run with it. Make your code better and your users (and your boss) happier. Let’s use isomorphic code to make the world a better place.

Everyday Functional Programming in Javascript

May 27, 2015

I gave a talk at the beginning of the year about functional programming. Someone asked “can you do functional programming little by little or do you have to do it all, all the time?”

When I answered, I felt I didn’t give them the answer they deserved or that I could have given.  This is my answer. Yes, you can do a little or a lot. You can write functional code little by little and solve things without changing your life and your career.  You can write programs that aren’t academic or theoretical. You can write everyday functional code.

So what does everyday functional programming look like?  Unless you work somewhere that you write in Lisp, Clojure, ML, F#, Haskell, etc, then it doesn’t look anything like the high-brow academic tutorials you see most often.  You don’t talk in monads and exclusively pure functions.  It’s not an ivory tower. At best you are a warrior acolyte of the functional cloth.

State is a thing.

So, when you are working in functional languages, state is a difficult knot to untie. Since values are immutable and shared state is the work of something unholy and evil, handling things like state machines becomes a chore. Who wants to go to work and think “today is the day I have to tackle the beast. I hate today?”

Not. Me. Thanks.

Sometimes you really need state. You actually need to know what happened and what is coming.  Sometimes you want something that you can mutate and something that is transitory, but still in memory. Hi to all of you Haskellians, yes I know there are other ways of doing that kind of monkey business, but I just don’t wanna. It looks a little too much like work and a little too little like fun.

First class functions are for everyone.

Now that I got the state stuff out of the way that OO does just so well, let’s talk about what functional workflow looks like in my happy little world. Arguably the thing I feel differentiates functional programming from programming that isn’t is the beautiful higher order function.

I mean, it’s magic right? Higher order functions, I mean look at this:

    function add(a, b){ return a + b; }

    function addTheseNumbers(numberArray){
         return numberArray.reduce(add, 0);
    }

That’s what I am talking about. Functions that take functions as arguments. It’s all kinds of awesome, right?

Okay, in all seriousness, the real awesome comes when you start blending pure functions in with your stateful code and moving all of that stateless logic into something that makes more sense for what you are trying to accomplish. Let’s have a look at one of my all time favorite constructs. It’s what makes my world go ‘round: either.

Watch this.

    //What life was like before
    function doStuff(someData){
        var someProperty;

        if(!!someData){
            if(!!someData.someSubData){
                someProperty = someData.someSubData.someProperty;
            }
        } else {
            someProperty = 'default value';
        }
        //What the crap is this???
    }

    //What life is like now
    function doStuff(someData){
        var defaultData = {
                someSubData:{ someProperty: 'defaultValue }
            },
            someProperty = either(defaultData, someData).someProperty;
        //Hooray! Now we can set a default
    }

All of this because, honestly, who needs all the conditionals? Do you care about the conditional logic or do you just care about the data? Personally, I think conditional logic is the devil. I mean, honestly, the worst bugs and the most  difficult mess comes from all of these horrible, horrible conditionals. Let’s cut to the chase and just make it right.

Here’s something even more amazing, ready for this? ARE YOU READY? Yeah, you’re ready. ```javascript //I mean, it MIGHT be an array or it might just be null. Who knows, right? function doFunctionalStuff(myArrayMaybe){ return either([], myArrayMaybe).filter(somePredicate) .map(transformStuff) .reduce(reducerFunction); }

I mean, DUDE, you can skip all of the worrying. If something null happens, you just pretend it never existed and everything turns out just fine. With just one new function, all of a sudden you get  all of the functional goodness that Javascript has to offer.

What does either look like?
```javascript    function either(defaultValue, maybeValue){
        return !!maybeValue ? maybeValue : defaultValue;
    }

That’s it. It’s the gift that keeps on giving.

At the end of the day, what I am really getting at is this: everyday functional programming is all about cutting to the core of what you want to do and eliminating the conditions, unnecessary shared state and error prone code so you can keep your sanity. It’s not about all pure functions all the time. It’s not always about monads and currying. It’s about the little things that make a big difference so you can do your best work.

Callbacks, callbacks, callbacks!

May 18, 2015

Waiter,

There’s a promise in my spaghetti.


So, dig, I like promises.  People I work with and people I talk to think I don’t but I really, genuinely do. Promises (in a computer science way) are just plain awesome.  Here’s the idea:

Program module: Yo, system, I want to do something and I want it to happen on another thread so I can keep doing stuff.

System: Okay. I’m doing it. Here’s an IOU, let me know when you are ready to collect.

Program module: Okay, I need that stuff now.

System: I’m not ready yet. Please hold.

Program module: okay, I’ll wait.

System: Okay, I’m done now, here’s the stuff you wanted.

Program module: Cool, thanks. Game on!

What happened here?  Basically a promise was issued and the program continued running with an async process continued in the background. When the program was ready for the data, but the data wasn’t ready, the promise became a blocking operation. Once the system was done, it delivered what was needed and the block was released.  This is awesome because you don’t end up with something that blocks up front. This can be annoying when you need something to appear completely transparent and non-blocking.  Such is the way of the world.

Javascript promises are, let’s just say… different. Everyone likes to say “oh they stop callback hell! They are the magic bullet!” Incorrect!

Promises are just syntactic sugar over a callback structure, which basically seems like a big fat lie to me. I don’t like the idea that I am “getting rid of callbacks” and really all I am doing is tucking away functions in a place where I have to do a TON of work to get tests around them. I have seen some of the worst code ever written inside of promise callbacks because “hey, it’s promise. It’s cool, man. You don’t need to test that.”

cough yes you do cough

Did you notice how I said “promise callback?” Yep, there it is. Promises and callbacks are still the same. You still pass in callbacks. You still have to handle the asynchronous nature of it all. This is where I climb to the mountaintop and proclaim “the cake is a lie!”

Then there is the q.all argument:

“What if you need to do a bunch of things and then call back? That’s like… complicated, man.”

It is. This was one the one concession I make… well, I USED to make. Q.all is pretty cool. Don’t get me wrong, anything that will bundle up a bunch of async calls and then hang out until they are all done, THEN callback is pretty darn nifty.  The problem is you are still introducing this idea of promises into the mix.  Stuff happens, the spell is woven and magic happens… Magic that is basically untestable.

So, let’s stop trying to paint the callback turd with a single layer of abstraction that makes things murkier and more difficult to understand. Promises are magic that have become lingua franca of async spaghetti. Instead, let’s have a look at a handy new library borne of Node and easily pulled into the client: Async

Dear promises, never send to know for whom the bells tolls; it tolls for thee.

Async deals with callbacks differently. Instead of wrapping everything up in a nasty set of promise.then().then().thens, try async.waterfall(). It’s like magic:

async.waterfall([ firstOperation, secondOperation, thirdOperation ], finishFunction);

Now your code actually says what it is doing. Callback hell is gone. Promises are eliminated. All is right in the world.

But what if I want to do a bunch of stuff that doesn’t happen in serial? Parallel. Check it, yo:

async.parallel([ anOperation, anotherOperation, yetAnotherOperation ], finishFunction);

It’s like magic right?

In closing, all I would ask is, if you are going to write a bunch of async stuff, please give me and everyone else on your team a break. Async is the way to righteousness and the light. Promises are great when you absolutely, positively must have it sometime later, but most work can be done with async. Give it a try and make your code a better place.

To New Beginnings

May 1, 2015

Wow! It’s shocking that the last post I wrote here was almost a year and a half ago. I guess it’s been busy!

In that time I worked for an education company, got laid off, found work at a startup and wrote a LOT of code. Am I older? Definitely. Am I wiser? I certainly hope so. If anything I gained a lot of insight and found evidence for my suspicions.  User experience is crucial and the only people who can guarantee a good experience are the people who create the software that users touch.

I spent much of the past 10 years trying to figure out what I wanted to be when I grew up.  I went through phases of user experience, accessibility, project management and research.  All the while I was busy writing software.  What I ultimately discovered is I like writing software.  I like creating things.  There’s a rush that I don’t get anywhere else but there.  That doesn’t get me the answer I was necessarily looking for, but I suppose it gave me something I could hold on to.

Another important thing I discovered along the way is there are a lot of people who have a lot to learn (including me) but I discovered something I didn’t believe before now: I have something to share.  For as much as I don’t know I have been fortunate to learn a lot of lessons and I can share that with people so, maybe… hopefully, they can either grow from what I experienced or, at least, I can help buoy their spirits a little by showing that everyone makes mistakes.

Wisdom is what you get when you don’t get what you want.

I didn’t come up with that phrase, but it sure sums up what I feel to be true.  Just because things didn’t work out the way you originally planned or wanted doesn’t mean that things didn’t turn out at all. Failure is such a better teacher than success that I just can’t imagine why people fear failure so much.  I aim to fail every day. Failing is awesome. Success just means you’re done, but when you fail, that means you went from working on something routine to a fascinating new puzzle. What a great opportunity!

I could go on and on like this for pages, talking in circles and rambling about vague pasts and lessons learned, but that isn’t what I set out to do.  This post marks the beginning of a new era for me and this blog.  I won’t promise that I will never post long diatribes about strange new discoveries I may or may not have uncovered myself.  What I can say is I have a focus today like I never could have imagined when I started writing this blog years ago.

I want to make stuff awesome and make awesome stuff. I want you to do the same.  I still want to make the web a better place, but maybe, somewhere along the way, I, or we, can actually make software better.  Let’s toast to new beginnings and new projects.  Here’s to all the projects that never quite were and the ones that are yet to come. Let’s make software. Let’s make it great. Let’s make it together.

Yo dawg, I heard you like accessibility...

Sep 5, 2013

So I put accessibility in your menus so your users can use your site even if they are disabled.

Okay, so I suck at yo, dawg jokes. I did, however make a handy little menu script.  It’s small. It’s functional. It supports accessibility features like roles and keyboard access. It’s easy to turn some plain old HTML into a menu without having to know ANY javascript.  Am I a mad genius? Quite possibly, but I’ll take what I can get.

So, here’s the deal, you can download the alpha release at the following link:

https://github.com/cmstead/ClickBeetleJS/releases/tag/v0.5-alpha

If you want to actually code and help make it better you can fork the project here:

https://github.com/cmstead/ClickBeetleJS

Important things you should know:

ClickBeetleJS requires jQuery. Pull requests won’t be accepted without passing tests associated. All my tests are written with QUnit. Please write yours using the same framework.

I hope this is useful for you.

Help me make the web a better place.

  • Web Designers Rejoice: There is Still Room

    I’m taking a brief detour and talking about something other than user tolerance and action on your site. I read a couple of articles, which you’ve probably seen yourself, and felt a deep need to say something. Smashing Magazine published Does The Future Of The Internet Have Room For Web Designers? and the rebuttal, I Want To Be A Web Designer When I Grow Up, but something was missing.

  • Anticipating User Action

    Congrats, you’ve made it to the third part of my math-type exploration of anticipated user behavior on the web. Just a refresher, the last couple of posts were about user tolerance and anticipating falloff/satisficing These posts may have been a little dense and really math-heavy, but it’s been worth it, right?

  • Anticipating User Falloff

    As we discussed last week, users have a predictable tolerance for wait times through waiting for page loading and information seeking behaviors. The value you get when you calculate expected user tolerance can be useful by itself, but it would be better if you could actually predict the rough numbers of users who will fall off early and late in the wait/seek process.

  • User Frustration Tolerance on the Web

    I have been working for quite a while to devise a method for assessing web sites and the ability to provide two things. First, I want to assess the ability for a user to perform an action they want to perform. Second I want to assess the ability for the user to complete a business goal while completing their own goals.

  • Google Geocoding with CakePHP

    Google has some pretty neat toys for developers and CakePHP is a pretty friendly framework to quickly build applications on which is well supported. That said, when I went looking for a Google geocoding component, I was a little surprised to discover that nobody had created one to do the hand-shakey business between a CakePHP application and Google.

  • Small Inconveniences Matter

    Last night I was working on integrating oAuth consumers into Noisophile. This is the first time I had done something like this so I was reading all of the material I could to get the best idea for what I was about to do. I came across a blog post about oAuth and one particular way of managing the information passed back from Twitter and the like.

  • Know Thy Customer

    I’ve been tasked with an interesting problem: encourage the Creative department to migrate away from their current project tracking tool and into Jira. For those of you unfamiliar with Jira, it is a bug tracking tool with a bunch of toys and goodies built in to help keep track of everything from hours to subversion check-in number. From a developer’s point of view, there are more neat things than you could shake a stick at. From an outsider’s perspective, it is a big, complicated and confusing system with more secrets and challenges than one could ever imagine.

  • When SEO Goes Bad

    My last post was about finding a healthy balance between client- and server-side technology. My friend sent me a link to an article about SEO and Google’s “reasonable surfer” patent. Though the information regarding Google’s methods for identifying and appropriately assessing useful links on a site was interesting, I am quite concerned about what the SEO crowd was encouraging because of this new revelation.

  • Balance is Everything

    Earlier this year I discussed progressive enhancement, and proposed that a web site should perform the core functions without any frills. Last night I had a discussion with a friend, regarding this very same topic. It came to light that it wasn’t clear where the boundaries should be drawn. Interaction needs to be a blend of server- and client-side technologies.

  • Coding Transparency: Development from Design Comps

    Since I am an engineer first and a designer second in my job, more often than not the designs you see came from someone else’s comp. Being that I am a designer second, it means that I know just enough about design to be dangerous but not enough to be really effective over the long run.

  • Usabilibloat or Websites Gone Wild

    It’s always great when you have the opportunity to built a site from the ground up. You have opportunities to design things right the first time, and set standards in place for future users, designers and developers alike. These are the good times.

  • Thinking in Pieces: Modularity and Problem Solving

    I am big on modularity. There are lots of problems on the web to fix and modularity applies to many of them. A couple of posts ago I talked about content and that it is all built on or made of objects. The benefits from working with objectified content is the ease of updating and the breadth and depth of content that can be added to the site.

  • Almost Pretty: URL Rewriting and Guessability

    Through all of the usability, navigation, design, various user-related laws and a healthy handful of information and hierarchical tricks and skills, something that continues to elude designers and developers is pretty URLs. Mind you, SEO experts would balk at the idea that companies don’t think about using pretty URLs in order to drive search engine placement. There is something else to consider in the meanwhile:

  • Content: It's All About Objects

    When I wrote my first post about object-oriented content, I was thinking in a rather small scope. I said to myself, “I need content I can place where I need it, but I can edit once and update everything at the same time.” The answer seemed painfully clear: I need objects.

  • It's a Fidelity Thing: Stakeholders and Wireframes

    This morning I read a post about wireframes and when they are appropriate. Though I agree, audience is important, it is equally important to hand the correct items to the audience at the right times. This doesn’t mean you shouldn’t create wireframes.

  • Developing for Delivery: Separating UI from Business

    With the advent of Ruby on Rails (RoR or Rails) as well as many of the PHP frameworks available, MVC has become a regular buzzword. Everyone claims they work in an MVC fashion though, much like Agile development, it comes in various flavors and strengths.

  • I Didn't Expect THAT to Happen

    How many times have you been on a website and said those very words? You click on a menu item, expecting to have content appear in much the same way everything else did. Then, BANG you get fifteen new browser windows and a host of chirping, talking and other disastrous actions.

  • Degrading Behavior: Graceful Integration

    There has been a lot of talk about graceful degradation. In the end it can become a lot of lip service. Often people talk a good talk, but when the site hits the web, let’s just say it isn’t too pretty.

  • Website Overhaul 12-Step Program

    Suppose you’ve been tasked with overhauling your company website. This has been the source of dread and panic for creative and engineering teams the world over.

  • Pretend that they're Users

    Working closely with the Creative team, as I do, I have the unique opportunity to consider user experience through the life of the project. More than many engineers, I work directly with the user. Developing wireframes, considering information architecture and user experience development all fall within my purview.

  • User Experience Means Everyone

    I’ve been working on a project for an internal client, which includes linking out to various medical search utilities. One of the sites we are using as a search provider offers pharmacy searches. The site was built on ASP.Net technology, or so I would assume as all the file extensions are ‘aspx.’ I bring this provider up because I was shocked and appalled by their disregard for the users that would be searching.

  • Predictive User Self-Selection

    Some sites, like this one, have a reasonably focused audience. It can become problematic, however, for corporate sites to sort out their users, and lead them to the path of enlightenment. In the worst situations, it may be a little like throwing stones into the dark, hoping to hit a matchstick. In the best, users will wander in and tell you precisely who they are.

  • Mapping the Course: XML Sitemaps

    I just read a short, relatively old blog post by David Naylor regarding why he believes XML sitemaps are bad. People involved with SEO probably know and recognize the name. I know I did. I have to disagree with his premise, but agree with his argument.

  • The Browser Clipping Point

    Today, at the time of this writing, Google posted a blog stating they were dropping support for old browsers. They stated:

  • Creativity Kills

    People are creative. It’s a fact of the state of humanity. People want to make things. It’s built into the human condition. But there is a difference between haphazard creation and focused, goal-oriented development.

  • Reactionary Navigation: The Sins of the Broad and Shallow

    When given a task of making search terms and frequetly visited pages more accessible to users, the uninitiated fire and fall back. They leave in their wake, broad, shallow sites with menus and navigtion which look more like weeds than an organized system. Ultimately , these navigation schemes fail to do the one thing they were intended for, enhance findability.

  • OOC: Object Oriented Content

    Most content on the web is managed at the page level. Though I cannot say that all systems behave in one specific way, I do know that each system I’ve used behaves precisely like this. Content management systems assume that every new piece of content which is created is going to, ultimately, have a page that is dedicated to that piece of content. Ultimately all content is going to live autonomously on a page. Content, much like web pages, is not an island.

  • Party in the Front, Business in the Back

    Nothing like a nod to the reverse mullet to start a post out right. As I started making notes on a post about findability, something occurred to me. Though it should seem obvious, truly separating presentation from business logic is key in ensuring usability and ease of maintenance. Several benefits can be gained with the separation of business and presentation logic including wiring for a strong site architecture, solid, clear HTML with minimal outside code interfering and the ability to integrate a smart, smooth user experience without concern of breaking the business logic that drives it.

  • The Selection Correction

    User self selection is a mess. Let’s get that out in the open first and foremost. As soon as you ask the user questions about themselves directly, your plan has failed. User self selection, at best, is a mess of splash pages and strange buttons. The web has become a smarter place where designers and developers should be able to glean the information they need about the user without asking the user directly.

  • Ah, Simplicity

    Every time I wander the web I seem to find it more complicated than the last time I left it.  Considering this happens on a daily basis, the complexity appears to be growing monotonically.  It has been shown again and again that the attention span of people on the web is extremely short.  A good example of this is a post on Reputation Defender about the click-through rate on their search results.

  • It's Called SEO and You Should Try Some

    It’s been a while since I last posted, but this bears note. Search engine optimization, commonly called SEO, is all about getting search engines to notice you and people to come to your site. The important thing about good SEO is that it will do more than simply get eyes on your site, but it will get the RIGHT eyes on your site. People typically misunderstand the value of optimizing their site or they think that it will radically alter the layout, message or other core elements they hold dear.

  • Information and the state of the web

    I only post here occasionally and it has crossed my mind that I might almost be wise to just create a separate blog on my web server.  I have these thoughts and then I realize that I don’t have time to muck with that when I have good blog content to post, or perhaps it is simply laziness.  Either way, I only post when something strikes me.

  • Browser Wars

    It’s been a while since I have posted. I know. For those of you that are checking out this blog for the first time, welcome. For those of you who have read my posts before, welcome back. We’re not here to talk about the regularity (or lack thereof) that I post with. What we are here to talk about is supporting or not supporting browsers. So first, what inspired me to write this? Well… this:

  • Web Scripting and you

    If there is one thing that I feel can be best learned from programming for the internet it’s modularity.  Programmers preach modularity through encapsulation and design models but ultimately sometimes it’s really easy to just throw in a hacky fix and be done with the whole mess.  Welcome to the “I need this fix last week” school of code updating.  Honestly, that kind of thing happens to the best of us.

  • Occam's Razor

    I have a particular project that I work on every so often. It’s actually kind of a meta-project as I have to maintain a web-based project queue and management system, so it is a project for the sake of projects. Spiffy eh? Anyway, I haven’t had this thing break in a while which either means that I did such a nice, robust job of coding the darn thing that it is unbreakable (sure it is) or more likely, nobody has pushed this thing to the breaking point. Given enough time and enough monkeys. All of that aside, every so often, my boss comes up with new things that she would like the system to do, and I have to build them in. Fortunately, I built it in such a way that most everything just kind of “plugs in” not so much that I have an API and whatnot, but rather, I can simply build out a module and then just run an include and use it. Neat, isn’t it?

  • Inflexible XML data structures

    Happy new year! Going into the start of the new year, I have a project that has carried over from the moment I started my current job. I am working on the information architecture and interaction design of a web-based insurance tool. Something that I have run into recently is a document structure that was developed using XML containers. This, in and of itself, is not an issue. XML is a wonderful tool for dividing information up in a useful way. The problem lies in how the system is implemented. This, my friends, is where I ran into trouble with a particular detail in this project. Call it the proverbial bump in the road.

  • Accessibility and graceful degradation

    Something that I have learnt over time is how to make your site accessible for people that don’t have your perfect 20/20 vision, are working from a limited environment or just generally have old browsing capabilities. Believe it or not, people that visit my web sites still use old computers with old copies of Windows. Personally, I have made the Linux switch everywhere I can. That being said, I spend a certain amount of time surfing the web using Lynx. This is not due to the fact that I don’t have a GUI in Linux. I do. And I use firefox for my usual needs, but Lynx has a certain special place in my heart. It is in a class of browser that sees the web in much the same way that a screen reader does. For example, all of those really neat iframes that you use for dynamic content? Yeah, those come up as “iframe.” Totally unreadable. Totally unreachable. Iframe is an example of web technology that is web-inaccessible. Translate this as bad news.

  • Less is less, more is more. You do the math.

    By this I don’t mean that you should fill every pixel on the screen with text, information and blinking, distracting graphics. What I really mean is that you should give yourself more time to accomplish what you are looking to do on the web. Sure, your reaction to this is going to be “duh, of course you should spend time thinking about what you are going to do online. All good jobs take time.” I say, oh young one, are you actually spending time where it needs to be spent? I suspect you aren’t.

  • Note to self, scope is important.

    Being that this was an issue just last evening, I thought I would share something that I have encountered when writing Javascript scripts.  First of all, let me state that Javascript syntax is extremely forgiving.  You can do all kinds of  unorthodox declarations of variables as well as use variables in all kinds of strange ways.  You can take a variable, store a string in it, then a number, then an object and then back again.  Weakly typed would be the gaming phrase.  The one thing that I would like to note, as it was my big issue last evening, is scope of your variables.  So long as you are careful about defining the scope of any given variable then you are ok, if not, you could have a problem just like I did.  So, let’s start with scope and how it works.

  • Subscribe

    -->