How to make JavaScript find value of input on focus, clear if it's default and keep if it's new data?
I've spent too many hours trying to figure this, and I've found parts of the answer here on Stackoverflow but still can't get this working.
What I want to do is control all input elements sitewide with some JS/jQuery. When a user focuses on the input, if the value is the same as when the page loaded, clear it, if it's been altered, keep it. Then on blur, if the field is empty, return the default value.
What I have so far is this:
var input = document.getElementsByTagName('input');
$('input, textarea').focus(function() {
value = $(this).val();
for (var i=input.length-1; i >= 0; i--) {
if(value == input[i].value){
$(this).attr("value","");
}
}
});
$('input, textarea').blur(function() {
if($(this).val()=="") {
$(this).val(value);
}
});
This partly works, it just keeps clearing the in开发者_高级运维puts though, whether they have been changed or not. I'm guessing I am storing the initial values wrong.
this line is the bad guy
if(value == input[i].value){
since getElementsByTagName returns a HTMLCollection, changes to the dom are also in your input variable. Thus, value will always be input[i].value, since your getting the value of the same input elem, which of course are the same!
use jquery data method to save the value within the element. and on blur, retrieve it again to make the comparison.
like this;
var handlers={
focus: function() {
var elm=$(this),
value=elm.val(),
old=elm.data("placeholder");
if (typeof old==="undefined"){
elm.data("placeholder", value);
old=value;
}
if (old==value){
elm.val("");
}
},
blur:function() {
var elm=$(this);
if( elm.val() == "" ) {
elm.val( elm.data("placeholder") );
}
}
};
$('input, textarea').each(function(i, elem){
$(elem).
focus(handlers.focus).
blur(handlers.blur);
});
//not tested, should work!
You just need to store a default value first, then reference it on blur and focus.
$('input, textarea').each(function() {
var $this = $(this);
$this.data('defaultValue', $this.val()); // stores the default value
$this.focus( function() {
if ($this.val() == $this.data('defaultValue')) {
$this.val("");
}
});
$this.blur( function() {
if ($this.val() == "") {
$this.val( $this.data('defaultValue') );
}
});
});
With a second look, I think that we don't even need the data store.
$('input, textarea').each(function() {
var $this = $(this),
defaultValue = $this.val(); // stores the default value
$this.focus( function() {
if ($this.val() == defaultValue) {
$this.val("");
}
});
$this.blur( function() {
if ($this.val() == "") {
$this.val(defaultValue);
}
});
});
this what I use on my Search box:
<input name="q" value="Search here ..." onfocus="if(this.value == 'Search here ...') this.value = '';" onblur="if(this.value == '') this.value = 'Search here ...';">
I think @japrescott is correct, but you have another issue as well - in the block:
$('input, textarea').blur(function() {
if($(this).val()=="") {
$(this).val(value);
}
});
...the variable value
isn't defined in scope.
So, issue 1 - that collection in input is by reference, so when your inputs are updated, they are also are updated in the collection, thus the value always appears to be the default.
What I would recommend is rather than storing the default values that way, store them as part of the element. On load you can loop through the elements and add the values to a "default" attribute. You could also add the default attribute server-side which would be better.
Something like this:
<input type='text' default='myval' value='myval'/>
var jInput = $('input');
if(jInput.val() == jInput.attr('default'))
...
I'm sure you get the idea.
this does it all: http://jsfiddle.net/uUzY3/4/
$(function() {
$("input").each( function () {
$(this).data('initialValue', $(this).val());
}).bind('focus', function() {
if ($(this).val() == $(this).data('initialValue'))
$(this).val("");
});
});
精彩评论