OpenLayers学习4-工具类Util_1

本来想直接看OpenLayers.Map对象(7277行), 然后按着使用api的顺序继续读代码
后来看了下估计直接看看不懂, 先扫一扫零碎和独立的代码吧.

最独立的应该就是Util 先从Util开始, 预计Util写两到三篇(看了三分之一就感觉收获颇丰, 真tmNb)

OpenLayers这块的代码比较朴实, 没用那么多花招, 拣几个说说:

一:零杂

1
2
//命名空间, Util里都是静态方法 如: OpenLayers.Util.getElement = func...
OpenLayers.Util = OpenLayers.Util || {};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//判断nodeType来确定节点是不是Element
//jq里也用了好些nodeType判断, 判断Element,文本一类的
OpenLayers.Util.isElement = function(o) {
return !!(o && o.nodeType === 1);
};
//相当于判断 a."toString" === '[object Array]'
//相较而言instanceof不准, 比如在不同的 iframe里原型链不同, instanceof总是返回false
OpenLayers.Util.isArray = function(a) {
return (Object.prototype.toString.call(a) === '[object Array]');
};
//slice没什么可说的, 不过真正的用意是最后返回原数组
OpenLayers.Util.removeItem = function(array, item) {
for(var i = array.length - 1; i >= 0; i--) {
if(array[i] == item) {
array.splice(i,1);
//break;more than once??
}
}
return array;//删完返回原数组
};

二: DOM操作集合

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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/**
* Function: getElement
* 从prototype.js里抄来的$()
*
* Parameters:
* 多个DOM元素id组成的数组
*
* Returns:
* 查找结果, 单个DOM(或多个DOM组成的数组)
*/
OpenLayers.Util.getElement = function() {
var elements = [];
for (var i=0, len=arguments.length; i<len; i++) {
//传参数组的其中一个
var element = arguments[i];
//string型的id
if (typeof element == 'string') {
element = document.getElementById(element);
}
//返回唯一一个
if (arguments.length == 1) {
return element;
}
elements.push(element);
}
//返回多个
return elements;
};
/**
* Function: 新建DIV 设置一些属性, Null的传参不设置
* Note - zIndex is NOT set on the resulting div.
*
* Parameters:
* id - {String} 元素的id, 要是没传 就自动生成一个id, "."会替换成"_"
* px - {<OpenLayers.Pixel>|Object} 元素的left 和 top ,
* OpenLayers.Pixel 或者有"x"和"y"的对象
* sz - {<OpenLayers.Size>|Object} 元素的width 和 height,
* OpenLayers.Size 或者有"x"和"h"的对象
* imgURL - {String} background img的url
* position - {String} The style.position value. eg: absolute,
* relative etc.
* border - {String} The the style.border value.
* eg: 2px solid black
* overflow - {String} The style.overflow value. Eg. hidden
* opacity - {Float} Fractional value (0.0 - 1.0)
*
* Returns:
* {DOMElement} A DOM Div created with the specified attributes.
*/
OpenLayers.Util.createDiv = function(id, px, sz, imgURL, position,
border, overflow, opacity) {
var dom = document.createElement('div');
if (imgURL) {
dom.style.backgroundImage = 'url(' + imgURL + ')';
}
//set generic properties
if (!id) {
id = OpenLayers.Util.createUniqueID("OpenLayersDiv");//自动生成一个id
}
if (!position) {
position = "absolute";
}
//修改DOM对象
OpenLayers.Util.modifyDOMElement(dom, id, px, sz, position,
border, overflow, opacity);
return dom;
};
/**
* Function: modifyDOMElement
*
* 一次修改DOM元素的多个属性. 传null的参数将不会设置
*
* Parameters:
* element - {DOMElement} 要修改的DOM元素
* id - {String} 给DOM元素赋的id值, 参数中的"."会被换成"_"
* px - {<OpenLayers.Pixel>|Object} 元素的left 和 top ,
* OpenLayers.Pixel 或者有"x"和"y"的对象
* sz - {<OpenLayers.Size>|Object} 元素的width 和 height,
* OpenLayers.Size 或者有"x"和"h"的对象
* position - {String} position 值如: absolute, relative, etc.
* border - {String} style.border属性. 如:solid black 2px
*
* overflow - {String} style.overview属性.
* opacity - {Float} 透明度 (0.0 - 1.0)
*/
OpenLayers.Util.modifyDOMElement = function(element, id, px, sz, position,
border, overflow, opacity) {
if (id) {
element.id = id.replace(OpenLayers.Util.dotless, "_");//id中的"."将会换成"_"
}
if (px) {
element.style.left = px.x + "px";//left , top
element.style.top = px.y + "px";
}
if (sz) {
element.style.width = sz.w + "px";//width , height
element.style.height = sz.h + "px";
}
if (position) {
element.style.position = position;//absolute什么的
}
if (border) {
element.style.border = border;//边框的字串
}
if (overflow) {
element.style.overflow = overflow;//overflow
}
if (parseFloat(opacity) >= 0.0 && parseFloat(opacity) < 1.0) {
element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')';//IE兼容
element.style.opacity = opacity;
} else if (parseFloat(opacity) == 1.0) {
element.style.filter = '';//1.0就不设置了
element.style.opacity = '';
}
};
/**
* delayDisplay - {Boolean} true的话会预加载
*/
OpenLayers.Util.createImage = function(id, px, sz, imgURL, position, border,
opacity, delayDisplay) {
var image = document.createElement("img");
//没指定ID就自动生成一个
if (!id) {
id = OpenLayers.Util.createUniqueID("OpenLayersDiv");
}
if (!position) {
position = "relative";//默认position
}
OpenLayers.Util.modifyDOMElement(image, id, px, sz, position,
border, null, opacity);//图片没有overflow
if (delayDisplay) {
image.style.display = "none";//先隐藏
function display() {//事先定义一个函数, 隐藏+停止事件传播
image.style.display = "";
OpenLayers.Event.stopObservingElement(image);
}
OpenLayers.Event.observe(image, "load", display);//图片load事件和error都运行上述函数
OpenLayers.Event.observe(image, "error", display);
}
//默认提示
image.style.alt = id;
image.galleryImg = "no";//IE里设置是否显示图片工具条(图片下方复制打印什么的)
if (imgURL) {
image.src = imgURL;
}
return image;
};
//IE 5.5 至 IE7 可以用alpha
OpenLayers.Util.alphaHack = function() {
if (OpenLayers.Util.alphaHackNeeded == null) {
var arVersion = navigator.appVersion.split("MSIE");
var version = parseFloat(arVersion[1]);
var filter = false;
try {
filter = !!(document.body.filters);//防止查不着, try-catch
} catch (e) {}
OpenLayers.Util.alphaHackNeeded = (filter &&
(version >= 5.5) && (version < 7));
}
return OpenLayers.Util.alphaHackNeeded;
};
//OpenLayers.Util.applyDefaults和OpenLayers.Util.extend()貌似一样

