jQuery实现的一个自定义Placeholder属性插件

时间:2022-03-14 12:47:06

HTML5中文本框的新属性placeholder是个非常好用的属性,但是IE系列直至IE9都不支持这一属性,这就让大家在用这一属性的时候有些犹豫不决。自己曾经写过很多类似共的小控件,但是都不是很通用,这里分享一个渐进增强的自定义placeholder的jQuery插件。有点是使用简单,大家也可以根据自己的需要进行改进。平常写jQuery插件比较少,考虑到用jQuery的同学比较多,这里就用jQuery插件的形式编写了。

在这里简单的介绍一下实现思路。

1.表现与html5原生的placeholder尽量类似
2.渐进增强对于支持placeholder的浏览器不做处理

一、首先是几个工具方法:

1.supportProperty(nodeType, property),获取浏览器是否支持某一控件的某一属性
2.getPositionInDoc(target, parent),获取对象在文档中的位置
3.$c,一个快速创建Dom对象的方法

这几个工具方法都是一些比较常见通用的方法,如果你有自己的或者更合适的可以自行替换。

二、主体,CustomPlaceholder对象。这个对象主要是维护每一个文本框的信息,包括其位置,应该显示的提示信息等等,另外它还包含创建提示信息以及定位等方法以及对象的相应事件。

事件主要是在initEvents函数中进行的处理,这里特别要注意的是对提示信息事件的处理,当提示信息被点击时焦点应该被重新定位到文本框。而文本框要处理的则是focus和blur事件。

 

复制代码 代码如下:


$(self.hint).bind( 'click', function(e){
 self.input.focus();
});

 

$(self.input).bind( 'focus', function(e){
 self.hint.style.display = 'none';
});

$(self.input).bind( 'blur', function(e){
 if(this.value == ''){
  self.hint.style.display = 'inline';
 }
});

 

CustomPlacehodler对象的两个主要方法是createHintLabel(text, position)和position()。createHintLabel是用于创建提示信息的DOM对象并对其进行定位,并返回这个对象。position方法用于强制对提示消息进行重新定位。主要用于页面大小改变的情况。这两个方法的功能和实现都比较简单。

三、插件的功能实现部分。jQuery插件实现方式就不多说了。这里首先进行了能力检测,如果原生支持placeholder则直接返回。

复制代码 代码如下:

if(supportProperty('input', 'placeholder')){
 return;
}

 

接下来是根据选择的input对象,生成相应的CustomPlaceholder对象,保存在数组中,并获取每个对象的提示信息的DOM对象,添加到容器中,最后将容器附加到body对象中。

复制代码 代码如下:


var customPlaceholders = [];
if(this.length > 0){
 var box = $c('div', 'dk_placeholderfixed_box');
 for(var i = 0, len = this.length; i < len; i++){
  var input = this[i];
  customPlaceholders.push(new CustomPlaceholder(box, input, option));
 }

 

 document.body.appendChild(box);
}

 

最后还有一件比较重要的事情,为window对象绑定resize事件,当window对象触发resize事件时对所有的customPlacehoder对象进行重新定位。

复制代码 代码如下:


$(window).bind( 'resize', function(e){
 for(var i = 0, len = customPlaceholders.length; i < len; i++){
  var customPlaceholder = customPlaceholders[i];
  customPlaceholder.position();
 }

 

});

 

这个简单的小插件到这里就写完了。

插件源码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
(function($){
 
var eles = {
    div: document.createElement('div'),
    ul: document.createElement('ul'),
    li: document.createElement('li'),
    span: document.createElement('span'),
    p: document.createElement('p'),
    a: document.createElement('a'),
    fragment: document.createDocumentFragment(),
    input: document.createElement('input')
}
    
var supportProperty = function(nodeType, property){
    switch(arguments.length){
        case 0:
            return false;
        case 1:
            var property = nodeType, nodeType = 'div';
            property = property.split('.');
            
            if(property.length == 1){
                return typeof eles[nodeType][property[0]] !== 'undefined';
            }else if(property.length == 2){
                return typeof eles[nodeType][property[0]][property[1]] !== 'undefined';
            }
        case 2:
            property = property.split('.');
            
            if(property.length == 1){
                return typeof eles[nodeType][property[0]] !== 'undefined';
            }else if(property.length == 2){
                return typeof eles[nodeType][property[0]][property[1]] !== 'undefined';
            }
            
            return false;
            
            
        default:
            return false;
    }
};
 
var getPositionInDoc = function(target, parent) {
    if (!target) {
        return null;
    }
    var left = 0,
        top = 0;
    do {
        left += target.offsetLeft || 0;
        top += target.offsetTop || 0;
        target = target.offsetParent;
        if(parent && target == parent){
            break;
        }
    } while (target);
    return {
        left: left,
        top: top
    };
}
 
var $c = function(tagName, id, className){
    var ele = null;
    if(!eles[tagName]){
        ele = eles[tagName] = document.createElement(tagName);
    }else{
        ele = eles[tagName].cloneNode(true);
    }
    if(id){
        ele.id = id;
    }
    if(className){
        ele.className = className;
    }
    return ele;
};
    
var CustomPlaceholder = function(box, input, option){
    var self = this;
    var position = getPositionInDoc(input);
    self.input = input;
    
    self.option = {xOffset:0, yOffset:0};
    for(var item in option){
        self.option[item] = option[item];
    }
    self.hint = self.createHintLabel(input.getAttribute('placeholder'), position);
    box.appendChild(self.hint);
    
    self.initEvents = function(){
        $(self.hint).bind( 'click', function(e){
            self.input.focus();
        });
        
        $(self.input).bind( 'focus', function(e){
            self.hint.style.display = 'none';
        });
        
        $(self.input).bind( 'blur', function(e){
            if(this.value == ''){
                self.hint.style.display = 'inline';
            }
        });
    };
    
    self.initEvents();
};
 
CustomPlaceholder.prototype = {
    createHintLabel: function(text, position){
        var hint = $c('label');
        hint.style.cusor = 'text';
        hint.style.position = 'absolute';
        hint.style.left = position.left + this.option.xOffset + 'px';
        hint.style.top = position.top + this.option.yOffset + 'px';
        hint.innerHTML = text;
        hint.style.zIndex = '9999';
        return hint;
    },
    position: function(){
        var position = getPositionInDoc(this.input);
        this.hint.style.left = position.left + this.option.xOffset + 'px';
        this.hint.style.top = position.top + this.option.yOffset + 'px';
    }
};
 
$.fn.placeholder = function(option){
    if(supportProperty('input', 'placeholder')){
        return;
    }
    var customPlaceholders = [];
    if(this.length > 0){
        var box = $c('div', 'dk_placeholderfixed_box');
        for(var i = 0, len = this.length; i < len; i++){
            var input = this[i];
            if($(input).is(':visible')){
                customPlaceholders.push(new CustomPlaceholder(box, input, option));
            }
        }
        
        document.body.appendChild(box);
    }
    
    $(window).bind( 'resize', function(e){
        for(var i = 0, len = customPlaceholders.length; i < len; i++){
            var customPlaceholder = customPlaceholders[i];
            customPlaceholder.position();
        }
        
    });
};
 
})(jQuery);