仿写一个简单的jQuery(学习笔记)

jQuery学习笔记:

function myAddEvent(obj, sEv, fn)
{
	if(obj.attachEvent)
	{
		obj.attachEvent('on'+sEv, function (){
			if(false==fn.call(obj))
			{
				event.cancelBubble=true;
				return false;
			}
		});
	}
	else
	{
		obj.addEventListener(sEv, function (ev){
			if(false==fn.call(obj))
			{
				ev.cancelBubble=true;
				ev.preventDefault();
			}
		}, false);
	}
}

function getByClass(oParent, sClass)
{
	var aEle=oParent.getElementsByTagName('*');
	var aResult=[];
	var i=0;
	
	for(i=0;i<aEle.length;i++)
	{
		if(aEle[i].className==sClass)
		{
			aResult.push(aEle[i]);
		}
	}
	
	return aResult;
}

function getStyle(obj, attr)
{
	if(obj.currentStyle)
	{
		return obj.currentStyle[attr];
	}
	else
	{
		return getComputedStyle(obj, false)[attr];
	}
}

function VQuery(vArg)
{
	//用来保存选中的元素
	this.elements=[];
	
	switch(typeof vArg)
	{
		case 'function':
			//window.οnlοad=vArg;
			myAddEvent(window, 'load', vArg);
			break;
		case 'string':
			switch(vArg.charAt(0))
			{
				case '#':	//ID
					var obj=document.getElementById(vArg.substring(1));
					
					this.elements.push(obj);
					break;
				case '.':	//class
					this.elements=getByClass(document, vArg.substring(1));
					break;
				default:	//tagName
					this.elements=document.getElementsByTagName(vArg);
			}
			break;
		case 'object':
			this.elements.push(vArg);
	}
}

function $(vArg)
{
	return new VQuery(vArg);
}

VQuery.prototype.click=function (fn)
{
	var i=0;
	
	for(i=0;i<this.elements.length;i++)
	{
		myAddEvent(this.elements[i], 'click', fn);
	}
	
	return this;
};

getElementById():Document对象,语法:document.getElementById("demo");返回值是元素对象

getElementsByClassName():元素对象,语法:element.getElementsByClassName(classname),返回值是
NodeList 对象,表示指定类名的元素集合。是类数组,不能使用数组方法。

var list = document.getElementsByClassName("example")[0];
list.getElementsByClassName("child")[0].innerHTML = "Milk";

getElementsByTagName():元素对象,element.getElementsByTagName(tagname);返回值是NodeList 对象,表示指定类名的元素集合。是类数组,不能使用数组方法。

var list=document.getElementsByTagName("UL")[0];
list.getElementsByTagName("LI")[0].innerHTML="Milk";


VQuery是一个构造函数,new出的对象有elements属性,用来存放所选择的元素,这是核心。VQuery.prototype原型对象下存在很多函数,例如click,new出来的VQuery对象可以使用这些函数,来操作每个对象下elements存储的DOM元素,例如:

new VQuery('#demo').click(function(){alert(1)});
但是这样写有点麻烦,每次都要写new,于是
function $(vArg)
{
	return new VQuery(vArg);
}
$('#demo').click(function(){alert(1)});
这样写比较简便,选中ID为#demo的元素,存放在elements中,click等函数可以对this.elements[i],即DOM元素进行操作,this指new出来的VQuery对象。

myAddEvent()中两种情况取消冒泡都是用了cancelBubble,这是因为cancelBubble在新版本chrome,opera浏览器中已经支持。但是cancelBubble不是W3C标准,stopPropagation()才是。

在IE下window.event.returnValue=false;和return false;都可以阻止默认事件。

if(false==fn.call(obj))
{
        event.cancelBubble=true;
	return false;
}
这种写法的目的:当添加事件执行的函数返回false,就同时取消冒泡和默认事件。


click():VQuery对象中elements可能会存放多个DOM元素,所以要进行for循环操作,给每一个DOM元素添加事件,函数返回this,this就是VQuery对象,目的是为了进行链式操作。