三: URL操作

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
//我还以为是从URL拿传参呢...,
//其实是吧键值对的对象, 转成字串, 做拼接URL的准备工作
OpenLayers.Util.getParameterString = function(params) {
var paramsArray = [];
for (var key in params) {
//遍历传入对象的k-v
var value = params[key];
//筛选, 过滤掉function
if ((value != null) && (typeof value != 'function')) {
var encodedValue;
//如果是数组要遍历
if (typeof value == 'object' && value.constructor == Array) {
var encodedItemArray = [];
var item;
for (var itemIndex=0, len=value.length; itemIndex<len; itemIndex++) {
item = value[itemIndex];
//数组的话,每个元非空元素要写入结果数组
encodedItemArray.push(encodeURIComponent(
(item === null || item === undefined) ? "" : item)
);
}
//字串用逗号连接
encodedValue = encodedItemArray.join(",");
}
else {
//最简单的字串
encodedValue = encodeURIComponent(value);
}
//格式: key1=value1
paramsArray.push(encodeURIComponent(key) + "=" + encodedValue);
}
}
//格式key1=value1 & key2=value2 ...
return paramsArray.join("&");
};
//拼接URL
OpenLayers.Util.urlAppend = function(url, paramStr) {
var newUrl = url;
if(paramStr) {
//现在原有url最后加了一个空格, 作为结尾符
var parts = (url + " ").split(/[?&]/);
//
newUrl += (parts.pop() === " " ?
paramStr : //若是结尾符,就加上新传入的参数字串
parts.length ? "&" + paramStr : "?" + paramStr);//若不是结尾符, 且parts.pop没了, 就得加?, 不然补&
}
return newUrl;
};
//取得images的路径
OpenLayers.Util.getImagesLocation = function() {
return OpenLayers.ImgPath || (OpenLayers._getScriptLocation() + "img/");
};
//这个路径获取比较有意思, 去所有<script>标签里找带OpenLayers*.js字样的, 然后把路径切出来
_getScriptLocation: (function() {
var r = new RegExp("(^|(.*?\\/))(OpenLayers[^\\/]*?\\.js)(\\?|$)"),
s = document.getElementsByTagName('script'),
src, m, l = "";
for(var i=0, len=s.length; i<len; i++) {
src = s[i].getAttribute('src');
if(src) {
m = src.match(r);
if(m) {
l = m[1];
break;
}
}
}
return (function() { return l; });
})(),

四: Try

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//遍历执行传参中的表达式, 直到其中一个不抛异常了, 就返回结果值(吞掉之前异常 不打断流程).
OpenLayers.Util.Try = function() {
var returnValue = null;
for (var i=0, len=arguments.length; i<len; i++) {
//传参都应该是function(){...}, 可能不是对用户的接口 所以没做类型检查
var lambda = arguments[i];
try {
//执行表达式
returnValue = lambda();
//只有执行完不报异常, 才会break
break;
} catch (e) {}//执行时异常了, 那吞掉, 继续遍历
}
//返回第一个非异常的结果, 要是没有就返回null
return returnValue;
};