OpenLayers学习6-工具类Util_3

一: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
//获取viewport元素
//除了IE都是document.documentElement(XHTML)
//IE有两种可能: 可能是document.body(没doctype), 或document.documentElement(XHTML);
OpenLayers.Util.getViewportElement = function() {
var viewportElement = arguments.callee.viewportElement;
if (viewportElement == undefined) {
viewportElement = (OpenLayers.BROWSER_NAME == "msie" &&
document.compatMode != 'CSS1Compat') ? document.body :
document.documentElement;
arguments.callee.viewportElement = viewportElement;
}
return viewportElement;
};
//计算一个DOM元素在页面上的位置(隐藏的元素返回0,0)
//结果是数组[left, top]
OpenLayers.Util.pagePosition = function(forElement) {
//
var pos = [0, 0];
var viewportElement = OpenLayers.Util.getViewportElement();
if (!forElement || forElement == window || forElement == viewportElement) {
//根对象和window返回0,0
return pos;
}
// 判断是否是Gecko内核,
//查了一下FF 3.6之前的Gecko内核使用document.getBoxObjectFor
var BUGGY_GECKO_BOX_OBJECT =
OpenLayers.IS_GECKO && document.getBoxObjectFor &&
OpenLayers.Element.getStyle(forElement, 'position') == 'absolute' &&
(forElement.style.top == '' || forElement.style.left == '');
var parent = null;
var box;
if (forElement.getBoundingClientRect) { // IE
//其实IE6+都支持, 包括ff和chrome等
box = forElement.getBoundingClientRect();
var scrollTop = window.pageYOffset || viewportElement.scrollTop;
var scrollLeft = window.pageXOffset || viewportElement.scrollLeft;
pos[0] = box.left + scrollLeft;
pos[1] = box.top + scrollTop;
} else if (document.getBoxObjectFor && !BUGGY_GECKO_BOX_OBJECT) { // gecko
//估计新的ff到不了这个判断了
box = document.getBoxObjectFor(forElement);
var vpBox = document.getBoxObjectFor(viewportElement);
pos[0] = box.screenX - vpBox.screenX;
pos[1] = box.screenY - vpBox.screenY;
} else { // safari/opera
pos[0] = forElement.offsetLeft;
pos[1] = forElement.offsetTop;
parent = forElement.offsetParent;
if (parent != forElement) {
while (parent) {
pos[0] += parent.offsetLeft;
pos[1] += parent.offsetTop;
parent = parent.offsetParent;
}
}
var browser = OpenLayers.BROWSER_NAME;
//减掉body.offsetTop
if (browser == "opera" || (browser == "safari" &&
OpenLayers.Element.getStyle(forElement, 'position') == 'absolute')) {
pos[1] -= document.body.offsetTop;
}
//处理滚动的情况(body不减scrollLeft和scrollTop)
parent = forElement.offsetParent;
while (parent && parent != document.body) {
pos[0] -= parent.scrollLeft;
if (browser != "opera" || parent.tagName != 'TR') {
pos[1] -= parent.scrollTop;
}
parent = parent.offsetParent;
}
}
return pos;
};

二: 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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//返回url+ port+ args
/*
* Valid options:
* ignoreCase - {Boolean} lowercase url,
* ignorePort80 - {Boolean} don't include explicit port if port is 80,
* ignoreHash - {Boolean} Don't include part of url after the hash (#).
* splitArgs - {Boolean} Split comma delimited params into arrays? Default is
* true.
*/
OpenLayers.Util.createUrlObject = function(url, options) {
options = options || {};
// 不是以"字串://"开头
if(!(/^\w+:\/\//).test(url)) {
var loc = window.location;
var port = loc.port ? ":" + loc.port : "";
//组装完整url
//host.split(":")先按冒号切成数组, shift()把[1]也就是冒号后边的端口号给弹出
var fullUrl = loc.protocol + "//" + loc.host.split(":").shift() + port;
if(url.indexOf("/") === 0) {
//相对路径, 第一位是"/"
url = fullUrl + url;
} else {
//相对路径, 第一位不是"/", 组装一下
var parts = loc.pathname.split("/");
parts.pop();
url = fullUrl + parts.join("/") + "/" + url;
}
}
//忽略大小写, 就都转成小写
if (options.ignoreCase) {
url = url.toLowerCase();
}
//新建a标签DOM, 借用a处理url
var a = document.createElement('a');
a.href = url;
var urlObject = {};
//去掉host:port中的端口号
urlObject.host = a.host.split(":").shift();
//协议名
urlObject.protocol = a.protocol;
//追加80端口
if(options.ignorePort80) {
urlObject.port = (a.port == "80" || a.port == "0") ? "" : a.port;
} else {
urlObject.port = (a.port == "" || a.port == "0") ? "80" : a.port;
}
//井号
urlObject.hash = (options.ignoreHash || a.hash === "#") ? "" : a.hash;
//args
var queryString = a.search;
if (!queryString) {
var qMark = url.indexOf("?");
queryString = (qMark != -1) ? url.substr(qMark) : "";
}
urlObject.args = OpenLayers.Util.getParameters(queryString,
{splitArgs: options.splitArgs});
//针对IE, 第一位不是斜杠, 补一个"/"
urlObject.pathname = (a.pathname.charAt(0) == "/") ? a.pathname : "/" + a.pathname;
return urlObject;
};
//清掉url里"?"或"&"末尾的字串
OpenLayers.Util.removeTail = function(url) {
var head = null;
var qMark = url.indexOf("?");
var hashMark = url.indexOf("#");
if (qMark == -1) {
//没问号的, 有井号, 就截井号
head = (hashMark != -1) ? url.substr(0,hashMark) : url;
} else {
//有问号, 有井号, 用Math.min判断下哪个在前, 截取
head = (hashMark != -1) ? url.substr(0,Math.min(qMark, hashMark))
: url.substr(0, qMark);
}
return head;
};

三:浏览器兼容检测

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
//从userAgent判断是不是gecko内核
OpenLayers.IS_GECKO = (function() {
var ua = navigator.userAgent.toLowerCase();
return ua.indexOf("webkit") == -1 && ua.indexOf("gecko") != -1;
})();
//测试是否支持canvas
//反正如果支持canvas的话也不用考虑内存回收的问题
OpenLayers.CANVAS_SUPPORTED = (function() {
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
})();
//配置项: 立即执行从navigator.userAgent获取浏览器名称
OpenLayers.BROWSER_NAME = (function() {
var name = "";
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf("opera") != -1) {
name = "opera";
} else if (ua.indexOf("msie") != -1) {
name = "msie";
} else if (ua.indexOf("safari") != -1) {
name = "safari";
} else if (ua.indexOf("mozilla") != -1) {
if (ua.indexOf("firefox") != -1) {
name = "firefox";
} else {
name = "mozilla";
}
}
return name;
})();
//获取配置项
OpenLayers.Util.getBrowserName = function() {
return OpenLayers.BROWSER_NAME;
};