Archive for the ‘JavaScript’ Category

Oct 22

An Event Apart 2008, Day 1, 3:45pm – 4:45pm

Read the previous talk in this series, On-the-Spot Usability Reviews by Robert Hoekman, Jr., or view An Event Apart’s Table of Contents

Designing the Details: Web-App UI Design Beyond the Basics

Jason Fried of 37 Signals

  • Hilight the craftmanship of our product
  • The calendar items that have active items are not emboldened, but normal, and the inactive pages are weakened. Don’t focus on normal and strong, but normal and weak. 
  • People often design the screens with a series of functions and goals, but think about flow and how that’s going to work. Use JS/Ajax to make flow more smooth.
  • Think about Before, During, and Next
  • You should minimize having to use the mouse. You don’t want to keep using your mouse. Think how you can focus people’s attention on the next thing they have to do. 
    • Add contact, the expected item pops up in Ajax popup, you select what you want. It pops up, the focus immediately goes to the text box where you want to type the note. They start typing, and then they use the mouse for the first time to add the item.
    • Next time people will want to add a follow up task. So, add a little yellow bar there with the “Add a task” link deal to it, which will expand to a text box with the allowance of an addition of a task.
  • Copywriting is key
    • “Who can see this person?” It’s a permissions issue, but don’t make it “Permissions”. Make it “Who can see this person?” Then continue the conversation with the options: “Everyone, Only I Can, Select a group…, Select people…”
    • Write your copy like you would talk to someone. Change things, don’t do person(s). Make it “Delete the selected person” and then “Delete the 2 selected people”. Just like we pay attention to pixels, these things matter because it contributes to the user experience.
    • Be as explicit as you possibly can. Don’t do “Advanced”, give people an idea. 
    • If you’re going to “add a category”, type “Add This Category” to the submit button. Don’t say “Submit”. No one says that. Say what you mean.
  • When hovering over stuff and having sections activate (like a hover tab that appears on hover of a TR), let it stick around a bit in case they overshoot. They have found .25 seconds to be a good amount of delay time. If off the target for over .25s, it will disappear then. This is the same for certain areas that for someone reason you want to have a delay to appear as well: .25s.
  • Allow things to have a delay. We’re accustomed in nature to things not happening instantly. When checking off an item in a todo list, allow it to relatively slowly (slower than instant) cross out, and then fade out to delete. This seems more natural.
  • Photographic memory
    • The app should remember things.
    • Create a task – there is a checkbox for “Let everyone see this task”. After making the post, remember this. Remember the last default settings, because whatever they just had as a preference they will likely want to keep for the next time around.
  • What just happened?
    • Allow ppl to know that something has happened without having to reload the page. The Yellow Fade Technique™. Also known as .highlight, or whathaveyou. Before the page would reload, but now in the Ajax world, this allows a notification. It feels natural.
    • Allow dialogs to come up that notify and then fade away. Give them some sort of confirmation that it actually worked.
  • Drag and drop visual cues to allow people to do tasks with an immediate visceral experience
    • reorder TRs by drag and drop
    • Show information (the “drag this item to a page in the sitebar to move the note to that page” box) as it’s needed – not on an immediate click, but wait until they’ve gone 200px to the right (toward the sidebar).
  • Eliminate error messages where you can.
    • Most cases it’s not an error, but an inconvenience. They add a new to-do list without naming it first. Most apps would say “error, requires a name”. Well can you just name it “List” and they can change it later? I think so. Just do that. Don’t error, just apply a default.
  • Applies thumbnails to a document as it is added, so on the grid view, can see the thumbnail next to the item. Must be generating it server side and applying an image thumbnail metadata to the piece of content.
  • These things take extra time, but these things matter. Jump people to where they need to go, implement JavaScript to let them know where they need to go.
  • 37Signals made a conscious decision that their products will not work without JavaScript. And that’s okay for them, some projects that won’t fly. But state that in the product requirements that you’re selling.
  • 37Signals uses Prototype
  • “We use Prototype because Sam, the guy who works for us, uh, he developed Prototype.” – Jason Fried
  • He likes to use words as much as possible without icons
  • The idea that everything has to be obvious is unimportant. The horizontal drag to a new page, that’s not mission critical, there’s nothing informing the user that they can do that, and that’s okay. If they don’t know that, it’s not a big deal either.
  • 37Signals doesn’t use wireframes, doesn’t believe in them. Doesn’t use Photoshop very often. Doesn’t use a Photoshop mockup. They go straight to HTML, because that’s real and that’s what the customer is going to use.
  • You never know if anything is any good until you build the real thing. Everything else is best guess, but once you start plugging in real content, it’s nothing. 95% of the time (cavalier made up stat) it is much better to start for realz.

View the next talk in this series: Underpants Over My Trousers by Andy Clarke, or skip to An Event Apart’s Table of Contents

Popularity: 6% [?]

Feb 13

Usually JavaScript libraries include a getElementsByClassName function. However, if you’re building your own personal library, you may want to include your own version. Robert Nyman has built and amended over the past 2.5 years a function for this very method: The Ultimate getElementsByClassName!

The parameters passed in are the element of origin (e.g., document), the tags to search (e.g., “div” or “*”), and the class name or names that you wish to aggregate.

The last revision was May 2007, but the method is so tiny and has undergone several revs. I have added it to my personal library and it works well. I haven’t tested performance, but it’s gone through so many revs that it must be worthwhile to have lasted this long. I know, to make an assumption that something is good because it has lasted is somewhat flawed logic, but from the JS that I know, it looks clean.

JS gurus, tell me, is it hot or not? Downloadable Ultimate getElementsByClassName.

Popularity: 9% [?]

Aug 16

I have previously used the following to check if an element belongs to a certain CSS class:

JavaScript:
  1. if(myElement.className == 'colorful-class'){
  2.    takeAction();
  3. }

This method fails when an element bears two or more classes (which I have been using more frequently). A better method is to use JavaScript regular expressions methods to find whether the class attribute contains your class. Visit regular-expressions.info for a crash course on regular expressions if you are unfamiliar - they are fabulous and you must learn to use them.

There are several JavaScript RegExp methods we can implement. The best for this purpose is the test() method.

JavaScript:
  1. if(/colorful-class/.test(myElement.className)){
  2.    takeAction();
  3. }

With the following HTML, the aforewritten regular expression will return true. Using the JS equality operator would return false.

HTML:
  1. <p class="textful colorful-class">
  2. A textfully classed paragraph.
  3. </p>

Popularity: 12% [?]

Jun 16

Congratulations to Dawid Lizak for winning the CSS Off competition of June. View his winning entry.

Gripes

Note: A lot of these gripes are directed to my own misunderstanding of the rules of this fairly new competition. If you disagree with any of my gripes, please, leave a comment.

Non-Semantic HTML

There are divs named "top", "topleft", etc. About half of the classes/ids are named semantically, and the others are describing style. The naming convention implemented is far from CSS best practices.

Copy Alterations

In the "Upcoming Events" section, Dawid has changed "August", "June", et cetera, to their three character abbreviation. The copy that we received in the Jabroni packet (included with the PSDs were text files of the copy) distinctly bore the month name fully spelled. Changing the month in the HTML is a cop-out. If the system feeds the page "August", and the design calls for "AUG", some sort of server-side or client-side processing must be taken. This ought to be clarified in future contests. If I can assume that "January" has been handled on the server-side, I would love to hard-code "JAN" into my page rather than write JavaScript to handle the text transform.

In like manner, there are various places where the HTML has uppercase lettering hard-coded rather than handled with CSS. The text document bore sentence capitalization. It's not fair to change this in the HTML unless we have specified that certain server-side text manipulation may be assumed. Conversely, it's simple to perform an uppercase text-transform with CSS, and I'm upset to see the lack of such a simple CSS implementation on the winning entry.

Missing Headings

Some of the heading tags are in improper order. An h5 tag is used underneath an h2 tag - tsk, tsk. This is a bear on the document outline and generally poor HTML practice. Some can be chalked up to semantics, but you should never jump multiple heading levels like that. You can find errors in your document outline by using the Web Developer's toolbar in Firefox: Miscellaneous > View Document Outline. If you are missing heading elements (as Lizak's entry is), this tool will reveal them to you.

Usage of b, small tags

I know they are technically valid, but really, are we ignoring best practices? And the "small" tag? Could we be any less semantic? Why don't we just write < font size="-1"> while we're at it?

Diversion from Original Design

I understand that some diversion is good if it improves upon the original design. This gripe is just a personal "Arg" because I was going to force my header to span the width of the browser window, like Dawid, but I looked again at the design and said, "No, that is not in the design," and refrained. Now I am wiser for future competitions.

