目录

情形:需求

实现:分析 实现

页面:前端

总结:仔细再仔细


情形:

最近遇到这样一个情况:

  1. 需要实现动态增加页面,可以添加页面,页面的内容需要能保存,修改和删除。
  2. 页面的名字可编辑,并且要实现单击页面切换,双击编辑页面名字文本。

最后结果就是这样:

实现:

最先开始决定用组建,先找的bootspript的表格,但是后来发现这个组建并不能满足我的需求,他无法添加可编辑名字的页面。随即放弃。再在后来决定使用js 拼接按钮的方式动态拼接html元素的方式实现页面添加。但是此方法需要注意3个点要处理好:

  1. 多个页面的数据存取都是用同一个数据库同一张表。
  2. js拼接的只能是button元素,因为需要绑定单双击事件,需要使用一个span标签和input标签来回切换。
  3. 各个拼接的button的id需要唯一,其中的span和input的id也要唯一

js拼接html代码:需要从别的html粘一个按钮过来,或者自己写也行。注意" "和' '使用,让变量和常量区分开来,如果你定义的整体是" ",那么变量使用 "+变量+" 的方式拼接,常量用 '常量'的方式拼接。相反,你的整体使用 ' ' 单引号的话,变量就要使用'+要传值的量+'来拼接。另外,onchange事件传值最好使用this 把这个input元素都传值过去,然后用this.value  this.id 的方式获取 id 和内容。

下面是页面添加按钮绑定的方法:我采用button + span+ input 的方式 来实现对 button的单双击切换

function addMicroserviceConfPage(){              //新建的时候不需要查之前的配置名字//rememberName='';var spanId="span_"+Math.floor(Math.random()*100000000);var inputId="input_"+Math.floor(Math.random()*100000000);var addTab="<button  style='margin-left:10px;margin-bottom:10px;' class='btn btn-default btn-style indexBtn checked'>"+"<span  id="+spanId+"></span>"+"<input id="+inputId+" value='请为当前配置文件命名'  style='border:none;width: 153px;color: black;'  onchange='changeConfNames(this);' /></button>";$("#buttonDivTab").append(addTab);
}          

因为需要各个元素的id唯一,因此需要两种情况:

1.数据库里没数据,按钮点击生成新页签的时候:此时文件名不存在,为了区分新建多个按钮的保存以及切换,我决定使用随机数来为span 和input 附上唯一的id,(Math.flow的意思是 向上取整数舍去小数)。

2、数据库有数据,打开页面就要显示数据,按钮的名字必须是唯一的,此时不用随机数了,使用配置文件名字来区分各个按钮对应哪个页面。js 拼接代码如下:

function findConfNameByPid(Pid){var confNames=[];$.ajax({async : false,cache:false,dataType:'json',type : 'POST', url : '<%=basePath%>/project/findConfNameByPid', data :{'projectVersionResourceID':Pid},success: function(result){confNames = result;allNamesForOnly=result;var ids=result;if(confNames.length==0){$("#buttonDivTab").empty();var spanId="span_"+Math.floor(Math.random()*100000000);var inputId="span_"+Math.floor(Math.random()*100000000);var addTab="<button  style='margin-left:10px;margin-bottom:10px' class='btn btn-default btn-style indexBtn checked'>"+"<span id="+spanId+"></span>"+   "<input id="+inputId+" value='请为当前配置文件命名'  style='border:none;width: 153px;color: black;' onchange='changeConfNames(this)' />"+"</button>";$("#buttonDivTab").append(addTab);}else{$("#buttonDivTab").empty();for(var i=0;i<confNames.length;i++){if(i==0){//第一个tab默认显示选中的样式var idNames=ids[i].split(".");var spanId="span_";var inputId="input_";if(idNames.length!=0){for(var j=0;j<idNames.length;j++) {spanId+=idNames[j];inputId+=idNames[j];}}  var addTab="<button  style='margin-left:10px;margin-bottom:10px' class='btn btn-default btn-style indexBtn checked'>"+"<span name='spName' id="+spanId+">"+confNames[i]+"</span>"+  "<input name='btnName' id="+inputId+" value="+confNames[i]+"  style='border:none;width: 153px;display:none;color: black;' onchange='changeConfNames(this)' /></button>";$("#buttonDivTab").append(addTab);}else{//为 span 和input 赋值唯一的idvar idNames=ids[i].split(".");var spanId="span_";var inputId="input_";if(idNames.length!=0){for(var j=0;j<idNames.length;j++) {spanId=spanId+idNames[j];inputId=inputId+idNames[j];}}  var addTab="<button  style='margin-left:10px;margin-bottom:10px' class='btn btn-default btn-style unchecked indexBtn'>"+"<span name='spName' id="+spanId+">"+confNames[i]+"</span>"+    "<input name='btnName' id="+inputId+" value="+confNames[i]+" style='border:none;width: 153px;display:none;' onchange='changeConfNames(this)' /></button>"; $("#buttonDivTab").append(addTab);}}}}});if(confNames.length!=0 && confNames !=null && confNames !=""){confName=confNames[0]; //第一个文件名}else{confName='请为当前配置文件命名'; //没数据给默认值name}  }

对应的onchange事件处理如下:

function changeConfNames(e){var valueName=e.value;var idName="#"+e.id;confName=valueName;if(allNamesForOnly!="" && valueName!=""){   if(allNamesForOnly.indexOf(valueName)!=-1){$(idName).val("");alertMsg("当前配置文件名字已经存在","info");}}
}

其中的allNamesForOnly 是全局变量 ,在页面加载的时候会将数据库里的文件名加载过来,用来确认是否重复。

(全局变量虽然方便,但是用完就要释放掉,不释放一般情况下不影响,但是一旦印象,那种经历你会一直记得,因为全局变量造成的bug不好复现,但是偶然的出现会让你摸不着头脑。)

单双击切换实现的代码:

//单击 切换页面   双击 编辑文本
$(document).ready(function(){var timer = null;$("#buttonDivTab").on("click","button",function(){clearTimeout(timer);$(this).addClass("checked");$(this).siblings().removeClass("checked");$(this).siblings().addClass("unchecked");confName=$(this).find("input").val(); timer = setTimeout(function() { //在单击事件中添加一个setTimeout()函数,设置单击事件触发的时间间隔 var rightData;    $.ajax({async : false,cache:false,dataType:'json',type : 'POST',  url : '<%=basePath%>/project/findConfByProjectAndName',// findConfByProject 查全部   findConfByProjectAndName 查名字对应的内容data :{'projectVersionResourceID':Pid,'confName':confName},success: function(result){rightData = result;removeData = [];// confName='';}});hotTable = $("#microserviceTable").data('handsontable');//获取表格的值var originalData = eval(JSON.stringify(rightData.rightData));if(originalData!= null && originalData!=""){hotTable.loadData(originalData);//给表格赋值 }else{hotTable.loadData(eval('[{"textName":"","ConfresourceID":"","value":""}]'));} // 恢复成butten状态var ids=confName;             var idNames=ids.split(".");var spanId="#span_";var inputId="#input_";if(idNames.length!=0){for(var i=0;i<idNames.length;i++) {spanId+=idNames[i];inputId+=idNames[i];}} $(spanId).show();$(inputId).removeAttr("style");$(inputId).attr("style","display:none;");//$("input[name='btnName']").attr("style","display:none;");//$("span[name='spName']").show();}, 300);});$("#buttonDivTab").bind("dblclick", function() { //双击事件 clearTimeout(timer); //在双击事件中,先清除前面click事件的时间处理            rememberName=confName;var ids=confName;var idNames=ids.split(".");var spanId="#span_";var inputId="#input_";if(idNames.length!=0){for(var i=0;i<idNames.length;i++) {spanId+=idNames[i];inputId+=idNames[i];}}$(spanId).hide();$(inputId).removeAttr("style");$(inputId).attr("style","border:none;color: black;");}); });   

单击 给当前button添加选中的样式,去掉其他button的样式,然后触发点击事件,获取button 的input标签的value去数据库查值,之后重新加载表格。

双击: button 的span 隐藏 ,input 输入框 去掉隐藏样式显示到button中来,需要注意的是:

单双击时间绑定在同一个元素上是会冲突的,双击事件失效,永远是触发的是单击事件。处理方式加一个事件执行时间的函数。在单双击事件执行之前放空执行时间。一般是在单击事件加setTimeOut函数 ,通常加参数300毫秒。

需要注意的是 :无论单双击 所有操作代码都要写在  clearTimeout(timer);  之后,才会触发双击事件。要先清空上次单击事件的时间。

页面:

页面的表格使用的handsontable,对新手不太友好的表格,因为关于他的资料太少了,估计用的人也不多。。。

这个组建的好处就是能像excel一样处理数据,功能比较强大,它能完成全选+复制 然后ctrl+v 表格能粘贴所有的数据过来(但我看来,bootstrpttable 一样厉害),他的数据源必须是数组或者数组对象。代码:

 $('#microserviceTable').handsontableExpand().handsontable({startRows : 0,colHeaders : function(col) {switch (col) {case 0:return '';case 1:return '<span style="float: center;">当前工程配置</span>';case 2:return '<span style="float: center;">说明信息</span>';case 3:return '';   case 4:return '';}    },colWidths : [50,325,325,0,0],hiddenColumns : {columns : [3,4],},rowHeights: 35,fillHandle:false,fixedColumnsLeft:true,rowHeaders:true,autoWrapRow:true,checkAllColumns:['ischecked'],afterCheckAll:[{'column':'ischecked'}],columns : [ {data : 'ischecked',type : 'checkbox'},{data : 'textName',type : 'text',//renderer : rightDescriptionRenderer,}, {data : 'value',type : 'text'},{data : 'ConfresourceID',type : 'text'},{data : 'projectVersionResourceID',type : 'text'}  ]}); $("#microserviceTable").handsontable('render');initMicroserviceTable(Pid);//展示 页面$("#distributeProjectDiv").panelRight('open');
}//初始化表格
function initMicroserviceTable(Pid){var rightData;  $.ajax({async : false,cache:false,dataType:'json',type : 'POST',  url : '<%=basePath%>/project/findConfByProjectAndName',data :{'projectVersionResourceID':Pid,'confName':confName},success: function(result){rightData = result;removeData = [];// confName='';}});hotTable = $("#microserviceTable").data('handsontable');//获取表格的值var originalData = eval(JSON.stringify(rightData.rightData));if(originalData!= null && originalData!=""){hotTable.loadData(originalData);//给表格赋值 }else{hotTable.loadData(eval('[{"textName":"","ConfresourceID":"","value":""}]'));}}

handsontable这个表格 个人感觉比较重要的方法:

申明/初始化表格的时候(在表格中设置的效果):

  1. 设置列头: colHeaders : function(col) {
                        switch (col) {
                        case 0:
                            return '';
                        case 1:
                            return '<span style="float: center;">当前工程配置</span>';
                        case 2:
                            return '<span style="float: center;">说明信息</span>';
                        case 3:
                            return '';    
                        case 4:
                            return '';
                        }    
                    },
  2. 各列占的宽度(不能用百分比,精确数字PX):colWidths : [50,325,325,0,0],
  3. 要隐藏的列:hiddenColumns : {
                        columns : [3,4],
                    }, //只显示0 1,2 三列,4,5 列隐藏,用于传值
  4. 给表格加个行头,在表格的最左侧固定加一列序号:1,2...,从rowHeaders:true,
  5. 全选:checkAllColumns:['ischecked'],  使用他需要引入一个js文件,handsontableExpand.js,你没有不要紧(我给你),你可以新建一个js文件,就以这个名字命名,内容我粘到这里,想体验的可以站过去,然后在你的页面引入你新建的页面,注意,这个全选的表格名字是hotTable写死的,需要你将自己的hangsontable表格名字也定义成hotTable。然后全选就可以了。js内容:(注意,引入js要确保路径正确,以当前的jsp为主,然后找js对应的位置)
    (function($, h, c) {var a = $([]),e = $.resize = $.extend($.resize, {}),i,k = "setTimeout",j = "resize",d = j + "-special-event",b = "delay",f = "throttleWindow";e[b] = 250;e[f] = true;$.event.special[j] = {setup: function() {if (!e[f] && this[k]) {return false;}var l = $(this);a = a.add(l);$.data(this, d, {w: l.width(),h: l.height()});if (a.length === 1) {g();}},teardown: function() {if (!e[f] && this[k]) {return false;}var l = $(this);a = a.not(l);l.removeData(d);if (!a.length) {clearTimeout(i);}},add: function(l) {if (!e[f] && this[k]) {return false;}var n;function m(s, o, p) {var q = $(this),r = $.data(this, d);if(r==null){var l = $(this);$.data(this, d, {w: l.width(),h: l.height()});r = $.data(this, d);}r.w = o !== c ? o: q.width();r.h = p !== c ? p: q.height();n.apply(this, arguments);}if ($.isFunction(l)) {n = l;return m;} else {n = l.handler;l.handler = m;}}};function g() {i = h[k](function() {a.each(function() {var n = $(this),p = this.parentNode,m = n.width(),l = n.height(),o = $.data(this, d);if ((!$(this).hasClass('wtHider')&&m !== o.w)||($(this).hasClass('wtHider')&& (l !== o.h||p.clientWidth!==$(p).width()||p.clientHeight!==$(p).height()))) {n.trigger(j, [o.w = m, o.h = l]);}});g();},e[b]);}
    })(jQuery, this);
    HandsontableExpand = function(obj) {var hot = obj.data('handsontable');var handsontableExpand = this;this.handsontable=function(settings){obj.handsontable(settings);hot = obj.data('handsontable');if('checkAllColumns' in settings)this.createAllCheck(settings['checkAllColumns']);if('afterCheckAll' in settings){var afterCheckAllArr = settings['afterCheckAll'];for(i=0;i<afterCheckAllArr.length;i++)this.afterCheckAll(afterCheckAllArr[i]['column'],afterCheckAllArr[i]['function']);}if('afterUndoRedo' in settings)this.undoRedo(settings['afterUndoRedo']);obj.find(".leftHead").parent().parent().css({'text-align': 'left','padding-left': '12px'});}this.undoRedo = function(afterBackOffOrForward) {this.undo(afterBackOffOrForward);this.redo(afterBackOffOrForward);};this.undo = function(afterBackOff) {hot.undoRedo.undo = function() {var flag = this.isUndoAvailable();if (flag) {var action = this.doneActions.pop();this.ignoreNewActions = true;var that = this;action.undo(this.instance, function() {that.ignoreNewActions = false;that.undoneActions.push(action);});}if (afterBackOff != null && afterBackOff != undefined) {var nextflag = this.isUndoAvailable();afterBackOff(flag, "Z", nextflag);}};};this.redo = function(afterForward) {hot.undoRedo.redo = function() {var flag = this.isRedoAvailable();if (flag) {var action = this.undoneActions.pop();this.ignoreNewActions = true;var that = this;action.redo(this.instance, function() {that.ignoreNewActions = false;that.doneActions.push(action);});}if (afterForward != null && afterForward != undefined) {var nextflag = this.isRedoAvailable();afterForward(flag, "Y", nextflag);}};};this.createOrRemoveRow = function(afterCreateRowFun, afterRemoveRowFun) {this.createRow(afterCreateRowFun);this.removeRow(afterRemoveRowFun);};this.createRow = function(afterCreateRowFun) {var thisAfterCreateRow = hot.getSettings().afterCreateRow;hot.updateSettings({afterCreateRow : function() {var rows = hot.getData().length;hot.updateSettings({height : (35 * rows) + 45});if (thisAfterCreateRow != null&& thisAfterCreateRow != undefined)thisAfterCreateRow();if (afterCreateRowFun != null&& afterCreateRowFun != undefined)afterCreateRowFun();}});};this.removeRow = function(afterRemoveRowFun) {var thisAfterRemoveRow = hot.getSettings().afterRemoveRow;hot.updateSettings({afterRemoveRow : function() {var rows = hot.getData().length;hot.updateSettings({height : (35 * rows) + 45});if (thisAfterRemoveRow != null&& thisAfterRemoveRow != undefined)thisAfterRemoveRow();if (afterRemoveRowFun != null&& afterRemoveRowFun != undefined)afterRemoveRowFun();}});};this.createRowPrevious = function(columnNameOrNum) {var ischeckedArr;if (typeof columnNameOrNum === "string")ischeckedArr = hot.getDataAtProp(columnNameOrNum);else if (typeof columnNameOrNum === "number")ischeckedArr = hot.getDataAtCol(columnNameOrNum);var checkIndex = $.inArray(true, ischeckedArr);var checkIndexNext = $.inArray(true, ischeckedArr, checkIndex + 1);if (checkIndex >= 0) {if (checkIndexNext < 0) {hot.alter('insert_row', checkIndex);return true;} else {alertMsg("请只选择一条数据插入上一行", "warning");return false;}} else {alertMsg("请选择一条数据插入上一行", "warning");return false;}};this.createRowNext = function(columnNameOrNum) {var ischeckedArr;if (typeof columnNameOrNum === "string") ischeckedArr = hot.getDataAtProp(columnNameOrNum);else if (typeof columnNameOrNum === "number") ischeckedArr = hot.getDataAtCol(columnNameOrNum);var checkIndex = $.inArray(true, ischeckedArr);var checkIndexNext = $.inArray(true, ischeckedArr, checkIndex + 1);if (checkIndex >= 0) {if (checkIndexNext < 0) {hot.alter('insert_row', checkIndex + 1);return true;} else {alertMsg("请只选择一条数据插入下一行", "warning");return false;}} else {alertMsg("请选择一条数据插入下一行", "warning");return false;}};this.isAllCheck=function(columnNameOrNum){var ischeckedArr;if (typeof columnNameOrNum === "string")ischeckedArr = hot.getDataAtProp(columnNameOrNum);else if (typeof columnNameOrNum === "number") ischeckedArr = hot.getDataAtCol(columnNameOrNum);var notCheckIndex = $.inArray(false, ischeckedArr);var nullCheckIndex = $.inArray(null, ischeckedArr);if(notCheckIndex<0&&nullCheckIndex<0) return true;else return false;};this.updateWidth=function(newWidth) {hot.updateSettings({colWidths : newWidth});};this.createAllCheck=function(columnNameOrNum) {var allCheckColNum=[];for(i=0;i<columnNameOrNum.length;i++){if (typeof columnNameOrNum[i] === "string") allCheckColNum.push(hot.propToCol(columnNameOrNum[i]));else if (typeof columnNameOrNum[i] === "number") allCheckColNum.push(columnNameOrNum[i]);}var thisColHeaders = hot.getSettings().colHeaders;var thisAfterLoadData = hot.getSettings().afterLoadData;var thisBeforeRender = hot.getSettings().beforeRender;hot.updateSettings({colHeaders : function (col) {if($.inArray(col, allCheckColNum)>-1){var txt = "<input name='checkall"+col+"' type='checkbox' class='checker' ";txt += obj.data('isChecked'+col) ? 'checked="checked"' : '';txt += ">";return txt;}if(thisColHeaders)return thisColHeaders(col);},afterLoadData:function(){for(i=0;i<allCheckColNum.length;i++)obj.data('isChecked'+allCheckColNum[i],false);obj.handsontable('render');if(thisAfterLoadData)thisAfterLoadData();},beforeRender:function(){for(i=0;i<allCheckColNum.length;i++)obj.data('isChecked'+allCheckColNum[i],handsontableExpand.isAllCheck(allCheckColNum[i]));if(thisBeforeRender)thisBeforeRender();}});for(i=0;i<allCheckColNum.length;i++){obj.on('mouseup', 'input[name=checkall'+allCheckColNum[i]+']', function (event) {var num = parseInt($(this).attr("name").replace("checkall",""));obj.data('isChecked'+num,!$(this).is(':checked'));var checkedcol = hotTable.propToCol("ischecked");hot.populateFromArray(0, num, [[!$(this).is(':checked')]], hot.countRows()-1, num);var fun = obj.data('aftercheckfun'+num);if(fun!=null)fun();});}};this.afterCheckAll=function(columnNameOrNum,fun){var colnum;if (typeof columnNameOrNum === "string") colnum=hot.propToCol(columnNameOrNum);else if (typeof columnNameOrNum === "number") colnum=columnNameOrNum;obj.data('aftercheckfun'+colnum,fun);};
    }
    $.fn.handsontableExpand = function() {return new HandsontableExpand(this);
    }
  6. 设置列的类型以及类型:columns : [ {
                        data : 'ischecked',
                        type : 'checkbox'
                    },{
                        data : 'textName',
                        type : 'text',
                        //renderer : rightDescriptionRenderer,
                    }, {
                        data : 'value',
                        type : 'text'
                    },
                    {
                        data : 'ConfresourceID',
                        type : 'text'
                    },
                    {
                        data : 'projectVersionResourceID',
                        type : 'text'
                    }  ]
                });

  7. 前面的复选框:复选框单独占一列,因此列头需要加一列, 就是列头的case 0: ,此外,columns 需要将type属性改为checkbox,data就是列的业务名字,到时候取值的拿data的内容就可以拿到数据。

  8. hotTable.loadData(originalData);//给表格赋值   这里的originalData 必须是数组或数组对象,否则前台就会报错loadData() 未定义。

表格加载完成之后(表格数据的获取):

  1. 获取所有的行数: var countRows = hotTable.countRows();
  2. 获取对应行数的列的textName的数据;  hotTable.getDataAtRowProp(i,'textName');
  3. 获取某列的全部数据:hotTable.getDataAtProp("ConfresourceID");
  4. 增加/删除页面的一行数据:     hotTable.alter('insert_row', 行数);  //增加 hotTable.alter('remove_row',行数);//删除
  5. 给表格第0行 第1列 单元格赋值" " : hotTable.setDataAtCell(0,1,"");
  6. 一些其他的方法参照:https://blog.csdn.net/qianqianyixiao1/article/details/81507257

这个table 的增加 单元格和删除 是这样的:

//增加行
var rowID=0;
function addRowsByNewBut(){rowID=rowID-1;hotTable.alter('insert_row', 0);  hotTable.setDataAtCell(0,1,"");
}//页面上移除数据
var ischeckedArr = hotTable.getDataAtProp("ischecked");
//计数
var num=0;
for(var i=0;i<ischeckedArr.length;i++){if(ischeckedArr[i]) { hotTable.alter('remove_row',i-num);num++;}
}

主要是hotTable.alter(); 这个方法。批量删除的时候需要定义一个num用来记录选中的行数。

总结:

  • 拼接代码的时候要仔细,不行就在w3c 和菜鸟教程上 利用假数据动态验证
  • 前端js和html css 知识点也很多 ,不知道真做不出来,都要了解
  • js全局变量一定要释放,java有虚拟机,js解释性弱类型语言,需要手动释放
  • 多个使用多个class 样式的选择器 可以用"."连接 如:$(".class1.class2.class3....");

js动态添加html页签(JavaScript 拼接html标签代码)相关推荐

  1. MUI 里js动态添加数字输入框后,增加、减少按钮无效

    https://www.cnblogs.com/ssjf/p/10193652.html numbox 的自动初化是在 mui.ready 时完成的 mui 页面默认会自动初始化页面中的所有数字输入框 ...

  2. js动态添加页面的icon图标

    js动态添加页面的icon图标 (function() {var link = document.createElement('link');link.type = 'image/x-icon';li ...

  3. 【原生js】js动态添加dom,如何绑定事件

    首先要明白浏览器在加载页面的时候是按顺序来加载的,这样以来就很清楚了,js动态添加dom以后,这些dom并没有绑定事件,这个时候最简单的一个办法就是:将绑定事件的方法封装到一个函数A中,在动态添加完d ...

  4. 原生js动态为table追加html,JS动态添加Table的TR,TD实现方法

    本文实例讲述了JS动态添加Table的TR,TD实现方法.分享给大家供大家参考.具体实现方法如下: var tempRow=0; var maxRows=0; function insertRows( ...

  5. js动态添加options(转载)

    JS动态添加Option的几种方式 在处理表单的时候,经常会有这样的需求:给定一定的数据来生成某个select的option,或者更进一步,某些option或许预先选中或者有高亮显示. 下面我们就来温 ...

  6. js 动态 添加 tabel 表格

    js 动态 添加 tabel 表格 代码 <!DOCTYPE html> <html><head><title> new document </t ...

  7. form表单 无法提交js动态添加的表单元素问题。。

    第一种情况, 这种情况js动态添加的表单元素是不能提交到服务器端的 <table> <form method="post" action=" url   ...

  8. layui upload.render上传组件js动态添加html后再次渲染

    页面效果 页面代码: <!-- 轮播图 --><input type="hidden" name="mcBaunell" id="m ...

  9. html中列表前面的序号带圆圈,js动态添加带圆圈序号列表方法

    js动态添加带圆圈序号列表方法 发布时间:2021-02-19 11:30:34 来源:亿速云 阅读:69 作者:小新 这篇文章给大家分享的是有关js动态添加带圆圈序号列表方法的内容.小编觉得挺实用的 ...

最新文章

  1. css炫酷标题,纯css3鼠标滑过图片炫酷标题显示特效
  2. python入门用spyder还是jupyter_python3工作环境部署+spyder3+jupyter notebook
  3. 网络流之——最小费用最大流
  4. 使用Dockerfile部署vue项目
  5. LeetCode MySQL 1205. 每月交易II(union all)*
  6. java 责任链模式 链表_责任链模式的实现及源码中应用
  7. 顺序查找(Linear Search)
  8. s和jquery设置disabled属性为true使按钮失效
  9. 排序算法专题-计数排序
  10. php5.1 0day,关于phpwind 5.01-5.3 0day的分析
  11. python神经网络编程 豆瓣,神经网络算法python实现
  12. ps 绘制的 路径丢失了
  13. Alice and the List of Presents CodeForces - 1236B 数学推导
  14. 传统安防监控直播的四分屏的前端展示代码
  15. 白帽子讲web安全之 浏览器安全
  16. 【温故知新】梳理React中HOC的点点滴滴
  17. win10内存占用过高
  18. Kafka topic分区增加副本
  19. 2019年,P2P的春天会来临吗?
  20. HTML入门---慕课网

热门文章

  1. 前端修炼の道:第一个 HTML 页面
  2. DDS的verilog 实现个人总结
  3. 【WPF、UWP】搜索蓝牙设备
  4. 关于U盘病毒(又名Autorun病毒)
  5. 《安富莱嵌入式周报》第285期:电子技术更新换代太快,我要躺平,Linux内核6.1已经并入RUST,一夜161个网站密码遭泄,Matlab精选课件,开源电子书
  6. 用wxBot和图灵机器人API实现微信群聊机器人
  7. 火山PC自绘高级表格及超级列表框
  8. 小白福利-手把手教你如何重新安装你的系统
  9. Cadence OrCAD Capture 在Excel中编辑所有元件属性然后导入设计图纸的方法
  10. C++ Concurrency in Action, Second Edition阅读笔记(一、二章)