深圳地鐵羅寶線和蛇口線示例:見上圖。
要求瀏覽器版本:browser does support HTML5 canvas element:Google Chrome V 8+;Mozilla Firefox V 3.6+;Opera V 11+;Apple Safari V 5+;Microsoft Internet Explorer V 9+。
javascript:
Copyright (c) 2010 Nik Kalyani nik@kalyani.com http://www.kalyani.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
(function ($) {
var plugin = {
defaults: {
debug: false,
grid: false
},
options: {
},
identity: function (type) {
if (type === undefined) type = "name";
switch (type.toLowerCase()) {
case "version": return "1.0.0"; break;
default: return "subwayMap Plugin"; break;
}
},
_debug: function (s) {
if (this.options.debug)
this._log(s);
},
_log: function () {
if (window.console && window.console.log)
window.console.log('[subwayMap] ' + Array.prototype.join.call(arguments, ' '));
},
_supportsCanvas: function () {
var canvas = $("<canvas></canvas>");
if (canvas[0].getContext)
return true;
else
return false;
},
_getCanvasLayer: function (el, overlay) {
this.layer++;
var canvas = $("<canvas + ((overlay ? 2000 : 1000) + this.layer) + "' width='" + this.options.pixelWidth + "' height='" + this.options.pixelHeight + "'></canvas>");
el.append(canvas);
return (canvas[0].getContext("2d"));
},
_render: function (el) {
this.layer = -1;
var rows = el.attr("data-rows");
if (rows === undefined)
rows = 10;
else
rows = parseInt(rows);
var columns = el.attr("data-columns");
if (columns === undefined)
columns = 10;
else
columns = parseInt(columns);
var scale = el.attr("data-cellSize");
if (scale === undefined)
scale = 100;
else
scale = parseInt(scale);
var lineWidth = el.attr("data-lineWidth");
if (lineWidth === undefined)
lineWidth = 10;
else
lineWidth = parseInt(lineWidth);
var textClass = el.attr("data-textClass");
if (textClass === undefined) textClass = "";
var grid = el.attr("data-grid");
if ((grid === undefined) || (grid.toLowerCase() == "false"))
grid = false;
else
grid = true;
var legendId = el.attr("data-legendId");
if (legendId === undefined) legendId = "";
var gridNumbers = el.attr("data-gridNumbers");
if ((gridNumbers === undefined) || (gridNumbers.toLowerCase() == "false"))
gridNumbers = false;
else
gridNumbers = true;
var reverseMarkers = el.attr("data-reverseMarkers");
if ((reverseMarkers === undefined) || (reverseMarkers.toLowerCase() == "false"))
reverseMarkers = false;
else
reverseMarkers = true;
this.options.pixelWidth = columns * scale;
this.options.pixelHeight = rows * scale;
//el.css("width", this.options.pixelWidth);
//el.css("height", this.options.pixelHeight);
self = this;
var lineLabels = [];
var supportsCanvas = $("<canvas></canvas>")[0].getContext;
if (supportsCanvas) {
if (grid) this._drawGrid(el, scale, gridNumbers);
$(el).children("ul").each(function (index) {
var ul = $(this);
var color = $(ul).attr("data-color");
if (color === undefined) color = "#000000";
var lineTextClass = $(ul).attr("data-textClass");
if (lineTextClass === undefined) lineTextClass = "";
var shiftCoords = $(ul).attr("data-shiftCoords");
if (shiftCoords === undefined) shiftCoords = "";
var shiftX = 0.00;
var shiftY = 0.00;
if (shiftCoords.indexOf(",") > -1) {
shiftX = parseInt(shiftCoords.split(",")[0]) * lineWidth/scale;
shiftY = parseInt(shiftCoords.split(",")[1]) * lineWidth/scale;
}
var lineLabel = $(ul).attr("data-label");
if (lineLabel === undefined)
lineLabel = "Line " + index;
lineLabels[lineLabels.length] = {label: lineLabel, color: color};
var nodes = [];
$(ul).children("li").each(function () {
var coords = $(this).attr("data-coords");
if (coords === undefined) coords = "";
var dir = $(this).attr("data-dir");
if (dir === undefined) dir = "";
var labelPos = $(this).attr("data-labelPos");
if (labelPos === undefined) labelPos = "s";
var marker = $(this).attr("data-marker");
if (marker == undefined) marker = "";
var markerInfo = $(this).attr("data-markerInfo");
if (markerInfo == undefined) markerInfo = "";
var anchor = $(this).children("a:first-child");
var label = $(this).text();
if (label === undefined) label = "";
var link = "";
var title = "";
if (anchor != undefined) {
link = $(anchor).attr("href");
if (link === undefined) link = "";
title = $(anchor).attr("title");
if (title === undefined) title = "";
}
self._debug("Coords=" + coords + "; Dir=" + dir + "; Link=" + link + "; Label=" + label + "; labelPos=" + labelPos + "; Marker=" + marker);
var x = "";
var y = "";
if (coords.indexOf(",") > -1) {
x = Number(coords.split(",")[0]) + (marker.indexOf("interchange") > -1 ? 0 : shiftX);
y = Number(coords.split(",")[1]) + (marker.indexOf("interchange") > -1 ? 0 : shiftY);
}
nodes[nodes.length] = { x: x, y:y, direction: dir, marker: marker, markerInfo: markerInfo, link: link, title: title, label: label, labelPos: labelPos};
});
if (nodes.length > 0)
self._drawLine(el, scale, rows, columns, color, (lineTextClass != "" ? lineTextClass : textClass), lineWidth, nodes, reverseMarkers);
$(ul).remove();
});
if ((lineLabels.length > 0) && (legendId != ""))
{
var legend = $("#" + legendId);
for(var line=0; line<lineLabels.length; line++)
legend.append("<div><span + lineWidth + "px;background-color:" + lineLabels[line].color + "'></span>" + lineLabels[line].label + "</div>");
}
}
},
_drawLine: function (el, scale, rows, columns, color, textClass, width, nodes, reverseMarkers) {
var ctx = this._getCanvasLayer(el, false);
ctx.beginPath();
ctx.moveTo(nodes[0].x * scale, nodes[0].y * scale);
var markers = [];
var lineNodes = [];
for(var node = 0; node < nodes.length; node++)
{
if (nodes[node].marker.indexOf("@") != 0)
lineNodes[lineNodes.length] = nodes[node];
}
for (var lineNode = 0; lineNode < lineNodes.length; lineNode++) {
if (lineNode < (lineNodes.length - 1)) {
接口
nodeType常量
nodeType值
备注
Element
Node.ELEMENT_NODE
1
元素节点
Text
Node.TEXT_NODE
3
文本节点
Document
Node.DOCUMENT_NODE
9
document
Comment
Node.COMMENT_NODE
8
注释的文本
DocumentFragment
Node.DOCUMENT_FRAGMENT_NODE
11
document片断
Attr
Node.ATTRIBUTE_NODE
2
节点属性
方法
描述
createAttribute()
用指定的名字创建新的Attr节点。
createComment()
用指定的字符串创建新的Comment节点。
createElement()
用指定的标记名创建新的Element节点。
createTextNode()
用指定的文本创建新的TextNode节点。
getElementById()
返回文档中具有指定id属性的Element节点。
getElementsByTagName()
返回文档中具有指定标记名的所有Element节点。
属性
描述
attributes
如果该节点是一个Element,则以NamedNodeMap形式返回该元素的属性。
childNodes
以Node[]的形式存放当前节点的子节点。如果没有子节点,则返回空数组。
firstChild
以Node的形式返回当前节点的第一个子节点。如果没有子节点,则为null。
lastChild
以Node的形式返回当前节点的最后一个子节点。如果没有子节点,则为null。
nextSibling
以Node的形式返回当前节点的兄弟下一个节点。如果没有这样的节点,则返回null。下一个兄弟节点
nodeName
节点的名字,Element节点则代表Element的标记名称。
nodeType
代表节点的类型。
parentNode
以Node的形式返回当前节点的父节点。如果没有父节点,则为null。
previousSibling
以Node的形式返回紧挨当前节点、位于它之前的兄弟节点。如果没有这样的节点,则返回null。上一个兄弟节点
方法
描述
appendChild()
通过把一个节点增加到当前节点的childNodes[]组,给文档树增加节点。
cloneNode()
复制当前节点,或者复制当前节点以及它的所有子孙节点。
hasChildNodes()
如果当前节点拥有子节点,则将返回true。
insertBefore()
给文档树插入一个节点,位置在当前节点的指定子节点之前。如果该节点已经存在,则删除之再插入到它的位置。
removeChild()
从文档树中删除并返回指定的子节点。
replaceChild()
从文档树中删除并返回指定的子节点,用另一个节点替换它。
jQuery的serialize模块中有个r20正则
jQuery.param方法中会将所有的"%20"转成"+",即提交数据前,数据中如果包含空格,那经过encodeURIComponent后,空格会转成"%20"
最后需要将"%20"转换成"="再Post提交。这样后台程序接受到的才是真正的空格。
关于 encodeURIComponent,见MDC描述
encodeURIComponent escapes all characters except the following: alphabetic, decimal digits, - _ . ! ~ * ' ( )
To avoid unexpected requests to the server, you should call encodeURIComponent on any user-entered parameters that will be passed as part of a URI. For example, a user could type "Thyme &time=again" for a variable comment. Not using encodeURIComponent on this variable will give comment=Thyme%20&time=again. Note that the ampersand and the equal sign mark a new key and value pair. So instead of having a POST comment key equal to "Thyme &time=again", you have two POST keys, one equal to "Thyme " and another (time) equal to again.
For application/x-www-form-urlencoded (POST), per http://www.w3.org/TR/html401/interac...m-content-type, spaces are to be replaced by '+', so one may wish to follow a encodeURIComponent replacement with an additional replacement of "%20" with "+".
相关:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent
http://www.w3.org/TR/html401/interact/forms.html#form-content-type
本文链接