Self-Critique

My entry did not validate. Why? Because I forgot to close my img tags a couple of times, and I forgot an alt attribute on one or two images. Arg! My CSS was valid, but not my HTML. I remember thinking immediately after I submitted the entry, "Doh! I forgot to validate my HTML!"; it must have been an oversight/tiredness from the short amount of time (only a few hours) that I had to build this.

I had not noticed my massive file size: 111kb. I wholly attribute this to my lack of proper image editing software.

Had my code validated, I am confident that I would have been one of the 6 semi-finalists. I should have abstracted my JavaScript. I'm relatively new to proper implementations of JavaScript and I see now the flaws in my JavaScript for cross-browser compatibility - namely, using getAttribute("class") rather than the .className property for IE compatibility. I also wonder if my lack of attention to fonts played a part in the disqualification. That's part of the frustration: when I'm coding a design in the workplace, I can ask the designer what typeface, what font size, what exact hex color.

So it goes.

Fortunately, I was one of 15 finalists (out of the 48 timely entries). View the finalists (I'm #10 in the list of chronologically ordered entries). Regardless of my place, I learned quite a few lessons in speed-coding.

Final Thoughts

I shouldn't gripe so much, as I neglected to close a few "img" tags, and had a minor cross-browser JavaScript quirk to learn about. I have also learned to spend more time in optimizing images for the web.

Sadly, I didn't really learn much from the winning entry except the interesting method of employing a two-toned header spanning the width of the browser window. It utilizes non-semantic divs, but we live in the real world, not an ideal one, which makes sparing use of non-semantic divs "acceptable".

It is a fabulous competition. With my learned lessons (from my stupid mistakes), perhaps I have a better chance of winning the next competition. Thanks to Tony and JD for their long hours judging despite loads of entrants' griping.

Popularity: 13% [?]

Jan 06

Courtesy of Daniel Nolan, I found this handy little rollover JS to add rollovers for all your images. It is standards compliant and will not invalidate your HTML. It also majorly cuts down on the bulkiness of your HTML, eliminating the inline JS that is so common on sites nowadays for image rollovers.

Why not just use pure CSS?

CSS allows use of the :hover pseudo-class to swap images. This eliminates nasty inline javascript nonsense to accomplish the same thing and even works with JavaScript disabled. Why not use this method?

I asked myself the same question. There are two answers:

  1. Safari does not support image replacement on form elements. Thus, the solution would only work some of the time.
  2. IE6 only supports :hover on anchor tags. "Who cares?" you ask. Well, clients who pay money for their sites to work for the largest audience possible care. And, people who don't upgrade their machines care. So, anyone with IE6 would lose the image rollover. Isn't that sad? Especially when you can include them so simply?

How to use it

  1. Have a consistent naming convention for your image (and its rollover)

    For example, name your image myimage.jpg, and your rollover myimage_o.jpg. The JS function handles the rest. It even handles the image preloads. Isn't that nice?

  2. Add the class "imgover" to the image which you would like the rollover applied.
  3. Include the rollover.js file in your site template. If you have a whole bunch of functions executing on the window.onload, delete that line from the bottom of rollover.js and add initRollovers(); to your preload function.

I made a minor addition to include inputs of type "image", as it was hugely cumbersome to me on a site that already had these implemented. My addition is copied below:

var aInputs = document.getElementsByTagName('input');

for (var i = 0; i < aInputs.length; i++){
if(aInputs[i].className == 'imgover'){
if(aInputs[i].getAttribute('type') == 'image'){
var src = aInputs[i].getAttribute('src');
var ftype = src.substring(src.lastIndexOf('.'), src.length);
var hsrc = src.replace(ftype, '-over'+ftype);

aInputs[i].setAttribute('hsrc', hsrc);

aPreLoad[i] = new Image();
aPreLoad[i].src = hsrc;

aInputs[i].onmouseover = function() {
sTempSrc = this.getAttribute('src');
this.setAttribute('src', this.getAttribute('hsrc'));
}

aInputs[i].onmouseout = function() {
if (!sTempSrc) sTempSrc = this.getAttribute('src').replace('-over'+ftype, ftype);
this.setAttribute('src', sTempSrc);
}

}
}
}

Popularity: 14% [?]




  • Meta