Skip to content

Instantly share code, notes, and snippets.

@remy
Created March 12, 2010 13:59
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save remy/330318 to your computer and use it in GitHub Desktop.
Save remy/330318 to your computer and use it in GitHub Desktop.
autofocus and placeholder support
/**
* Add this script to the end of your document that use <input autofocus type="text" />
* or <input type="text" placeholder="username" /> and it'll plug support for browser
* without these attributes
* Minified version at the bottom
*/
(function () {
function each(list, fn) {
var l = list.length;
for (var i = 0; i < l; i++) {
if (fn.call(list[i], list[i], i, list) === false) {
break;
}
}
}
var addEvent = (function () {
if (document.addEventListener) {
return function (el, type, fn) {
if (el && el.nodeName || el === window) {
el.addEventListener(type, fn, false);
} else if (el && el.length) {
for (var i = 0; i < el.length; i++) {
addEvent(el[i], type, fn);
}
}
};
} else {
return function (el, type, fn) {
if (el && el.nodeName || el === window) {
el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
} else if (el && el.length) {
for (var i = 0; i < el.length; i++) {
addEvent(el[i], type, fn);
}
}
};
}
})();
var i = document.createElement('input'),
inputs = [].slice.call(document.getElementsByTagName('input'), 0);
inputs = inputs.concat([].slice.call(document.getElementsByTagName('textarea'), 0));
if (!('placeholder' in i)) {
// placeholder fix
each(inputs, function (el) {
// note - we're using el instead of this across the board because it compresses better
var lastValue = el.value, placeholder = el.getAttribute('placeholder');
var focus = function () {
if (el.value == placeholder) {
el.value = '';
el.style.color = '';
}
};
var blur = function () {
if (el.value == '') {
el.value = placeholder;
el.style.color = '#A29797';
}
};
addEvent(el, 'focus', focus);
addEvent(el, 'blur', blur);
// remove the placeholder if the page is reload or the form is submitted
addEvent(el.form, 'submit', function () { focus.call(el); });
addEvent(window, 'unload', function () { focus.call(el); });
// set the default state
if (el.value == '') {
blur.call(el);
}
});
}
if (!('autofocus' in i)) {
// auto focus
each(inputs, function (el) {
if (el.getAttribute('autofocus') != null) {
el.focus();
return false; // "there can only be one"
}
});
}
})();
// minified
(function(f,g){function i(a,d){for(var c=a.length,b=0;b<c;b++)if(d.call(a[b],a[b],b,a)===false)break}var e=function(){return g.addEventListener?function(a,d,c){if(a&&a.nodeName||a===f)a.addEventListener(d,c,false);else if(a&&a.length)for(var b=0;b<a.length;b++)e(a[b],d,c)}:function(a,d,c){if(a&&a.nodeName||a===f)a.attachEvent("on"+d,function(){return c.call(a,f.event)});else if(a&&a.length)for(var b=0;b<a.length;b++)e(a[b],d,c)}}(),j=g.createElement("input"),h=[].slice.call(g.getElementsByTagName("input"),
0);h=h.concat([].slice.call(g.getElementsByTagName("textarea"),0));"placeholder"in j||i(h,function(a){var d=a.getAttribute("placeholder");function c(){if(a.value==d){a.value="";a.style.color=""}}function b(){if(a.value==""){a.value=d;a.style.color="#A29797"}}e(a,"focus",c);e(a,"blur",b);e(a.form,"submit",function(){c.call(a)});e(f,"unload",function(){c.call(a)});a.value==""&&b.call(a)});"autofocus"in j||i(h,function(a){if(a.getAttribute("autofocus")!=null){a.focus();return false}})})(this,document);
@mathiasbynens
Copy link

It’s probably a good idea to move our Twitter conversation here, for future reference.

I’ve put up a test page for this script over at jsbin.com/avuzu3.

Your trick to disable Firefox autocomplete seems to fail (tested in Firefox 3.6.6), even though it used to work in previous Fx versions. The input values appear to be stored in the autocomplete database instantly upon submit (before their values are cleared). Any idea how to fix that?

Also, this script seems to throw an error in IE8.

@remy
Copy link
Author

remy commented Jul 27, 2010

@mathiasbynens - I can't seem to replicate the bug in FF3.6.6 - have you got a specific pattern of user input I can test to replicate?

Also - I don't see how the placeholder.js would work in IE8 (I've not tested it yet, so I might be eating my words), but it uses HTMLElement.prototype - which isn't available in IE, and it's using addEventListener which isn't available in IE8 and below...

@mathiasbynens
Copy link

@remy: I tested it using the page I linked to before, in Firefox 3.6.8 this time. Same result. Here’s a short screencast: http://screenr.com/JJX Please tell me if I’m doing it wrong.

Also - I don't see how the placeholder.js would work in IE8 (I've not tested it yet, so I might be eating my words), but it uses HTMLElement.prototype - which isn't available in IE, and it's using addEventListener which isn't available in IE8 and below...

My mistake, I hadn’t tested in IE / looked at the source code either :) Edited my comment now. I guess I was just trying to point out yours doesn’t seem to work in IE.

@danielstocks
Copy link

Very nice indeed. I made a similar script with jQuery and packaged it into a plugin, it has the benefit of also supporting password inputs for IE (all versions), which many of the placeholder implementations seems to lack of.

http://github.com/danielstocks/jQuery-Placeholder

Cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment