leaflet生成地图封装成jquery插件使用
公司业务里一直都有使用leaflet地图插件来做地图展示、绘图等操作。公司有个项目已经有好几年了,由于项目原因一直在使用,今年由于google 地图 api过期,导致已经使用的地图无法加载。我作为现在该项目的维护者,虽然未参与项目的开发阶段,但是事情在我手上了还是要处理的。
上面说到api过期,无法加载地图了。我首先想到的是更换api key,FQ出去,搞了许久,没有成功。想想也是,就我这个英语水平成功就是偶然。当然也不全是英语问题,在我在墙外的世界捣鼓来捣鼓去的时候,隐约的发现谷歌api 有关的认证加强了(事情过了1一个月了,也忘记了)。
在最简单的方法尝试无效后,下定决心重写吧。好,写,一顿搜索猛如虎(差点写成:猛如狗了^_^),最后找了个现成的代码来改吧改吧就可用了。其实改完效果还可以,比以前多了 图层切换功能,而且使用国内地图也不怕哪天项目上说用谷歌不行了。
上面的事情距离我现在写这个文章的时候有一个月了。我是按照用一个项目改一个项目的原则,有些项目无人问津了,我便没改了。按照之前的套路,合并了其他已改项目的分支,项目类似,基本合并无冲突。代码到了现在的项目上了,由于这个项目用到了这套系统且要更新功能,我真nm的欲哭无泪,好老的项目了(用的还是php yii1的框架,前端用的是一框bjui的框架,说起它可能知道的人不多,但是jui框架应该要多点,它就是基于jui的框架)。
埋怨项目老,技术老之后还是要做事,因为在系统升级完成之前必须用它苟延残喘下去。翻看着代码,终于忍不住了,怎么可以这么重复的做某件事呢,难道是对它不想忘记吗? 重复不说,js里面混入php的判断,这些老的套路,越看越那啥了
又吐槽了代码之后,我先来展示一下那些 旋转代码吧(╯﹏╰)
var mainLayer = new L.Google('HYBRID', {
// maxNativeZoom : 3,
// maxZoom : 4,
// minZoom : 3,
// noWrap : true,
errorTileUrl : '<?php echo Yii::app()->baseUrl; ?>/images/tiles/empty.jpg?t=<?php echo time(); ?>',
// continuousWorld : true,
attribution : ''
}); var mainMap = L.map('map', {
zoomControl: false
})
.setView([31.2288614009,104.0252005317], 17)
.addLayer(mainLayer); <?php foreach ($lands as $key => $land) {
if (!empty($land->polygon)) {
$isBindPopup = $hasWarning = 'false';
$labelContent = $land->name;
if ((!empty($land->nodes) && count($land->nodes[0]->tempDataArr > 0) || count($land->devices) > 0)) {
$isBindPopup = 'true';
}
if ($land->hasWarning()) {
$hasWarning = 'true';
$labelContent .= '<br><span style="font-weight:normal; color:#c00;">' . $land->warningMessage . '</span>';
}
?>
land_polygon(<?php echo $land->polygon; ?>, mainMap, '<?php echo $labelContent; ?>', <?php echo $land->id; ?>, <?php echo $isBindPopup; ?>, <?php echo $hasWarning; ?>); <?php } } ?> <?php foreach ($hikvideos as $video) {
if (!empty($video->marker)) {
$isNull = 'true';
if (!empty($video->land->nodes) && count($video->land->nodes[0]->tempDataArr) > 0) {
$isNull = 'false';
} if (BUtils::isLocalClient()) {
$video->ip = $video->local_ip;
$video->http_port = $video->local_http_port;
}
?> videoMarker(mainMap, <?php echo $video->marker; ?>, <?php echo $video->id; ?>, '<?php echo $video->name; ?>', <?php echo CJSON::encode($video); ?>, <?php echo $isNull ?>); <?php } } ?> <?php if (!empty($this->_config['xph_marker'])) {?>
(function weatherStationMarker (map, latLng, labelContent) {
var myIcon = L.divIcon({
iconSize: [50, 67],
className: 'weather-station-marker'
});
var marker = new L.Marker(latLng, {
icon: myIcon
});
map.addLayer(marker);
if (labelContent) {
// marker.bindLabel(labelContent, {noHide: false}).addTo(map);
var label = new L.Label({
noHide: true
});
label.setContent(labelContent).setLatLng({lat: latLng.lat, lng:latLng.lng + 1.4});
map.showLabel(label);
}
marker.on('popupopen', function(event) {
$('#map').bjuiajax('refreshDiv', 'leaflet_land_popup_xph');
}).on('mouseout', function(event) { }).bindPopup(document.getElementById('leaflet_land_popup_xph'), {
minWidth: 500,
className: 'leaflet-popup'
});
})(mainMap, <?php echo $this->_config['xph_marker']; ?>, '气象站');
<?php }?> <?php if (!empty($this->_config['xph_soil_marker'])) {?>
(function soilStationMarker (map, latLng, labelContent) {
var myIcon = L.divIcon({
iconSize: [50, 67],
className: 'soil-station-marker'
});
var marker = new L.Marker(latLng, {
icon: myIcon
});
map.addLayer(marker);
if (labelContent) {
// marker.bindLabel(labelContent, {noHide: false}).addTo(map);
var label = new L.Label({
noHide: true
});
label.setContent(labelContent).setLatLng({lat: latLng.lat, lng:latLng.lng + 1.4});
map.showLabel(label);
}
marker.on('popupopen', function(event) {
$('#map').bjuiajax('refreshDiv', 'leaflet_land_popup_xph_soil');
}).on('mouseout', function(event) { }).bindPopup(document.getElementById('leaflet_land_popup_xph_soil'), {
minWidth: 500,
className: 'leaflet-popup'
});
})(mainMap, <?php echo $this->_config['xph_soil_marker']; ?>, '土壤墒情监测点');
<?php }?> function videoMarker (map, latLng, id, labelContent, videoOption, isNull) {
var myIcon = L.divIcon({
iconSize: [25, 41],
className: 'video-marker'
});
var marker = new L.Marker(latLng, {
icon: myIcon
}); wth = 350;
if (!isNull) {
wth = 800;
} map.addLayer(marker);
if (labelContent) {
marker.bindLabel(labelContent, {noHide: false}).addTo(map);
// var label = new L.Label({
// noHide: true
// });
// label.setContent(labelContent).setLatLng(latLng);
// map.showLabel(label);
}
marker.on('mouseover', function(event) { }).on('mouseout', function(event) { }).bindPopup(document.getElementById('leaflet_video_popup'), {
minWidth: wth,
className: 'leaflet-popup',
}); marker.on('popupopen', function(event) {
setTimeout(function () {
$('#leaflet_video_refresh').show();
$('#leaflet_video_name').text(videoOption.name); video_window = '';
var html = $('#bjui-navtab .tabsPageContent').find('#video_window').html();
if (html) {
video_window = $('#video_window').remove(); $('#leaflet_video_window').html(video_window);
$('#video_window').addClass('video_window'); WebVideoCtrl.I_ChangeWndNum(1);
} videoInit();
videoLogin(videoOption); if (!isNull) {
$('#refresh_land_info').show();
} else {
$('#refresh_land_info').hide();
} $('#leaflet_video_window').bjuiajax('doLoad', {url:"<?php echo $this->createUrl('land/realdata', ['id' => '_ID_']); ?>".replace('_ID_', videoOption.land_id), target:"#refresh_land_info"}); }, 10);
}).on('popupclose', function(event) {
console.log('popupclose', videoOption);
});
} function land_polygon (polygon, map, labelContent, id, isBindPopup, hasWarning) {
var initColor = 'pink',
initOpacity = 0.3,
hoverColor = 'orange',
hoverOpacity = 0.3;
if (hasWarning) {
initColor = 'red';
}
var land = new L.Polygon(polygon, {
weight: 2,
opacity: initOpacity,
fillOpacity: initOpacity,
color: initColor
});
var domId = 'leaflet_land_popup_' + id;
map.addLayer(land);
var label = new L.Label();
label.setContent(labelContent).setLatLng(land.getBounds().getCenter());
map.showLabel(label);
land.on('mouseover', function(event) {
land.setStyle({
color: hoverColor,
opacity: hoverOpacity,
fillOpacity: hoverOpacity,
});
}).on('mouseout', function(event) {
land.setStyle({
color:initColor,
opacity: initOpacity,
fillOpacity: initOpacity,
});
}).on('popupopen', function(event) {
$('#map').bjuiajax('refreshDiv', domId);
}); if (isBindPopup) {
land.bindPopup(document.getElementById(domId), {
minWidth: 500,
className: 'leaflet-popup'
});
}
}
</script>
就这样的代码,能在一个代码里面好几个地方重复出现,你说是有多大的心去维护啊,又难受了。
说了这么的故事,该说重点了,基于上面的情况呢,必须有个什么东西来优化它,想来想去,考虑地图是基于dom生成加载的,那这样的话,写一个jquery的插件应该是比较好的了,当然的话自己封装一个类也行。
对于jquery插件的话,我分享一个网址吧:jquery插件
附上巨人的肩膀
1、ChineseTmsProviders:Leaflet.ChineseTmsProviders
2、tileLayer.baidu
L.CRS.Baidu = new L.Proj.CRS('EPSG:3395', '+proj=merc +lon_0=0 +k=1 +x_0=1440 +y_0=255 +datum=WGS84 +units=m +no_defs', {
resolutions: function () {
level = 19
var res = [];
res[0] = Math.pow(2, 18);
for (var i = 1; i < level; i++) {
res[i] = Math.pow(2, (18 - i))
}
return res;
}(),
origin: [0, 0],
bounds: L.bounds([20037508.342789244, 0], [0, 20037508.342789244])
}); L.tileLayer.baidu = function (option) {
option = option || {}; var layer;
var subdomains = '0123456789';
switch (option.layer) {
//单图层
case "vec":
default:
//'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl&b=0&limit=60&scaler=1&udt=20170525'
layer = L.tileLayer('http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=' + (option.bigfont ? 'ph' : 'pl') + '&scaler=1&p=1', {
name:option.name,subdomains: subdomains, tms: true
});
break;
case "img_d":
layer = L.tileLayer('http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46', {
name: option.name, subdomains: subdomains, tms: true
});
break;
case "img_z":
layer = L.tileLayer('http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=' + (option.bigfont ? 'sh' : 'sl') + '&v=020', {
name: option.name, subdomains: subdomains, tms: true
});
break; case "custom"://Custom 各种自定义样式
//可选值:dark,midnight,grayscale,hardedge,light,redalert,googlelite,grassgreen,pink,darkgreen,bluish
option.customid = option.customid || 'midnight';
layer = L.tileLayer('http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid=' + option.customid, {
name: option.name, subdomains: "012", tms: true
});
break; case "time"://实时路况
var time = new Date().getTime();
layer = L.tileLayer('http://its.map.baidu.com:8002/traffic/TrafficTileService?x={x}&y={y}&level={z}&time=' + time + '&label=web2D&v=017', {
name: option.name, subdomains: subdomains, tms: true
});
break; //合并
case "img":
layer = L.layerGroup([
L.tileLayer.baidu({ name: "底图", layer: 'img_d', bigfont: option.bigfont }),
L.tileLayer.baidu({ name: "注记", layer: 'img_z', bigfont: option.bigfont })
]);
break;
}
return layer;
};
再谈谈我心路吧,其实也是司空见惯的东西了。
- 为了更好的配置,我选择了两种配置,也就是除了自己传递配置参数的话,也可以通过标签属性传递
- 不好解决坐标系问题,我选择了加一个参数来区分百度和其它地图
- 外部更好的使用,必须在需要的地方添加回调参数
- 为了统一的管理和不重复的添加,我选择了使用一个变量存储所有加载的图层。在设置的时候,已经出现的图层会直接返回
最后我贴上目前的一个代码,改代码下午才写,不完善,下周应该会完善自己需要使用的地方。虽然已过了青葱的岁月,可是代码水平还是难^_^。
/**
* jQuery and leaflet Plugin createMap
* jquery插件:生成百度、谷歌、高德、天地图等地图到页面
*
* version 1.0, 2020-03-20
* by jcy
* Git repository : https://github.com/jiechengyang/jqLeafletCreateMap
*/ /**
* example:
*
* 默认生成谷歌等多图层【查看地图右上角图层管理工具】:var mapService = $("#map").createMap({center: [lat, lng]});
*
* 生成百度地图:var mapService = $("#map").createMap({center: [lat, lng], imap: 'Bd.Normal.Map'});
*
* 生成单张地图请传递:single:true
*
* 修改默认加载地图请传:iLayer:'对应chinaProviderKeys的key值'
* */ /**
* add method:
* iconMarker: 图标加载
* addPolygon: 面加载
*
*/
(function ($) {
function arrIndexOf(array, find, field) {
var index = -1;
for (var i = 0; i < array.length; i++) {
var arr = array[i];
if (arr[field] === find) {
index = i;
break;
}
} return index;
} function mapService() {
this.layers = [];
this.chinaProviderKeys = [
{
key: 'Geoq.Normal.Map',
name: '智图地图',
group: 'Geog'
},
{
key: 'Geoq.Normal.PurplishBlue',
name: '智图午夜蓝',
group: 'Geog'
},
{
key: 'Geoq.Normal.Gray',
name: '智图灰色',
group: 'Geog'
},
{
key: 'Geoq.Normal.Warm',
name: '智图暖色',
group: 'Geog'
},
{
key: 'TianDiTu.Normal.Map',
name: '天地图',
group: 'TianDiTu'
},
{
key: 'TianDiTu.Normal.Annotion',
name: '',
group: 'TianDiTu'
},
{
key: 'TianDiTu.Satellite.Map',
name: '天地图影像',
group: 'TianDiTu'
},
{
key: 'TianDiTu.Satellite.Annotion',
name: '',
group: 'TianDiTu'
},
{
key: 'Google.Normal.Map',
name: '谷歌地图',
group: 'Google'
},
{
key: 'Google.Satellite.Map',
name: '谷歌影像',
group: 'Google'
},
{
key: 'GaoDe.Normal.Map',
name: '高德地图',
group: 'GaoDe'
},
{
key: 'GaoDe.Satellite.Map',
name: '高德影像',
group: 'GaoDe'
},
{
key: 'GaoDe.Satellite.Annotion',
name: '',
group: 'GaoDe'
}
];
this.map = null;
this.get = function (key) {
return this.layers.indexOf(key) === 1 ? this.layers[key] : null;
}
this.set = function (key, options) {
if (this.layers.indexOf(key) >= 0) {
return this.get(key);
} if (arrIndexOf(this.chinaProviderKeys, key, 'key') === -1) {
return null;
} var layer = L.tileLayer.chinaProvider(key, options);
this.layers[key] = layer;
return layer;
} this.delete = function (key) {
delete this.layers[key];
} this.getMap = function () {
return this.map;
} this.destroy = function () {
this.layers = [];
this.map = null;
} this.init = function (domId, settings) {
if (!settings.hasOwnProperty('iLayer')) {
settings.iLayer = settings.imap;
}
var defaultMapOpts = {
zoom: settings.zoom,
zoomControl: settings.zoomControl,
center: settings.center
}; var bdMap = false;
if (settings.imap === 'Bd.Normal.Map') {
defaultMapOpts.crs = L.CRS.Baidu;
bdMap = true;
} var mainMap = L.map(domId, defaultMapOpts);
this.map = mainMap;
var opts = {
maxZoom: settings.maxZoom,
minZoom: settings.minZoom,
}; if (bdMap) {
opts.layer = settings.bdLayer ? settings.bdLayer : 'custom';
opts.customid = settings.bdCustomid ? settings.bdCustomid : 'googlelite';
var firstLayer = this.getBdMap(opts);
settings.single = true;
} else {
var firstLayer = this.set(settings.iLayer, opts);
}
if (firstLayer) {
mainMap.addLayer(firstLayer);
} if (!settings.single) {
var baseLayers = this.addLayers(settings.method, opts);
if (baseLayers) {
var providerName = this.chinaProviderKeys[arrIndexOf(this.chinaProviderKeys, settings.iLayer, 'key')]['name'];
baseLayers[providerName] = firstLayer;
L.control.layers(baseLayers, null).addTo(mainMap);
}
}
L.Util.requestAnimFrame(mainMap.invalidateSize, mainMap, !1, mainMap._container);
} this.addLayers = function (method, opts) {
method = 'add' + method;
if (this.hasOwnProperty(method)) {
return this[method].call(this, opts);
} return {};
} /**
* 智图内容
*/
this.addGeoNorMaps = function (options) {
var layers = {};
for (var i = 0; i < this.chinaProviderKeys.length; i++) {
var provider = this.chinaProviderKeys[i];
if (provider.group !== 'Geog') continue;
var layer = this.set(provider.key, options);
if (layer) {
layers[provider.name] = layer;
}
} return layers;
} /**
* 百度地图
*/
this.getBdMap = function (options) {
options = $.extend({
// maxZoom: 18,
// minZoom: 4,
attribution: 'ⓒ 2020 Bd Map',
layer: 'custom',
customid: 'grassgreen',
// crs: L.CRS.Baidu
}, options);
//百度:titleLayer.baidu.js
//TODO: 请引入 proj4.js 和 proj4leaflet.js
var layer = new L.tileLayer.baidu(options);
this.layers['Bd.Normal.Map'] = layer;
return layer;
} /**
* 天地图内容
*/
this.addTianDiMaps = function (options) {
var normalm = this.set('TianDiTu.Normal.Map', options),
normala = this.set('TianDiTu.Satellite.Annotion', options),
imgm = this.set('TianDiTu.Satellite.Map', options),
imga = this.set('TianDiTu.Normal.Map', options);
var normal = L.layerGroup([normalm, normala]),
image = L.layerGroup([imgm, imga]); return {
"天地图": normal,
"天地图影像": image,
}
} /**
* 谷歌地图内容
*/
this.addGoogleMaps = function (options) {
var normalMap = this.set('Google.Normal.Map', options),
satelliteMap = this.set('Google.Satellite.Map', options);
return {
"谷歌地图": normalMap,
"谷歌影像": satelliteMap,
}
} /**
* 高德地图
*/
this.addGaoDeMaps = function (options) {
var Gaode = this.set('GaoDe.Normal.Map', options);
var Gaodimgem = this.set('GaoDe.Satellite.Map', options);
var Gaodimga = this.set('GaoDe.Satellite.Annotion', options);
var Gaodimage = L.layerGroup([Gaodimgem, Gaodimga]);
return {
"高德地图": Gaode,
"高德影像": Gaodimage,
} } /**
* 所有地图
*/
this.addAllMaps = function (options) {
var keys = [
'GeoNorMaps',
'TianDiMaps',
'GoogleMaps',
'GaoDeMaps',
];
var layers = {};
for (var i in keys) {
var method = 'add' + keys[i];
if (this.hasOwnProperty(method)) {
layers = $.extend(layers, this[method](options));
}
} return layers;
}
} /**
*
* 图表标记
*/
mapService.prototype.iconMarker = function (icon, marker, labelContent, popupOpts, events) {
events = events || null;
labelContent = labelContent || null;
var defaultOpts = {
minWidth: 500,
className: 'leaflet-popup'
};
popupOpts = $.extend(defaultOpts, popupOpts);
var marker = new L.Marker(marker, {
icon: icon
});
this.getMap().addLayer(marker);
if (labelContent) {
var label = new L.Label({
noHide: true
});
label.setContent(labelContent).setLatLng({lat: marker.lat, lng: marker.lng + 1.4});
this.getMap().showLabel(label);
}
if (popupOpts.id) {
marker.bindPopup(document.getElementById(popupOpts.popupId), popupOpts);
} if (events) {
for (var eKey in events) {
marker.on(eKey, events[eKey]);
}
} return marker;
}; /**
*
* 多边形地块
*/
mapService.prototype.landPolygon = function (polygonObj, opts, events) {
var defaultOpts = {
initColor: 'pink',
initOpacity: 0.3,
hoverColor: 'orange',
hoverOpacity: 0.3,
domId: 'leaflet_land_popup_' + polygonObj.id,
};
events = events || {};
opts = $.extend(defaultOpts, opts);
if (polygonObj.hasWarning) {
opts.initColor = 'red';
}
var land = new L.Polygon(polygonObj.polygon, {
weight: 2,
opacity: opts.initOpacity,
fillOpacity: opts.initOpacity,
color: opts.initColor
});
this.getMap().addLayer(land);
var label = new L.Label();
label.setContent(polygonObj.labelContent).setLatLng(land.getBounds().getCenter());
this.getMap().showLabel(label);
var defaultEvent = {
mouseover: function (event) {
land.setStyle({
color: opts.hoverColor,
opacity: opts.hoverOpacity,
fillOpacity: opts.hoverOpacity,
});
},
mouseout: function (event) {
land.setStyle({
color: opts.initColor,
opacity: opts.initOpacity,
fillOpacity: opts.initOpacity,
});
}
}; events = $.extend(defaultEvent, events); for (var eKey in events) {
land.on(eKey, events[eKey]);
} if (polygonObj.isBindPopup) {
land.bindPopup(document.getElementById(polygonObj.domId), {
minWidth: 500,
className: 'leaflet-popup'
});
} return land;
}; var methods = {
init: function (options) {
var tData = this.data() || {};
// TODO: 参数合并:隐式参数与显示参数;隐式参数:dom标签的data-属性 显示参数:调用对象传参
options = $.extend(tData, options);
var settings = $.extend({
maxZoom: 18,// leaflet 参数
minZoom: 5,// leaflet 参数
zoom: 14,// leaflet 参数
zoomControl: false,// leaflet 参数
center: [30.29898916168688, 103.57831210632321],// leaflet 参数
imap: 'Google.Normal.Map',// 插件 参数:默认地图加载谷歌地图,Bd.Normal.Map:由于坐标系问题,暂时只能加载它一个地图
bdLayer: 'custom',// 百度地图图层选择,
bdCustomid: 'googlelite',// 插件 参数:百度地图图层样式选择
single: false,// 插件 参数:是否加载单个地图图层:默认是加载多张
method: 'AllMaps'// 插件 参数:加载多张地图图层时有几种类型选择:智图、天地图、百度、谷歌、高德
}, options);
var service = new mapService();
service.init(this.attr('id'), settings);
return service;
},
destroy: function () {
this.empty();
}
}; $.fn.createMap = function (method) {
method = method || null;
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
// return methods.init(this, methods);
} else {
$.error('Method' + method + 'does not exist on jQuery.tooltip');
}
}
})(jQuery);
最后再说一下,我们提升代码质量的唯一途径只有看源码。愿得到指点,愿共勉。
-------------------------垃圾猿
leaflet生成地图封装成jquery插件使用的更多相关文章
- 星级评分--封装成jquery插件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 如何将Js代码封装成Jquery插件
很多相同的Jquery代码会在很多页面使用,每次都复制粘贴太麻烦了,不如封装成一个Jquery插件就方便了,至于影响网页的速度不,我就没有测试了哈. 代码如下 这是一个自定闪烁打印文字的Jquery特 ...
- 自己做jQuery插件:将audio5js封装成jQuery语音播放插件
日前的一个项目需要用到语音播放功能.发现Audio5js符合需求且使用简单,又鉴于jQuery控件便于开发操作,于是有了以下的封装. 首先先简单介绍一下Audio5js吧. Audio5js是一个能够 ...
- 封装第三方jquery插件
需要自己编写 directives 的情况通常是当你使用了第三方的 jQuery 插件.因为插件在 AngularJS 之外对表单值进行更改,并不能即时反应到 Model 中.例如我们用得比较多的 j ...
- 学了一个封装的jquery插件,感觉还成
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 自动生成气泡对话框的jQuery插件CreateBubble.js
之前在写一个界面,想要用到气泡,然而一直找不到现成的有效地办法,是在没有办法了我只好自己写一个,于是就有了现在的CreateBubble.js.很简单的一个函数,但是非常实用. 使用方法: 1.HTM ...
- 气球或者泡泡向上飘动 jQuery插件
圣诞.元旦要来了,公司以往基本每个月至少要搞一两款手机小游戏来宣传产品,这次也不例外!! 之前做过,按压柚子.许愿.吃柚子等等小游戏,这次是做个那种 气球向上飘动,戳破气球,随机获取奖品.如下图: 手 ...
- JQuery-- 链式编程、静态函数,自己制作jQuery插件
一.链式编程 为什么jQuery运行链式编程 ,让我们的代码(方法)连续不间断书写(连续调用)其实主要还是jQuery很多的函数执行完毕之后,都会返回一个jQuery对象 因为获取操作的时候,会返回获 ...
- 点击弹出 +1放大效果 -- jQuery插件
20140110更新: <!doctype html> <html> <head> <meta charset="UTF-8"> & ...
- 我的第一个jquery插件:下拉多选框
<!DOCTYPE HTML> <html> <head> <title> New Document </title> <meta n ...
随机推荐
- nginx jupyterWeb
location /jupyterWeb/ { add_header X-Frame-Options SAMEORIGIN; add_header Access-Control-Allow-Origi ...
- git path
github -> deepin-4090-edd25519-key openl -> deepin-4090-rsa-key gitee -> deepin-4090-dsa-ke ...
- elasticsearch数据导出和导入
数据导入和导出依赖于命令 elasticdump 数据导出 #!/bin/bash ES=http://ip:port ED=数据保存位置 datename=$(date +%Y-%m-%d) #da ...
- 永远不要轻易设置Oracle的隐藏参数,哪怕是DRM
这篇文章可能会存在较大争议,甚至颠覆一些人的固有思维. 因为关于Oracle的隐藏参数,江湖上一直都有两派对立的观点: 1.不要设置任何隐藏参数,只有当遇到特殊问题时在售后指导下临时使用,在问题解决后 ...
- 如何快速的开发一个完整的iOS直播app(点赞功能)
客户端代码 点击小红心,发送socket给服务器,并且要传递房间Key给服务器,通知给哪个主播点赞,就能传入到对应的分组socket中 怎么传递房间key,房间Key在主播界面,一般一个客户端,只会产 ...
- Idea创建maven项目流程、修改默认配置、及注意事项
这里所演示的环境: windows7+jdk1.7.0_80+tomcat8.5.41+maven3.0.5+idea2017.3.6 1.idea使用指定maven版本 打开idea,使用快捷键ct ...
- 移动端如何自动适配px
<script type="text/javascript"> (function(doc, win) { var docEl = doc.documentElemen ...
- OSI七层经典模型架构以及网络的基本概念
在大.中型网络中,通常通过模块化方式将网络功能结构进行分解.但是在各个模块内部,还是存在结构的扩展和弹性问题. 譬如一个园区网络需要接入大量用户等,这个问题一般通过网络的层次化来解决. 传统的网络采用 ...
- Centos7部署DVWA靶场
Centos7部署DVWA靶场 DVWA 款开源的渗透测试漏洞练习平台,其中内含xs SQL注入. 文件上传.文件包含. CSRF和暴力破解等各个难度的测试环境. 安装httpd及其相关的组件 y ...
- Prometheus修改数据存储位置
Prometheus修改数据存储位置 Prometheus的数据存储位置可以通过配置文件中的 --storage.tsdb.path 参数来指定.默认情况下,数据存储在Prometheus安装目录下的 ...