He encontrado que la mejor manera de resolver esto es utilizar un <label>
y la posición sobre el área de entrada. Esto le da:
- Más libertad estética
- Mantiene su página semántica
- Le permite funcionar fácilmente a
- no causa problemas mediante la presentación de la información sobre herramientas como el valor de entrada o tienen que preocuparse por la gestión ese problema
Aquí hay una versión estándar ya que no pidió un marco. El marcado no debería tener que cambiar, pero es posible que deba ajustar el CSS para que funcione con sus necesidades.
HTML:
<html>
<head>
<style>
label.magiclabel {
position: absolute;
padding: 2px;
}
label.magiclabel,
input.magiclabel {
width: 250px;
}
.hidden { display: none; }
</style>
<noscript>
<style>
/* Example of graceful degredation */
label.magiclabel {
position: static;
}
</style>
</noscript>
</head>
<body>
<label>This is not a magic label</label>
<form>
<label class="magiclabel" for="input-1">Test input 1</label>
<input class="magiclabel" type="text" id="input-1" name="input_1" value="">
<label class="magiclabel" for="input-2">Test input 2 (with default value)</label>
<input class="magiclabel" type="text" id="input-2" name="input_2" value="Default value">
</form>
<script src="magiclabel.js"></script>
</body>
</html>
vanilla-magiclabel.js
(function() {
var oldOnload = typeof window.onload == "function" ? window.onload : function() {};
window.onload = function() {
// Don't overwrite the old onload event, that's just rude
oldOnload();
var labels = document.getElementsByTagName("label");
for (var i in labels) {
if (
// Not a real part of the container
!labels.hasOwnProperty(i) ||
// Not marked as a magic label
!labels[i].className.match(/\bmagiclabel\b/i) ||
// Doesn't have an associated element
!labels[i].getAttribute("for")
) { continue; }
var associated = document.getElementById(labels[i].getAttribute("for"));
if (associated) {
new MagicLabel(labels[i], associated);
}
}
};
})();
var MagicLabel = function(label, input) {
this.label = label;
this.input = input;
this.hide = function() {
this.label.className += " hidden";
};
this.show = function() {
this.label.className = this.label.className.replace(/\bhidden\b/ig, "");
};
// If the field has something in it already, hide the label
if (this.input.value) {
this.hide();
}
var self = this;
// Hide label when input receives focuse
this.input.onfocus = function() {
self.hide();
};
// Show label when input loses focus and doesn't have a value
this.input.onblur = function() {
if (self.input.value === "") {
self.show();
}
};
// Clicking on the label should cause input to be focused on since the `for`
// attribute is defined. This is just a safe guard for non-compliant browsers.
this.label.onclick = function() {
self.hide();
};
};
Vanilla demo
Como se puede ver, alrededor de la mitad del código está envuelto en la inicialización de la window.onload
. Esto puede mitigarse usando un marco. Aquí hay una versión utilizando jQuery:
$(function() {
$("label.magiclabel[for]").each(function(index, label) {
label = $(label);
var associated = $("#" + label.attr("for"));
if (associated.length) {
new MagicLabel(label, associated);
}
});
});
var MagicLabel = function(label, input) {
// If the field has something in it already, hide the label
if (input.val() !== "") {
label.addClass("hidden");
}
label.click(function() { label.addClass("hidden"); });
input.focus(function() { label.addClass("hidden"); });
input.blur(function() {
if (input.val() === "") {
label.removeClass("hidden");
}
});
};
jQuery demo. No es necesario cambiar el marcado, pero, por supuesto, deberá incluir la biblioteca jQuery.
Una pregunta ¿podemos cargarlo sin cargar? Debido a que el formulario que estoy usando este asistente está cargado con la ayuda de ajax y ya estoy usando algunas cosas onload. – Shishant