Statistiques
| Révision :

root / tei / js / jquery.positionBy.js @ 2

Historique | Voir | Annoter | Télécharger (8,39 ko)

1
/*
2
 * positionBy 1.0.7 (2008-01-29)
3
 *
4
 * Copyright (c) 2006,2007 Jonathan Sharp (http://jdsharp.us)
5
 * Dual licensed under the MIT (MIT-LICENSE.txt)
6
 * and GPL (GPL-LICENSE.txt) licenses.
7
 *
8
 * http://jdsharp.us/
9
 *
10
 * Built upon jQuery 1.2.2 (http://jquery.com)
11
 * This also requires the jQuery dimensions plugin
12
 */
13
(function($){
14
        /**
15
         * This function centers an absolutely positioned element
16
         */
17
        /*
18
        $.fn.positionCenter = function(offsetLeft, offsetTop) {
19
                var offsetLeft         = offsetLeft || 1;
20
                var offsetTop         = offsetTop || 1;
21

22
                var ww = $(window).width();
23
                var wh = $(window).height();
24
                var sl = $(window).scrollLeft();
25
                var st = $(window).scrollTop();
26

27
                return this.each(function() {
28
                        var $t = $(this);
29
                        
30
                        // If we are not visible we have to display our element (with a negative position offscreen)
31

32
                        var left = Math.round( ( ww - $t.outerWidth() ) / 2 );
33
                        if ( left < 0 ) {
34
                                left = 0;
35
                        } else {
36
                                left *= offsetLeft;
37
                        }
38
                        left += sl;
39
                        var top  = Math.round( ( wh - $t.outerHeight() ) / 2 );
40
                        if ( top < 0 ) {
41
                                top = 0;
42
                        } else {
43
                                top *= offsetTop;
44
                        }
45
                        top += st;
46

47
                        $(this).parents().each(function() {
48
                                var $this = $(this);
49
                                if ( $this.css('position') != 'static' ) {
50
                                        var o = $this.offset();
51
                                        left += -o.left;
52
                                        top         += -o.top;
53
                                        return false;
54
                                }
55
                        });
56

57
                        $t.css({left: left, top: top});
58
                });
59
        };
60
        */
61
        
62
        // Our range object is used in calculating positions
63
        var Range = function(x1, y1, x2, y2) {
64
                this.x1        = x1;        this.x2 = x2;
65
                this.y1 = y1;        this.y2 = y2;
66
        };
67
        Range.prototype.contains = function(range) {
68
                return         (this.x1 <= range.x1 && range.x2 <= this.x2) 
69
                                && 
70
                                (this.y1 <= range.y1 && range.y2 <= this.y2);
71
        };
72
        Range.prototype.transform = function(x, y) {
73
                return new Range(this.x1 + x, this.y1 + y, this.x2 + x, this.y2 + y);
74
        };
75

    
76
        $.fn.positionBy = function(args) {
77
                var date1 = new Date();
78
                if ( this.length == 0 ) {
79
                        return this;
80
                }
81
                
82
                var args = $.extend({        // The target element to position us relative to
83
                                                                target:                null,
84
                                                                // The target's corner, possible values 0-3
85
                                                                targetPos:        null,
86
                                                                // The element's corner, possible values 0-3
87
                                                                elementPos:        null,
88
                                                                
89
                                                                // A raw x,y coordinate
90
                                                                x:                        null,
91
                                                                y:                        null,
92

    
93
                                                                // Pass in an array of positions that are valid 0-15
94
                                                                positions:        null,
95

    
96
                                                                // Add the final position class to the element (eg. positionBy0 through positionBy3, positionBy15)
97
                                                                addClass:         false,
98
                                                                
99
                                                                // Force our element to be at the location we specified (don't try to auto position it)
100
                                                                force:                 false,
101
                                                                
102
                                                                // The element that we will make sure our element doesn't go outside of
103
                                                                container:         window,
104

    
105
                                                                // Should the element be hidden after positioning?
106
                                                                hideAfterPosition: false
107
                                                        }, args);
108

    
109
                if ( args.x != null ) {
110
                        var tLeft        = args.x;
111
                        var tTop        = args.y;
112
                        var tWidth        = 0;
113
                        var tHeight        = 0;
114
                        
115
                // Position in relation to an element
116
                } else {
117
                        var $target        = $( $( args.target )[0] );
118
                        var tWidth        = $target.outerWidth();
119
                        var tHeight        = $target.outerHeight();
120
                        var tOffset        = $target.offset();
121
                        var tLeft        = tOffset.left;
122
                        var tTop        = tOffset.top;
123
                }
124

    
125
                // Our target right, bottom coord
126
                var tRight        = tLeft + tWidth;
127
                var tBottom        = tTop + tHeight;
128

    
129
                return this.each(function() {
130
                        var $element = $( this );
131

    
132
                        // Position our element in the top left so we can grab its width without triggering scrollbars
133
                        if ( !$element.is(':visible') ) {
134
                                $element.css({        left:                  -3000, 
135
                                                                top:                 -3000
136
                                                                })
137
                                                                .show();
138
                        }
139

    
140
                        var eWidth        = $element.outerWidth();
141
                        var eHeight        = $element.outerHeight();
142
        
143
                        // Holds x1,y1,x2,y2 coordinates for a position in relation to our target element
144
                        var position = [];
145
                        // Holds a list of alternate positions to try if this one is not in the browser viewport
146
                        var next         = [];
147
        
148
                        // Our Positions via ASCII ART
149
                        /*
150
                          8   9       10   11
151
                           +------------+
152
                         7 | 15      12 | 0
153
                           |            |
154
                         6 | 14      13 | 1
155
                           +------------+ 
156
                         5   4        3   2
157
        
158
                         */
159

    
160
                        position[0]        = new Range(tRight,                         tTop,                                 tRight + eWidth,         tTop + eHeight);
161
                        next[0]                = [1,7,4];
162
                
163
                        position[1]        = new Range(tRight,                         tBottom - eHeight,         tRight + eWidth,         tBottom);
164
                        next[1]                = [0,6,4];
165
                
166
                        position[2] = new Range(tRight,                         tBottom,                        tRight + eWidth,         tBottom + eHeight);
167
                        next[2]                = [1,3,10];
168
                
169
                        position[3] = new Range(tRight - eWidth,         tBottom,                        tRight,                         tBottom + eHeight);
170
                        next[3]                = [1,6,10];
171
                        
172
                        position[4] = new Range(tLeft,                                 tBottom,                        tLeft + eWidth,         tBottom + eHeight);
173
                        next[4]                = [1,6,9];
174
                
175
                        position[5] = new Range(tLeft - eWidth,         tBottom,                         tLeft,                                 tBottom + eHeight);
176
                        next[5]                = [6,4,9];
177
                
178
                        position[6] = new Range(tLeft - eWidth,         tBottom - eHeight,        tLeft,                                 tBottom);
179
                        next[6]                = [7,1,4];
180
                        
181
                        position[7] = new Range(tLeft - eWidth,         tTop,                                tLeft,                                 tTop + eHeight);
182
                        next[7]                = [6,0,4];
183
                        
184
                        position[8] = new Range(tLeft - eWidth,         tTop - eHeight,                tLeft,                                 tTop);
185
                        next[8]                = [7,9,4];
186
                        
187
                        position[9] = new Range(tLeft,                                 tTop - eHeight,                tLeft + eWidth,         tTop);
188
                        next[9]                = [0,7,4];
189
                        
190
                        position[10]= new Range(tRight - eWidth,         tTop - eHeight,                tRight,                         tTop);
191
                        next[10]        = [0,7,3];
192
                
193
                        position[11]= new Range(tRight,                         tTop - eHeight,         tRight + eWidth,         tTop);
194
                        next[11]        = [0,10,3];
195
                        
196
                        position[12]= new Range(tRight - eWidth,         tTop,                                tRight,                         tTop + eHeight);
197
                        next[12]        = [13,7,10];
198
                        
199
                        position[13]= new Range(tRight - eWidth,         tBottom - eHeight,        tRight,                         tBottom);
200
                        next[13]        = [12,6,3];
201
                        
202
                        position[14]= new Range(tLeft,                                 tBottom - eHeight,        tLeft + eWidth,         tBottom);
203
                        next[14]        = [15,1,4];
204
                        
205
                        position[15]= new Range(tLeft,                                 tTop,                                tLeft + eWidth,         tTop + eHeight);
206
                        next[15]        = [14,0,9];
207
        
208
                        if ( args.positions !== null ) {
209
                                var pos = args.positions[0];
210
                        } else if ( args.targetPos != null && args.elementPos != null ) {
211
                                var pos = [];
212
                                pos[0] = [];
213
                                pos[0][0] = 15;
214
                                pos[0][1] = 7;
215
                                pos[0][2] = 8;
216
                                pos[0][3] = 9;
217
                                pos[1] = [];
218
                                pos[1][0] = 0;
219
                                pos[1][1] = 12;
220
                                pos[1][2] = 10;
221
                                pos[1][3] = 11;
222
                                pos[2] = [];
223
                                pos[2][0] = 2;
224
                                pos[2][1] = 3;
225
                                pos[2][2] = 13;
226
                                pos[2][3] = 1;
227
                                pos[3] = [];
228
                                pos[3][0] = 4;
229
                                pos[3][1] = 5;
230
                                pos[3][2] = 6;
231
                                pos[3][3] = 14;
232

    
233
                                var pos = pos[args.targetPos][args.elementPos];
234
                        }
235
                        var ePos = position[pos];
236
                        var fPos = pos;
237

    
238
                        if ( !args.force ) {
239
                                // TODO: Do the args.container
240
                                // window width & scroll offset
241
                                $window = $( window );
242
                                var sx = $window.scrollLeft();
243
                                var sy = $window.scrollTop();
244
                                
245
                                // TODO: Look at innerWidth & innerHeight
246
                                var container = new Range( sx, sy, sx + $window.width(), sy + $window.height() );
247
        
248
                                // If we are outside of our viewport, see if we are outside vertically or horizontally and push onto the stack
249
                                var stack;
250
                                if ( args.positions ) {
251
                                        stack = args.positions;
252
                                } else {
253
                                        stack = [pos];
254
                                }
255
                                var test = [];                // Keeps track of our positions we already tried
256
                                
257
                                while ( stack.length > 0 ) {
258
                                        var p = stack.shift();
259
                                        if ( test[p] ) {
260
                                                continue;
261
                                        }
262
                                        test[p] = true;
263
        
264
                                        // If our current position is not within the viewport (eg. window) 
265
                                        // add the next suggested position
266
                                        if ( !container.contains(position[p]) ) {
267
                                                if ( args.positions === null ) {
268
                                                        stack = jQuery.merge( stack, next[p] );
269
                                                }
270
                                        } else {
271
                                                ePos = position[p];
272
                                                break;
273
                                        }
274
                                }
275
                        }
276

    
277
                        // + TODO: Determine if we are going to use absolute left, top, bottom, right 
278
                        // positions relative to our target
279
                
280
                        // Take into account any absolute or fixed positioning
281
                        // to 'normalize' our coordinates
282
                        $element.parents().each(function() {
283
                                var $this = $(this);
284
                                if ( $this.css('position') != 'static' ) {
285
                                        var abs = $this.offset();
286
                                        ePos = ePos.transform( -abs.left, -abs.top );
287
                                        return false;
288
                                }
289
                        });
290
                
291
                        // Finally position our element
292
                        var css = { left: ePos.x1, top: ePos.y1 };
293
                        if ( args.hideAfterPosition ) {
294
                                css['display'] = 'none';
295
                        }
296
                        $element.css( css );
297

    
298
                        if ( args.addClass ) {
299
                                $element.removeClass( 'positionBy0 positionBy1 positionBy2 positionBy3 positionBy4 positionBy5 '
300
                                                                        + 'positionBy6 positionBy7 positionBy8 positionBy9 positionBy10 positionBy11 '
301
                                                                        + 'positionBy12 positionBy13 positionBy14 positionBy15')
302
                                                .addClass('positionBy' + p);
303
                        }
304
                });
305
        };
306
})(jQuery);