VQuery.prototype.click=function (fn)
{
	var i=0;
	
	for(i=0;i<this.elements.length;i++)
	{
		myAddEvent(this.elements[i], 'click', fn);
	}
	
	return this;
};
show(),hide(),hover()函数原理上和click函数相同:进行for循环操作,返回this。

VQuery.prototype.show=function ()
{
	var i=0;
	
	for(i=0;i<this.elements.length;i++)
	{
		this.elements[i].style.display='block';
	}
	
	return this;
};

VQuery.prototype.hide=function ()
{
	var i=0;
	
	for(i=0;i<this.elements.length;i++)
	{
		this.elements[i].style.display='none';
	}
	
	return this;
};

VQuery.prototype.hover=function (fnOver, fnOut)
{
	var i=0;
	
	for(i=0;i<this.elements.length;i++)
	{
		myAddEvent(this.elements[i], 'mouseover', fnOver);
		myAddEvent(this.elements[i], 'mouseout', fnOut);
	}
	
	return this;
};
css():首先判断参数的个数:

两个,则进行css设置,

一个,并且是字符串,则进行css读取,

一个,并且是object,即json格式,则进行css设置
读取时,是读取第一个DOM的css格式,即elements[0],不用进行for循环,

设置时,每个DOM元素都要设置相同的样式,多以要进行for循环。

最后返回this,目的是进行链式操作。

VQuery.prototype.css=function (attr, value)
{
	if(arguments.length==2)	//设置样式
	{
		var i=0;
		
		for(i=0;i<this.elements.length;i++)
		{
			this.elements[i].style[attr]=value;
		}
	}
	else	//获取样式
	{
		if(typeof attr=='string')
		{
		//return this.elements[0].style[attr];
			return getStyle(this.elements[0], attr);
		}
		else
		{
			for(i=0;i<this.elements.length;i++)
			{
				var k='';
				
				for(k in attr)
				{
					this.elements[i].style[k]=attr[k];
				}
			}
		}
	}
	
	return this;
};
attr():如果是两个参数,则对每个DOM元素进行设置,需要for循环操作,如果只有一个参数,则只读取第一个DOM元素的属性值,最后返回this。

VQuery.prototype.attr=function (attr, value)
{
	if(arguments.length==2)
	{
		var i=0;
		
		for(i=0;i<this.elements.length;i++)
		{
			this.elements[i][attr]=value;
		}
	}
	else
	{
		return this.elements[0][attr];
	}
	
	return this;
};
toggle():将fn1,fn2,fn3...作为参数传递给toggle函数,给每个元素添加click事件,每次点击执行不同的时间,第一次点击执行fn1,第二次点击执行fn2,循环执行。这是因为addToggle()函数中的myAddEvent()引用了count变量,形成闭包

VQuery.prototype.toggle=function ()
{
	var i=0;
	var _arguments=arguments;
	
	for(i=0;i<this.elements.length;i++)
	{
		addToggle(this.elements[i]);
	}
	
	function addToggle(obj)
	{
		var count=0;
		myAddEvent(obj, 'click', function (){
			_arguments[count++%_arguments.length].call(obj);
		});
	}
	
	return this;
};
eq():返回一个VQuery对象,该对象中的elements存放下标对应的DOM元素

VQuery.prototype.eq=function (n)
{
	return $(this.elements[n]);
};
find():把所有复合要求的元素存放在aResult数组中,新建一个VQuery对象,把 aResult赋值给VQuery对象的elements属性,返回VQuery对象。

function appendArr(arr1, arr2)
{
	var i=0;
	
	for(i=0;i<arr2.length;i++)
	{
		arr1.push(arr2[i]);
	}
}

VQuery.prototype.find=function (str)
{
	var i=0;
	var aResult=[];
	
	for(i=0;i<this.elements.length;i++)
	{
		switch(str.charAt(0))
		{
			case '.':	//class
				var aEle=getByClass(this.elements[i], str.substring(1));
				
				aResult=aResult.concat(aEle);
				break;
			default:	//标签
				var aEle=this.elements[i].getElementsByTagName(str);
				
				//aResult=aResult.concat(aEle);
				appendArr(aResult, aEle);
		}
	}
	
	var newVquery=$();
	
	newVquery.elements=aResult;
	
	return newVquery;
};

index():所选元素中的第一个元素,在兄弟元素中的位置。

function getIndex(obj)
{
	var aBrother=obj.parentNode.children;
	var i=0;
	
	for(i=0;i<aBrother.length;i++)
	{
		if(aBrother[i]==obj)
		{
			return i;
		}
	}
}

VQuery.prototype.index=function ()
{
	return getIndex(this.elements[0]);
};
bind():循环执行myAddEvent(),给每个元素添加事件
VQuery.prototype.bind=function (sEv, fn)
{
	var i=0;
	
	for(i=0;i<this.elements.length;i++)
	{
		myAddEvent(this.elements[i], sEv, fn);
	}
};
extend():

VQuery.prototype.extend=function (name, fn)
{
	VQuery.prototype[name]=fn;
};
animate():
$().extend('animate', function (json){
	var i=0;
	
	for(i=0;i<this.elements.length;i++)
	{
		startMove(this.elements[i], json);
	}
	
	function getStyle(obj, attr)
	{
		if(obj.currentStyle)
		{
			return obj.currentStyle[attr];
		}
		else
		{
			return getComputedStyle(obj, false)[attr];
		}
	}
	
	function startMove(obj, json, fn)
	{
		clearInterval(obj.timer);
		obj.timer=setInterval(function (){
			var bStop=true;		//这一次运动就结束了——所有的值都到达了
			for(var attr in json)
			{
				//1.取当前的值
				var iCur=0;
				
				if(attr=='opacity')
				{
					iCur=parseInt(parseFloat(getStyle(obj, attr))*100);
				}
				else
				{
					iCur=parseInt(getStyle(obj, attr));
				}
				
				//2.算速度
				var iSpeed=(json[attr]-iCur)/8;
				iSpeed=iSpeed>0?Math.ceil(iSpeed):Math.floor(iSpeed);
				
				//3.检测停止
				if(iCur!=json[attr])
				{
					bStop=false;
				}
				
				if(attr=='opacity')
				{
					obj.style.filter='alpha(opacity:'+(iCur+iSpeed)+')';
					obj.style.opacity=(iCur+iSpeed)/100;
				}
				else
				{
					obj.style[attr]=iCur+iSpeed+'px';
				}
			}
			
			if(bStop)
			{
				clearInterval(obj.timer);
				
				if(fn)
				{
					fn();
				}
			}
		}, 30)
	}
});
Drag():先计算出事件在元素中的位置(disX,disY),拖动后,用鼠标在屏幕中的位置(clientX,clientY)减去 (disX,disY)。onmouseup时,将document.οnmοusemοve=null;document.onmouseup=null;这是防止松开鼠标键后,元素继续随鼠标移动,注意事项:onmousedown的对象是oDiv,即oDiv.onmousedown;onmousemove和onmouseup的对象的document

$().extend('drag', function (){
	var i=0;
	
	for(i=0;i<this.elements.length;i++)
	{
		drag(this.elements[i]);
	}
	
	function drag(oDiv)
	{
		oDiv.οnmοusedοwn=function (ev)
		{
			var oEvent=ev||event;
			var disX=oEvent.clientX-oDiv.offsetLeft;
			var disY=oEvent.clientY-oDiv.offsetTop;
			
			document.οnmοusemοve=function (ev)
			{
				var oEvent=ev||event;
				
				oDiv.style.left=oEvent.clientX-disX+'px';
				oDiv.style.top=oEvent.clientY-disY+'px';
			};
			
			document.οnmοuseup=function ()
			{
				document.οnmοusemοve=null;
				document.οnmοuseup=null;
			};
		};
	}
});












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个简单的 Python GPT 模型实现。以下是一个基于 TensorFlow 的 GPT-2 模型的简单实现。让我们开始吧! 首先,我们需要安装 TensorFlow 和其他必要的库: ```python !pip install tensorflow !pip install keras !pip install numpy ``` 接下来,我们需要导入所需的库: ```python import tensorflow as tf import numpy as np from keras.layers import Input, Embedding, Dense, LSTM, Lambda, Flatten from keras.models import Model from keras.optimizers import Adam from keras.preprocessing.sequence import pad_sequences from keras.utils import to_categorical ``` 然后,我们需要定义一些模型的超参数: ```python MAX_SEQ_LENGTH = 100 MAX_VOCAB_SIZE = 3000 EMBEDDING_DIM = 50 HIDDEN_DIM = 50 NUM_LAYERS = 2 BATCH_SIZE = 32 EPOCHS = 1000 LEARNING_RATE = 0.0001 ``` 现在,我们可以定义我们的 GPT 模型。我们将使用 LSTM 作为我们的 RNN 层,因为它比 GRU 更加常用。 ```python # 定义输入层 input = Input(shape=(MAX_SEQ_LENGTH,)) # 定义嵌入层 embedding = Embedding(input_dim=MAX_VOCAB_SIZE, output_dim=EMBEDDING_DIM, input_length=MAX_SEQ_LENGTH)(input) # 定义 LSTM 层 lstm = LSTM(units=HIDDEN_DIM, return_sequences=True)(embedding) # 定义输出层 output = TimeDistributed(Dense(units=MAX_VOCAB_SIZE, activation='softmax'))(lstm) # 定义模型 model = Model(inputs=input, outputs=output) # 编译模型 model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=LEARNING_RATE), metrics=['accuracy']) ``` 接下来,我们需要读入我们的数据集。在这里,我们将使用一个简单的文本文件作为我们的数据集。 ```python # 读取文本文件 with open('data.txt', 'r') as f: text = f.read() # 将文本转换成小写 text = text.lower() # 创建字符到索引的映射 char_to_idx = { ch:i+1 for i,ch in enumerate(sorted(set(text))) } # 创建索引到字符的映射 idx_to_char = { i+1:ch for i,ch in enumerate(sorted(set(text))) } # 将文本转换成索引序列 idxs = [char_to_idx[ch] for ch in text] # 计算文本序列的长度 num_chars = len(idxs) ``` 接下来,我们需要创建我们的输入和目标序列。在这里,我们将使用一个滑动窗口来创建我们的输入和目标序列,其中每个输入序列的长度为 MAX_SEQ_LENGTH。 ```python # 创建输入序列和目标序列 input_seq = [] target_seq = [] for i in range(0, num_chars - MAX_SEQ_LENGTH, MAX_SEQ_LENGTH): input_seq.append(idxs[i:i+MAX_SEQ_LENGTH]) target_seq.append(idxs[i+1:i+MAX_SEQ_LENGTH+1]) # 将输入序列和目标序列转换为 numpy 数组 input_seq = np.array(input_seq) target_seq = np.array(target_seq) # 将目标序列进行 one-hot 编码 target_seq = to_categorical(target_seq, num_classes=MAX_VOCAB_SIZE) ``` 现在,我们可以训练我们的 GPT 模型: ```python # 训练模型 model.fit(input_seq, target_seq, batch_size=BATCH_SIZE, epochs=EPOCHS, verbose=1) ``` 最后,我们可以使用我们的模型来生成新的文本: ```python # 生成新的文本 def generate_text(model, seed_text, num_chars): # 将种子文本转换为索引序列 seed_idx = [char_to_idx[ch] for ch in seed_text] # 循环生成新的文本 for i in range(num_chars): # 将种子文本进行填充 padded_seed = pad_sequences([seed_idx], maxlen=MAX_SEQ_LENGTH, padding='post') # 预测下一个字符的概率分布 probs = model.predict(padded_seed)[0, -1, :] # 从概率分布中采样下一个字符 next_idx = np.random.choice(len(probs), p=probs) # 将下一个字符添加到生成的文本中 seed_idx.append(next_idx) # 将索引序列转换为文本 generated_text = ''.join([idx_to_char[idx] for idx in seed_idx]) return generated_text # 生成新的文本 generated_text = generate_text(model, 'hello world', 1000) # 打印生成的文本 print(generated_text) ``` 这就是一个简单的 Python GPT 模型的实现。当然,这只是一个基于 LSTM 的简单实现,与 GPT-2 模型相比,还有很大的改进空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值