(function(window,undefined){
var arr = [],
push = arr.push,
slice = arr.slice;
//首先要做的就是封装一个parseHtml函数
//要注意的是,parthHtml要放在一个自调用函数内
var parseHtml = (function(){
//做一个模板
var div = document.createElement('div');
//这个函数是用来创建标签
function parseHtml(html){
var res = [];
//这边是将具有html语义的字符串放在模板div中,div里面的就有这些标签了
div.innerHTML = html;
//这个时候div里有标签元素,循环遍历div里面的元素
for(var i = 0;i < div.childNodes.length;i++){
//这边是将div模板里面的元素一一放到res数组里,因为这边的div.childNodes[i]是单个元素,可以直接push进数组
res.push(div.childNodes[i]);
}
//完成之后,将div里面的元素清除掉,方便下一次使用
div.innerHTML = '';
//将这个数组返回
return res;
}
return parseHtml;
})();
//封装insertBefore方法
function prependChild(parent,element){//传入的元素是父元素,要插入的元素
var first = parent.firstChild;//将父元素中的第一个元素取出来
parent.insertBefore(element,first);//使用insertBefore方法将element插入到父元素的第一个子元素的前面
}
//封装cc函数
function cc(html){
//这边返回的是cc原型对象里面的一个方法创建出来的实例
return new cc.fn.init(html);
}
//这边是为了后面书写方便
cc.fn = cc.prototype = {
constructor : cc,
length : 0,
//这两个属性要加到原型上
selector: '',//这两个属性在init所创建的实例之中还会用到,所以要加到这个原型上面
type : 'cc',
init : function(html){//这个函数的作用就是:1.创建实例;2.在这个函数里面对所传入的参数进行一个判断
this.events = {};
if(html == ''){//这边判断传入的参数是不是一个空字符串
return;//如果传入的是一个空字符串,那么就直接返回this,注意,这边虽然没写返回this,但是他是默认的
}else if(cc.isString(html)){//这边是当传入的html是字符串的时候
if(/^</.test(html)){//这边的html是标签组成的字符串
push.apply(this,parseHtml(html));
}else{//这边的html是选择器字符串
//这边的this指的是通过:cc.prototype.init这个函数创建出来的实例
push.apply(this,select(html));
//将这个实例的selector设置成html
this.selector = html;
}
}else if(html && html.type === 'cc'){//这边是当传入的html是一个cc对象的时候
push.apply(this,html);
this.selector = html.selector;
this.events = html.events;
}else if(html && html.nodeType){//这边是当传入的是一个dom对象的时候,因为dom对象都有nodeType属性
this[0] = html;
this.length = 1;
}else if(typeof html === 'function'){//这边是当传入的是一个函数的时候,进入里面
var oldfunc = onload;//将原来onload里面的函数取出来
if(typeof oldfunc === 'function'){
onload = function(){
oldfunc();
html();
}
}else{
onload = html;
}
}
}
};
//将封装好的select方法放到这里面
var select = (function () {
//这是一个异常与捕获的代码,它表示的意思是:如果push方法出现了错误那么就需要重写push方法
try {
//这边是自己模拟一个场景,来使用系统的push方法,如果可以实现的话就证明系统支持push方法
//这种方法是系统能力检测中的方法功能检测
var div = document.createElement( 'div' );
div.innerHTML = '<p></p>';
var arr = [];
push.apply( arr, div.getElementsByTagName( 'p' ));
} catch ( e ) {
//这边是当try里面的push方法不执行的时候,会进入这里面
//在这里面将push重新定义了一下,将其变为一个对象,这个对象里面有一个push方法
var push = {
//将apply变成了push对象里面的一个方法
apply: function ( array1, array2 ) {
for ( var i = 0; i < array2.length; i++ ) {
//注意这边的赋值
array1[ array1.length++ ] = array2[ i ];
}
}
};
}
// 正则表达式
//这句正则表达式是为了匹配系统中是否有自带的方法
var rnative = /\{\s*\[native/;
var rtrim = /^\s+|\s+$/g;
//这个是为了匹配出 Id 类名 通配符 标签名
// 1 2 3 4
var rbaseselector = /^(?:\#([\w\-]+)|\.([\w\-]+)|(\*)|(\w+))$/;
// 基本函数, support 对象, 验证 qsa 与 byclass
var support = {};
//基本函数里面的一个属性,实质上是为了看一下系统中是否有该方法(使用正则来判断)
support.qsa = rnative.test( document.querySelectorAll + '' );
//同上
support.getElementsByClassName = rnative.test( document.getElementsByClassName + '' );
support.trim = rnative.test( String.prototype.trim + '' );
support.indexOf = rnative.test( Array.prototype.indexOf + '' );
// 基本方法
//封装了getElementsByClassName函数,这是为了解决兼容问题
//传入两个参数,一个是className,另一个是node-->这个node指的是从页面上的node元素开始查找这个className
function getByClassName ( className, node ) {
//如果没有传入node的话就给它一个默认值:document
node = node || document;
//声明一些变量
var allElem, res = [], i;
//首先做判断,如果系统有这个方法会使用系统的
if ( support.getElementsByClassName ) {
//直接使用定义的push方法
return push.apply(res,node.getElementsByClassName( className ));
} else {
allElem = node.getElementsByTagName( '*' );
for ( i = 0; i < allElem.length; i++ ) {
if ( allElem[ i ].className === className ) {
res.push( allElem[ i ] );
}
}
return res;
}
}
// 自定义实现 trim 方法,该方法是将字符串中的指定的东西去掉
var myTrim = function ( str ) {
// 表示两端去空格, 然后返回去除空格的结果
if ( support.trim ) {
return str.trim();
} else {
// 自定义实现
//这边是将rtrim转换成空字符串,即将空格去掉了
return str.replace( rtrim, '' );
}
}
//这边封装的是indexOf方法,传入三个参数,数组,要搜索的东西,要搜索的东西在数组里面的开始索引(从第几个开始找)
var myIndexOf = function ( array, search, startIndex ) {
//首先将索引赋值,如果传入了索引,那么就让开始的索引等于它,如果没有传入那么就让它从零开始找
startIndex = startIndex || 0;
//这边还是先判断系统有没有这种方法
if ( support.indexOf ) {
//这里表示系统有这种方法,那么就直接使用就OK了,将结果返回
return array.indexOf( search, startIndex );
} else {
//如果没有的话,我们就自己动手封装一个
//对这个数组进行一个遍历,遍历的初始值就是从startIndex开始
for ( var i = startIndex; i < array.length; i++ ) {
//判断一下,如果数组里面有值与要查询的值相等,那么就返回这个索引值
if ( array[ i ] === search ) {
return i;
}
}
//当遍历完成之后,如果还是没有找到的话,就返回-1
return -1;
}
}
//封装一个去重的函数,传入的参数是一个数组
var unique = function ( array ) {
//声明一个空数组,用于接收去重之后的元素
var resArray = [], i = 0;
//对传入的数组进行一个遍历
for ( ; i < array.length; i++ ) {
//做一个判断,如果说resArray里面没有arr里面的元素,则将arr里面的元素放到resArray里面
//注意,这边使用的是之前封装好的myIndexOf方法
if ( myIndexOf( resArray, array[ i ] ) == -1 ) {
//使用的是前面封装好的push方法
resArray.push( array[ i ] );
}
}
//将这个数组返回
return resArray;
}
//这边封装的是四种基本选择器,ID选择器,类选择器,通配符选择器,标签选择器
function basicSelect ( selector, node ) {
//这边的node指的是要在哪一个下面去寻找selector
node = node || document;
var m, res;
if ( m = rbaseselector.exec( selector ) ) {
if ( m[ 1 ] ) { // id选择器
res = document.getElementById( m[ 1 ] );
if ( res ) {//如果res不是一个空的话,进入
return [ res ];
} else {//当res为空的话返回一个空数组
return [];
}
} else if ( m[ 2 ] ) { // class选择器
return getByClassName( m[ 2 ], node );
} else if ( m[ 3 ] ) {//通配符选择器
return node.getElementsByTagName( m[ 3 ] );
} else if ( m[ 4 ] ) {//标签选择器
return node.getElementsByTagName( m[ 4 ] );
}
}
return [];
}
//封装一个组合选择器,这里面的标签使用逗号隔开的
function select ( selector, results ) {
results = results || [];
var m, temp, selectors, i, subselector;
//这边是如果传入的selector不是一个字符串的话,那么返回空数组
if ( typeof selector != 'string' ) return results;
// 表明参数都没有问题, 接下来就是如何选择
// 首先判断 qsa 是否可用
// 然后再 一步步的 自己实现
if ( support.qsa ) {//如果系统有querySelectorAll方法,那么就使用
push.apply( results, document.querySelectorAll( selector ) );
} else {
// 不存在再来考虑自己实现
//首先将传入的参数以逗号隔开,放到一个数组里面
selectors = selector.split( ',' );
// 循环遍历这个数组
for ( i = 0; i < selectors.length; i++ ) {
//在这个循环里面对数组里面的每一个元素进行一个去除空格的操作,保证数据是我们想要的形式
subselector = myTrim( selectors[ i ] );
// 接下来就是 处理 subselector,使用正则进行判断
if ( rbaseselector.test( subselector ) ) {
// 基本选择器
//如果匹配到了就将匹配到的传入到基本的四种选择器函数只中,返回一个数组,将这个数组进行一个push
push.apply( results, basicSelect( subselector ) );
} else {
//如果匹配不到那么就使用 select2 函数
select2( subselector, results );
}
}
}
// 返回 result注意,这个数组要进行一个去重操作
return unique( results );
}
//封装一个后代选择器的函数,传入两个参数
function select2 ( selector, results ) {
results = results || [];
//将这个参数以逗号隔开
var selectors = selector.split( ' ' );
//声明一个数组,这个数组用于存放元素,以及一个node数组,这个数组用于存放从哪一个元素开始找
var arr = [], node = [ document ];
for ( var j = 0; j < selectors.length; j++ ) {
for ( var i = 0; i < node.length; i++ ) {
//因为这边寻找的是后代选择器,所以只要找到最后面的并将其返回就可以了
push.apply( arr, basicSelect( selectors[ j ], node[ i ] ));
}
//在结束的时候将arr里面的值全部给node,要注意此时node里面的值的作用是什么
node = arr;
//将arr清空
arr = [];
}
//在最后将最后一次获取到的node值赋给results
//这里面的值是最后一次获取到的元素,也就是说是要获取的子代元素中的的最后一个元素
push.apply( results, node );
return results;
}
return select;
})();
//让init这个方法的原型与cc这个构造函数的原型相等,这样init的原型里面就有init的方法
cc.fn.init.prototype = cc.fn;
//给cc以及cc原型添加一个混入的方法
cc.extend = cc.fn.extend = function extend(obj){
for(var k in obj){
this[k] = obj[k];
}
}
//给cc混入方法,这些方法都是静态方法
cc.extend({
//给cc混入一个isString方法
isString : function(html){
return typeof html === "string";
},
//给cc混入一个each方法
each : function(arr,fnc){
var i;
if(arr instanceof Array || arr.length >= 0){
for(i = 0; i < arr.length; i ++){
fnc.call(arr[i],i,arr[i]);
}
}else {
for( i in arr){
fnc.call(arr[i],i,arr[i]);
}
}
return arr;
},
map : function(arr,fnc){
var i,tmp,res=[];
if(arr instanceof Array || arr.length >= 0){
for(i =0;i<arr.length;i++){
//这边的tmp的值是这边fnc的返回值,如果说fnc这个函数里面没有返回值的话(return),那么tmp就是undefined
tmp = fnc(arr[i],i);
if(tmp != null){
res.push(tmp);
}
}
}else{
for(i in arr){
tmp = fnc(arr[i],i);
if(tmp != null){
res.push(tmp);
}
}
}
return res;
},
//获取到样式
getStyle : function(dom,styleName){
if(dom.currentStyle){
return dom.currentStyle[styleName];
}else{
return window.getComputedStyle(dom)[styleName];
}
},
getText : function(dom,list){
var node = dom.childNodes;
for(var i = 0;i < node.length;i ++){
if(node[i].nodeType == 3){
list.push(node[i].nodeValue);
}
if(node[i].nodeType == 1){
cc.getText(node[i],list);
}
}
}
});
//核心方法
cc.fn.extend({
//将调用该方法的对象变成数组模式
toArray : function(){
//法一:
/*var res = [];
for(var i = 0;i < this.length; i ++){
res.push(this[i]);
}
return res;*/
//法二:
//这句话的意思是:this.slice(0);--->this指的是实例对象,调用slice将其从一个伪数组变成一个数组
return slice.call(this , 0);
},
//get方法是通过索引值来返回调用该方法的对象/数组里面的对应的值
get : function(index){
if(index === undefined){
return this.toArray();
}
return this[index];
},
//这边的eq返回的是dom对象,这是与get方法的区别,简单地说就是eq返回的是一个init对象,而get返回的是一个元素
eq : function(num){
var dom;
if(num >= 0){
dom = this.get(num);
}else{
dom = this.get(this.length + num);
}
return cc(dom);
},
each : function(fnc){
return cc.each(this,fnc);
},
map : function(fnc){
return cc.map(this,fnc);
}
});
//对DOM的操作方法
cc.fn.extend({
//给cc的原型混入一个appendTo方法,注意这边的原型是与init的原型是一至的
//首先要明白,appendTo方法是将appendT之前的元素添加到appendTo的括号里
appendTo : function(selector){
//首先声明一个ccObj对象,这个对象是和this一样,是init的实例对象
//当我们将selector传入其中时,它会解析出来传入的是一个什么样的参数
//这边的selector参数,其实就是appendTo括号里面的内容
var ccObj = this.constructor(selector);
//这边声明一个新的init的实例对象,这是为了仿照jQuery里面链式原理的写法
//这边执行完该方法之后,返回的是一个dom对象
var newObj = this.constructor();
//这边循环遍历this,这个this指的就是appendTo前面的内容
for(var i = 0;i < this.length;i ++){
//这边循环遍历的是解析了传入参数selector之后得到的一个对象ccObj
for(var j = 0;j < ccObj.length;j ++){
//声明一个变量temp
var temp;
if(j == ccObj.length-1){//当j循环到最后一个的时候,进入这个循环
//将this[i]赋值给temp
temp = this[i];
}else{
//这种情况就是当j值还没有到最后一个的时候
temp = this[i].cloneNode(true);
}
//将temp里面的值,放到之前创建的newobj中,这是为了仿照jQuery里面的链式结构
push.call(newObj , temp);
//将temp添加到ccObj中,temp里面存放的是this伪数组里面的值
ccObj[j].appendChild(temp);
}
}
//这个是:即使完成了这个appendTo操作,返回值依旧是一个cc对象
return newObj;
},
//首先要明确的是:append方法是将append括号里面的加到append前面的元素中
append: function(selector){
//还是一样,先声明一个cc对象,这个对象里面是将传入的参数进行解析
var ccObj = this.constructor(selector);
//这个循环的是创建的cc对象
for(var i = 0;i < ccObj.length;i ++){
//这个循环的是this这个伪数组
for(var j = 0;j < this.length;j ++){
var temp;
if(j == this.length-1){//这边的做法可以参照appendTo的方法封装
temp = ccObj[i];
this[j].appendChild(temp);
}else{
temp = ccObj[i].cloneNode(true);
this[j].appendChild(temp);
}
}
}
return this;
},
prependTo : function(selector){
var ccObj = this.constructor(selector);
var newObj = this.constructor();
for(var i = 0;i< this.length;i ++){
for(var j = 0;j < ccObj.length;j ++){
var temp;
if(j == ccObj.length-1){
temp = this[i];
}else{
temp = this[i].cloneNode(true);
}
push.call(newObj,temp);
prependChild(ccObj[j],temp);
}
}
return newObj;
},
prepend : function(selector){
var ccObj = this.constructor(selector);
for(var i = 0;i < ccObj.length;i ++){
for(var j = 0;j < this.length;j ++){
var temp;
if(j == this.length-1){
temp = ccObj[i];
prependChild(this[j],temp);
}else{
temp = ccObj[i].cloneNode(true);
prependChild(this[j],temp);
}
}
}
return this;
}
});
//事件处理模块
cc.fn.extend({
on : function(type,fn){
if(!this.events[type]){//当this中的events属性里面没有type的时候,进入这个里面
this.events[type] = [];//给它提供一个空数组
//当cc对象中的元素被点击的时候我们应该把数组中保存的函数拿出来一一执行
//我们应该为cc对象中的元素添加事件处理函数
var iObj = this;//将this赋值给iObj,此时iObj就表示创建出来的实例对象
//这边的this指的是实例对象
this.each(function(){//调用这个实例的each方法
var fnc = function(e){//fnc执行的时机是type事件执行的时候,在这个时候跟着传入一个e,这个e是事件参数
for(var i = 0;i < iObj.events[type].length;i ++){
//iObj.events[type][i]指的是:找到iObj对象->events属性->type数组->第i个函数,将之执行
//iObj.events[type][i]指的是:函数
//在执行的时候,这边的this指的是执行点击的这个dom元素
iObj.events[type][i].call(this,e);//这边将e传入到这个执行的函数中
}
}
//如果系统支持addEventListener方法就用它添加事件处理函数f,否则使用attachEvent
//事件参数e是从哪里来的?就是从事件绑定的函数来的
//我们通过addEventListener绑定事件的处理函数为f,那么f就带有了事件参数e
if(this.addEventListener){
this.addEventListener(type,fnc);
}else{
this.attachEvent('on' + type,fnc);
}
});
}
this.events[type].push(fn);
return this;
},
off : function(type,fn){
var arr = this.events[type];
if(arr){
for(var i = arr.length;i >= 0;i --){
if(arr[i] == fn){
arr.splice(i,1);
}
}
}
return this;
}
});
//其他事件
//其他事件的添加是将这些字符串用split方法分隔
var arr =
("blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu").split(' ');
//调用cc的each方法,这个方法里面传入的一个参数是数组,一个参数是函数fnc
cc.each(arr,function(i,v){
//在这个fnc中,
cc.fn[v] = function(fn){
this.on(v,fn);
return this;
}
});
cc.fn.extend({
hover : function(fn1,fn2){
this.mouseover(fn1);
this.mouseout(fn2);
return this;
},
toggle : function(){
var i = 0;
var args = arguments;
this.on('click' , function(e){
args[i % args.length].call(this , e);
i ++;
});
}
});
//样式操作
cc.fn.extend({
css : function(option){
var args = arguments,
argsLength = arguments.length;
if(argsLength == 2){
if(cc.isString(args[0]) && cc.isString(args[1])){
return this.each(function(){
this.style[args[0]] = args[1];
})
}
}
if(argsLength == 1){
if(cc.isString(option)){
return this[0].style[option] || cc.getStyle(this[0],option)
}
if(typeof option === 'object'){
return this.each(function(){
for(var k in option){
this.style[k] = option[k];
}
})
}
}
},
addClass : function(name){
return this.each(function(){
var classText = this.className;
if(classText){
if((' ' + classText +' ').indexOf(' ' + name + ' ') ==-1){
this.className += ' ' + name;//这边是将这个name添加到dom的className中
}
}else{
this.className = name;
}
})
},
removeClass : function(name){
return this.each(function(){
var classText = this.className;
if(classText){
var arr = classText.split(' ');
for(var i = arr.length;i >= 0;i --){
if(arr[i] == name){
arr.splice(i,1);
}
}
this.className = arr.join(' ');
}
})
},
hasClass : function(name){
//法一
/*var boolean;
this.each(function(){
var classText = this.className;
if(classText){
var arr = classText.split(' ');
for(var i = 0;i < arr.length;i ++){
if(arr[i] == name){
boolean = true;
return;
}
}
boolean = false;
return;
}
boolean = false;
return;
});
return boolean;*/
//法二
for(var i = 0;i < this.length;i ++){
if((' ' + this[i].className + ' ').indexOf(' ' + name + ' ') != -1){
return true;
}
}
return false;
},
toggleClass : function(name){
if(this.hasClass(name)){
this.removeClass(name);
}else{
this.addClass(name);
}
}
});
//属性操作
cc.fn.extend({
attr: function(name,value){
//第一种情况:有value值以及value值为空时
if(value || value == ''){
//这时要传入的name以及value都要是字符串
if(cc.isString(name) && cc.isString(value)){
this.each(function(){
this.setAttribute(name,value);//设置属性
})
}
}else{//这种情况是当只传了name且name为字符串
if(cc.isString(name)){
//这个时候是获取该属性
return this[0].getAttribute(name);
}
}
//这个是当以上两种都不符合时:
return this;
},
prop : function(name,value){
if(value || value == ''){
if(cc.isString(name) && cc.isString(value)){
this.each(function(){
this[name] = value;
})
}else{
if(cc.isString(name)){
return this[name];
}
}
}
return this;
},
val : function(value){
return this.attr('value',value);
},
html : function(html){
return this.prop('innerHTML',html);
},
text : function(){
var res = [];
cc.getText(this[0],res);
return res.join(' ');
}
});
//给cc原型添加anmite属性
cc.fn.extend({
animate : function(property,time,fn,easing){
var iObj = this
flag = false;
this.each(function(){
move(this,property,time,fn,easing);
});
return this;
function move(node,property,time,fn,easing){//需要传入的参数有:元素,元素要移动的距离,动画执行的时长
var start = {};
for(var k in property){
start[k] = parseInt(cc.getStyle(node,k));
}
var startTime = + new Date;//开始的时间
iObj.timer = setInterval(function(){//设置定时器
var currentTime = + new Date,//当前时间
deltaTime = currentTime - startTime;//当前时间与开始事件的差值,这个差值可以得到的是已经过去了多久
if(deltaTime >= time){//这边如果差值大于规定的时长之后,进入这个判断里面
clearInterval(iObj.timer);//这时候要清除计时器
deltaTime = time;//将差值赋值为要求的时长
flag = true;
}
easing = easing || 'change';
for(var k in property){
node.style[k] = start[k]
+ g(deltaTime,time,start[k],parseInt(property[k]),easing)
+ 'px';
}
if(flag && fn){
fn.call(iObj);
return;
}
},20);
};
function g(deltaTime,time,start,end,easing){
if(easing == 'line'){
return ((end - start)/time)*deltaTime;
}else if(easing == 'change'){
var distance = end - start;//需要移动的距离
//法一:
//return distance*Math.sin(daleTime*Math.PI/2/time);
//法二:
return distance*(Math.log(deltaTime + 1) / Math.log(time + 1));
}
}
},
timer : null,
stop : function(){
clearInterval(this.timer);
this.timer = null;
}
})
//在桌面上可以使用I以及cc来调用沙箱内部的cc函数
window.C = window.cc = cc;
})(window);
仿照jQuery进行一些简单的框架封装(欢迎指教~)的更多相关文章
-
.Net Core 简单定时任务框架封装
有段日子没有更新,写点东西冒个泡 .这篇文章过来讲个小东西,也是大家在日常开发中也经常需要面临的问题:后台定时任务处理.估计大家看到这句就已经联想到 QuartZ 等类似第三方类库了,不好意思,后边的 ...
-
【JavaScript框架封装】使用原生js封装的类似于JQuery的框架及核心源码分享(多文件版本)
这个版本的JQuery是对上一个版本的JQuery,使用了require.js进行了二次封装,基本上把前面的每一个框架封装成为一个单独的模块,最终的目录结构如下: 由于代码量和目录比较多,这个封装好的 ...
-
【JavaScript框架封装】自己动手封装一个涵盖JQuery基本功能的框架及核心源码分享(单文件版本)
整个封装过程及阅读JQuery源码的过程基本上持续了一个月吧,最终实现了一个大概30%的JQuery功能的框架版本,但是里面涉及的知识点也是非常多的,总共的代码加上相关的注释大概在3000行左右吧,但 ...
-
C# .NET Socket 简单实用框架,socket组件封装
参考资料 https://www.cnblogs.com/coldairarrow/p/7501645.html 根据.NET Socket 简单实用框架进行了改造,这个代码对socket通信封装还是 ...
-
第209天:jQuery运动框架封装(二)
运动框架 一.函数------单物体运动框架封装 1.基于时间的运动原理 动画时间进程 动画距离进程 图解: 物体从0移动到400 当物体移动到200的时候 走了50% 同样的,物体总共运行需要4秒 ...
-
Magicodes.WeiChat——后台JS框架封装
Magicodes.WeiChat同时也致力于提高后台开发效率,因此对在后台前端这块也做了一定的封装.我们先来说说主要的框架JS——mwc.js和mwc_elements.js.这两个JS文件位于Sc ...
-
.NET 跨平台RPC框架DotNettyRPC Web后台快速开发框架(.NET Core) EasyWcf------无需配置,无需引用,动态绑定,轻松使用 C# .NET 0配置使用Wcf(半成品) C# .NET Socket 简单实用框架 C# .NET 0命令行安装Windows服务程序
.NET 跨平台RPC框架DotNettyRPC DotNettyRPC 1.简介 DotNettyRPC是一个基于DotNetty的跨平台RPC框架,支持.NET45以及.NET Standar ...
-
读jQuery源码之整体框架分析
读一个开源框架,大家最想学到的就是设计的思想和实现的技巧.最近读jQuery源码,记下我对大师作品的理解和心得,跟大家分享,权当抛砖引玉. 先附上jQuery的代码结构. (function(){ / ...
-
对jquery的ajax进行二次封装
第一种方法: $(function(){ /** * ajax封装 * url 发送请求的地址 * data 发送到服务器的数据,数组存储,如:{"username": " ...
随机推荐
-
LDA的Python实现源码
#-*- coding:utf-8 -*- import logging import logging.config import ConfigParser import numpy as np im ...
-
asp.net c# 打开新页面或页面跳转
1.最常用的页面跳转(原窗口被替代):Response.Redirect("XXX.aspx"); 2.利用url地址打开本地网页或互联网:Respose.Write(" ...
-
AD域环境的搭建 基于Server 2008 R2
AD(Active Directory)即活动目录,微软的基础件.微软的很多产品如:Exchange Server,Lync Server,SharePoint Server,Forefront Se ...
-
前端学PHP之自定义模板引擎
前面的话 在大多数的项目组中,开发一个Web程序都会出现这样的流程:计划文档提交之后,前端工程师制作了网站的外观模型,然后把它交给后端工程师,它们使用后端代码实现程序逻辑,同时使用外观模型做成基本架构 ...
-
[scrapy]使用Anaconda来搭建scrapy的运行环境。官方推荐方法。
1.官方文档推荐. 2.一般情况下多数人使用框架的时候使用的是,安装pywin32,和openssl来搭建scrapy的运行环境.但是由于,在这样搭建环境中会遇到各种各样的问题,诸如:下载的版本有问题 ...
-
JS-函数作用域
如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量.
-
谷歌地图,国内使用Google Maps JavaScript API,国外业务
目前还是得墙 <!DOCTYPE html> <html> <head> <meta name="viewport" content=&q ...
-
【转】在 XAML 的属性中,转义大括号 {}
我们知道大括号"{}"在XAML中是用来处理标记扩展的. 比如: <Button Content="{Binding}"/> 但如何转义而表示普 ...
-
html标签之img
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
-
Freemarker 基本数据类型
一 数据类型简介 freemarker 模板中的数据类型由如下几种: 1. 布尔型:等价于java中的boolean类型, 不同的是不能直接输出,可以转换成字符串再输出 2. 日期型:等价于java中 ...