Skip to content

Instantly share code, notes, and snippets.

@bbqsrc
Last active January 2, 2016 09:38
Show Gist options
  • Save bbqsrc/8284079 to your computer and use it in GitHub Desktop.
Save bbqsrc/8284079 to your computer and use it in GitHub Desktop.
Placeholder polyfill for IE8, including programmatic updating
(function() {
var blank = "",
cls = 'ie8-placeholder';
if (document.createElement('input').placeholder === blank) {
return;
}
function handlePlaceholder(node, newNode) {
var v, r;
if (node != null) {
v = node.value;
r = v === blank;
node[cls] = true;
if (r) {
node.classList.add(cls);
node.value = node.placeholder;
}
node.hasPlaceholder = r;
delete node[cls];
node = null;
}
if ("placeholder" in newNode) {
node = newNode;
node.classList.remove(cls);
node[cls] = true;
if (node.hasPlaceholder) {
node.value = blank;
node.hasPlaceholder = false;
}
delete node[cls];
}
return node;
}
var lastActiveElement = null;
document.attachEvent('onpropertychange', function() {
if (event.propertyName == "activeElement") {
lastActiveElement = handlePlaceholder(lastActiveElement, document.activeElement);
}
});
window.attachEvent("onbeforeunload", function() {
var i, ii, node;
var nodes = document.querySelectorAll("[placeholder]");
for (i = 0, ii = nodes.length; i < ii; ++i) {
node = nodes[i];
delete node.hasPlaceholder;
node[cls] = true;
node.value = blank;
delete node[cls];
}
});
window.attachEvent("onload", function() {
var i, ii;
var nodes = document.querySelectorAll("[placeholder]");
for (i = 0, ii = nodes.length; i < ii; ++i) {
handlePlaceholder(nodes[i], {});
}
});
function fix(proto) {
var valueDesc = Object.getOwnPropertyDescriptor(proto, 'value'),
getAttr = proto.getAttribute,
setAttr = proto.setAttribute;
defineProperty(proto, 'placeholder', { value: blank });
defineProperty(proto, 'value', {
get: function() {
return this.hasPlaceholder ? blank : valueDesc.get.call(this);
},
set: function(v) {
var classList = this.classList,
r;
if (!this[cls]) {
v = v == null ? blank : v;
r = v === blank;
this.hasPlaceholder = r;
classList.toggle(cls, r);
valueDesc.set.call(this, r ? this.placeholder : v);
} else {
valueDesc.set.call(this, v);
}
return v;
}
});
proto.getAttribute = function(attr) {
if (attr == "value") {
return this.value;
}
return getAttr.call(this, attr);
}
proto.setAttribute = function(attr, value) {
if (attr == "value") {
return this.value = value;
}
return setAttr.call(this, attr, value);
}
}
fix(HTMLInputElement.prototype);
fix(HTMLTextAreaElement.prototype);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment