深入PHP许愿墙模块功能分析
发布时间:2020-12-13 06:26:50 所属栏目:PHP教程 来源:网络整理
导读:FONT style="COLOR: #0000ff" 许愿墙模块功能分析 FONT style="COLOR: #ff0000"一,热点技术 1,实现可拖放DOM技术移动许愿字条 可拖放DOM模式(Draggable DOM pattern)的宗旨在于允许浏览者自己定义页面中各元素的位置,并且,只需要用鼠标选中要移动的部分
<FONT style="COLOR: #0000ff"> 许愿墙模块功能分析<FONT style="COLOR: #ff0000">一,热点技术可拖放DOM模式(Draggable DOM pattern)的宗旨在于允许浏览者自己定义页面中各元素的位置,并且,只需要用鼠标选中要移动的部分,把它拖到新的位置上,就可以定制页面。DOM是Document Object Model文档对象模型的缩写,是一种与浏览器、平台、语言无关的接口,使用户可以访问页面其他的标准组件。DOM是以层次结构组织的节点或信息片段的集合。这个层次结构允许开发人员在树中导航寻找特定信息。分析该结构通常需要加载整个文档的构造层次结构,然后才能做任何工作。由于它基于信息层次,因此DOM被认为基于树或基于对象。 |
爱墙编号:".$id."".$sendtime."× |
<a href='#' onclick='holdout(".$id.",".$hits.")''>[祝福你]福气:".$hits." QQ:".$QQ." |
";
当按下鼠标左键时,应用鼠标时间onmousedown触发Move()函数
<div class="codetitle"><a style="CURSOR: pointer" data="46785" class="copybut" id="copybut46785" onclick="doCopy('code46785')"> 代码如下:<div class="codebody" id="code46785">
var Layer='';
document.onmouseup=moveEnd;
document.onmousemove=moveStart;
var b;
var c;
function Move(Object,event){//移动DIV许愿字条
Layer=Object.id;
if(document.all){
document.getElementById(Layer).setCapture();
b=event.x-document.getElementById(Layer).style.pixelLeft;//设置左边框
c=event.y-document.getElementById(Layer).style.pixelTop;//设置右边框
}else if(window.captureEvents){
window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
b=event.layerX;//返回时间对象相对于本体的横坐标
c=event.layerY;//返回时间对象相对于本体的纵坐标
}
/实现鼠标单击字条时,字条置上/
document.getElementById(Layer).style.zIndex=iLayerMaxNum;
iLayerMaxNum=iLayerMaxNum+1;
/****/
}
document.all是文档中所有标签组成的一个数组变量,包括了文档对象中的所有元素,这个数组可以访问文档中的所有元素。
语法:
<FONT style="COLOR: #ff0000">document.all[i]document.all[name]
document.all.tags[tagname]
说明:
all[]是一个多功能的类似数组的对象,它提供了对文档中所有HTML元素的访问。all[]数组源自于IE4并已经被很多其他浏览器采用all[]已经被Document接口的标准的getElementById()方法和getElementByTagName()方法以及Document对象的getElementByName()方法所取代。all[]包含的元素保存了最初的顺序,如果你知道他们在数组中的确切数字化位置,可以直接从数组中提取他们。然而,更为常见的是使用all[]数组,根据他们的HTML属性name或id来访问元素。如果元素拥有指定的name,将得到共享同一名称的元素的一个数组。document.all可以判断浏览器是否是IE
<div class="codetitle"><a style="CURSOR: pointer" data="24759" class="copybut" id="copybut24759" onclick="doCopy('code24759')"> 代码如下:<div class="codebody" id="code24759">
if(document.all){
alert("is IE!");
}
window.captureEvents()
window.captureEvents(event1 | event2 | eventN)
captureEvents()方法捕获所有发生的事件类型,如果有多个事件发生,则用|竖线隔开;captureEvents()方法主要事件如下:
Event.ABORT
Event.BLUR
Event.CHANGE
Event.CLICK
Event.DBLCLICK
Event.DRAGDROP
Event.ERROR
Event.FOCUS
Event.KEYDOWN
Event.KEYPRESS
Event.KEYUP
Event.LOAD
Event.MOUSEDOWN
Event.MOUSEMOVE
Event.MOUSEOUT
Event.MOUSEOVER
Event.MOUSEUP
Event.MOVE
Event.RESET
Event.RESIZE
Event.SELECT
Event.SUBMIT
Event.UNLOAD
示例代码:
<div class="codetitle"><a style="CURSOR: pointer" data="64280" class="copybut" id="copybut64280" onclick="doCopy('code64280')"> 代码如下:<div class="codebody" id="code64280"><script language="JavaScript1.2">
<form name="myForm">
当鼠标移动时,触发moveStart()函数,代码如下:
<div class="codetitle"><a style="CURSOR: pointer" data="45717" class="copybut" id="copybut45717" onclick="doCopy('code45717')"> 代码如下:<div class="codebody" id="code45717">
function moveStart(d){
if(Layer!=''){//如果图层不为空
if(document.all){
document.getElementById(Layer).style.left=event.x-b;//设置左边距
document.getElementById(Layer).style.top=event.y-c;//设置右边距
}else if(window.captureEvents){
document.getElementById(Layer).style.left=(d.clientX-b)+"px";
document.getElementById(Layer).style.top=(d.clientY-c)+"px";
}
}
}
应用DOM方法(document对象的getElementById方法)获取包含许愿字条layer层左边距和上边距的距离。b和c分别表示获取Layer层的横纵坐标。
clientX:
检索与窗口客户区域有关的鼠标坐标的x坐标,属性为只读,没有默认值。clientY:
检索与窗口客户区域有关的鼠标光标的y坐标,属性为只读,没有默认值。<FONT style="COLOR: #ff0000">clientX,pageX,offsetX,x,layerX,screenX,offsetLeft
各浏览器通用属性:
screenX:
鼠标在显示屏幕上的坐标。clientX:
鼠标在页面显示区域的坐标。
特有属性:(
注:IE和FF的定位有个1px的差别,实际上,IE的定位从0开始,FF的定位从1开始,FF永远会比IE大1px,需要根据实际情况处理。)pageX:FF特有,鼠标在页面上的位置,从页面左上角开始定位,这个可以很方便在整个页面上进行定位,IE没有直接替换的属性。
layerX:
FF特有,鼠标相对于“触发事件的元素的层级关系中离该元素最近的,设置了position的父元素”的边界的位置,从border的左上角开始定位,即如果这个父元素存在border,则坐标原点在border的左上角,而不是内容区域的左上角。offsetX:IE特有,鼠标相对于“触发事件的元素”的位置,从内容区域左上角开始定位,不是从border左上角开始!这个属性比较好用,用来判断鼠标点在一个元素中的哪个位置很方便,FF没有直接替换的属性。
x:
IE特有,跟layerX一个效果,可作为layerX的直接替换属性。offsetLeft:
这个属性不是事件对象的属性,而是DOM对象所有的,该属性表示的是DOM对象在“该DOM对象的层级关系中离该对象最近的,设置了position的父对象”中的位置,虽然话是这么说的,但是不同的浏览器效果不一样,FF中严格按上述说明执行,但是在IE6/7中,这个属性返回该DOM对象在其直接父对象中的位置,但是IE8改正了这个问题,不过IE8又有了一个新问题,其他的浏览器都是从父对象的内容区域的左上角开始定位,IE8确是从父元素的border的左上角开始定位,由于测试环境为IETester中的IE8,不能排除是IETester的问题。当鼠标抬起时,触发moveEnd()函数,代码如下:
<div class="codetitle"><a style="CURSOR: pointer" data="27963" class="copybut" id="copybut27963" onclick="doCopy('code27963')"> 代码如下:<div class="codebody" id="code27963">function moveEnd(d){
if(Layer!=''){ //如果layer图层不为空
if(document.all){
document.getElementById(Layer).releaseCapture();
Layer='';//将layer图层设为空
}else if(window.captureEvents){
window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
Layer='';//将layer图层设为空
}
}
}
在上面的代码中,setCapture()函数的作用是将后续的mouse事件都发送给这个对象,releaseCapture()函数是将mouse事件返回,由document、window等对象来自行处理,这样就保证了在拖动的过程中,不会由于经过了其他元素而受到干扰。另外,还有一个很重要的因素,在win32上,MOUSEMOVE的时间不是连续的,并不是每次移动一个像素的鼠标指针,就会发生一个MOUSEMOVE事件,Windows会周期性检测鼠标指针的位置变化来产生MOUSEMOVE的事件。所以,如果是一个很小的页面对象,例如一个直径5像素的圆点,如果没有setCapture和releaseCapture,那么在按住鼠标之后,快速地移动鼠标,就有可能鼠标移动走了但小圆点还在原地,就是因为下一次的mousemove事件已经不再发给这个圆点对象了。
2,对QQ号文本框中禁止非数字字符输入
在动态网站中,为了确保用户输入的文本或数值的有效性,必须对用户输入的数据加以验证,确保数据的准确及安全性。本模块禁止用户向QQ文本框中输入汉字或英文字符。<div class="codetitle"><a style="CURSOR: pointer" data="54667" class="copybut" id="copybut54667" onclick="doCopy('code54667')"> 代码如下:<div class="codebody" id="code54667">
<input name="QQ" type="text" id="QQ"
<SPAN style="WHITE-SPACE: pre">onKeyUp="setQQ();if(/(^0+)/.test(value))value=value.replace(/^0/,'')"
<SPAN style="WHITE-SPACE: pre">onKeyDown="setQQ();" //键盘按下时触发,比如按着1不放时,该函数生效
<SPAN style="WHITE-SPACE: pre">onKeyPress="return event.keyCode>=48 && event.keyCode<=57;" size="16" maxlength="10"
<SPAN style="WHITE-SPACE: pre">onpaste="var s=clipboardData.getData('text'); if(!/D/.test(s))value=s.replace(/^0/,'');
<SPAN style="WHITE-SPACE: pre">return false;"
/>
上面代码中,分别应用3个事件来控制QQ号输入的值。
onKeyUp事件:事件会在键盘按键被松开时发生。如果是数字则可以添加到QQ号文本框中。
onKeyPress事件:事件会在键盘按键被按下并释放一个键时发生。只允许用户输入0~9之间的数字。
onpaste事件:当用户粘贴数据以便从系统剪切板向文档传送数据时在目标对象上触发。当用户向QQ号文本框中粘贴字符串时,只允许用户粘贴数字串。
另外,应用isNaN()方法来验证输入的QQ号是否是数值型。
isNaN(num Value);
numvalue:是必选项,用来检查是否为NaN的值。
当提交签字许愿字条时,将触发checkForm()函数,应用document.getElementById()函数和表单字段的ID(QQ文本框的ID号为“QQ”)来直接获取这个元素。应用isNaN()方法来验证QQ号是否为数值型。
<div class="codetitle"><a style="CURSOR: pointer" data="74557" class="copybut" id="copybut74557" onclick="doCopy('code74557')"> 代码如下:<div class="codebody" id="code74557">
function checkForm(){//祝福内容
if(isNaN(document.getElementById('QQ').value)){
alert('您输入的QQ号不是数值型,请重新输入!');
document.getElementById('QQ').focus();
return false;
}
}
常用文本框限制代码:
代码示例:
onkeyup="value=value.replace(/[^a-zA-Z]/g,'')"
说明:
replace(/[^a-zA-Z]/g,'')其中有^为逻辑词“非”,然后后面跟着a-zA-Z指的是英文字母大小写范围,“/g”表示用后面的''中的字符(当前为空)全局替换。
此句代码的含义为:在文本框中只能输入大写或小写字母,如果不是,则自动删除。
常用输入限制代码:
只能输入英文字母:
<div class="codetitle"><a style="CURSOR: pointer" data="41445" class="copybut" id="copybut41445" onclick="doCopy('code41445')"> 代码如下:<div class="codebody" id="code41445">
<input type="text" onkeyup="value=value.replace(/[^a-zA-Z]/g,'')"/>
只能输入英文和数字:
<div class="codetitle"><a style="CURSOR: pointer" data="40781" class="copybut" id="copybut40781" onclick="doCopy('code40781')"> 代码如下:<div class="codebody" id="code40781">
<input type="text" onkeyup="value=value.replace(/[^0-9a-zA-Z]/g,'')"/>
<input type="text" onkeyup="value=value.replace(/[W]/g,'')"/> W匹配字母或数字或下划线或汉字,D表示匹配数字
只能输入数字和x(用于身份证号的输入) :
<div class="codetitle"><a style="CURSOR: pointer" data="16214" class="copybut" id="copybut16214" onclick="doCopy('code16214')"> 代码如下:<div class="codebody" id="code16214">
<input type="text" onKeyUp="value=value.replace(/[^d|x]/g,'')"/> |后面的就是可以排除的非数字,可是一个范围x-z
只能输入数字
<div class="codetitle"><a style="CURSOR: pointer" data="89915" class="copybut" id="copybut89915" onclick="doCopy('code89915')"> 代码如下:<div class="codebody" id="code89915">
D表示匹配数字,中文输入法输入时,存在后续表格不能输入中文问题
<input type="text" onKeypress="if(event.keyCode < 45 || event.keyCode >57) event.returnValue = false;"> 不能输入字母,但能输入/.-等
<INPUT TYPE="text" onkeyup="this.value=this.value.replace(/[^d]/g,'')" onpaste="return false">不能输入数字,不允许粘贴
<input name=txt1 onchange="if(/D/.test(this.value)){alert('只能输入数字');this.value='';}">
<input onkeyup="if(isNaN(value))execCommand('undo')" onafterpaste="if(isNaN(value)) execCommand('undo')"> 但可以输入空格,解决中文输入法问题
只能输入字母和汉字(还有一些非数字字符)
<div class="codetitle"><a style="CURSOR: pointer" data="42254" class="copybut" id="copybut42254" onclick="doCopy('code42254')"> 代码如下:<div class="codebody" id="code42254">
<input onkeyup="value=value.replace(/[d]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[d]/g,''))">
小数点后只能有最多两位(数字,中文都可输入),不能输入字母和运算符号
<div class="codetitle"><a style="CURSOR: pointer" data="85238" class="copybut" id="copybut85238" onclick="doCopy('code85238')"> 代码如下:<div class="codebody" id="code85238">
<input onKeyPress="if((event.keyCode<48 || event.keyCode>57) && event.keyCode!=46 || /.dd$/.test(value))event.returnValue=false">
3,限制纸条内容的长度
在签写许愿内容时,通常需要限制用户输入文本的长度。在字符串长度的计算上,汉字是占两个字符(汉字的宽度以及存储所占的位置决定了一个汉字占两个字符),而英文字母和数字都被识别为一个字符。在PHP中获取字符串长度应用strlen()函数实现。但是在本模块中,为了能够实现统计许愿内容所允许输入的剩余字符数,这里就要重新输写计算中英文数字混合字符串长度的函数。在签写许愿内容时,实时限制字符数。添加一个文本框,用来控制输入祝福纸条内容剩余的字节数。
<div class="codetitle"><a style="CURSOR: pointer" data="9401" class="copybut" id="copybut9401" onclick="doCopy('code9401')"> 代码如下:<div class="codebody" id="code9401">
在上面的代码中,应用“freeLength”来实时输出祝福纸条内容所剩余的字符数。
添加一个编辑框用来输入祝福纸条的内容,添加onkeydown和onkeyup事件来触发javascript脚本自定义的函数textCounter(),用来限制该编辑输入的字符数,最多输入150个字符,如果许愿内容大于150,则自动删除,仅保留最大容量值。
<div class="codetitle"><a style="CURSOR: pointer" data="36913" class="copybut" id="copybut36913" onclick="doCopy('code36913')"> 代码如下:<div class="codebody" id="code36913">
<textarea name="content" id="content" cols="66" rows="6"
onkeydown="textCounter(this.form.content,this.form.freeLength,150)"
onkeyup="textCounter(this.form.content,150)"
onafterpaste="textCounter(this.form.content,150)">
在上面的代码中,textCounter()函数有3个参数值,第一个参数值“this.form.content”是指输入的许愿内容;第二个参数值“this.form.freeLength”是指允许输入的许愿内容字符数;第三个参数“150”是输入许愿内容的最大容量值。应用javascript脚本自定义一个函数textCounter(),控制祝福内容不能超过150个字符,这里需要注意的是,中英文所占的字节数不同。DBCS是亚洲的字符集,包含ANSI(ANSI即ASCII码值为0~255之间的字符)。DBCS使用1个或者2个字节来表示一个字符集,超过256个字符则占用两个字节。当字符为ANSI时,存放于文件中只占用1个字节。如果非ANSI(大于256个字符),则占用两个字节。因此,这里就用三目运算符来分别计算英文数字和汉字所占用的字节数。当变量StrValue.charCodeAt(i)小于等于256时,按1个字节计算;大于256时按2个字节计算。
<div class="codetitle"><a style="CURSOR: pointer" data="1260" class="copybut" id="copybut1260" onclick="doCopy('code1260')"> 代码如下:<div class="codebody" id="code1260">
function textCounter(field,countfield,maxlimit) {//祝福内容限制在120个字符内
var StrValue = field.value;
var ByteCount = 0;
var StrLength = field.value.length;
for (i=0;i<StrLength;i++){//记算祝福文字个数,英文数字占1个字符,汉字占2个字
ByteCount = (StrValue.charCodeAt(i)<=256) ? ByteCount + 1 : ByteCount + 2;
}
if(ByteCount<=maxlimit){
strtemp=StrValue;
document.getElementById('ContentSample').innerHTML = StrValue;
countfield.value = maxlimit - ByteCount;
}else{
document.getElementById('content').innerHTML = strtemp;
}
}
该函数只能限制显示部分150字节,但是输入框没有现在,而且粘贴超过150字节时,显示为空白。修改代码如下:
<div class="codetitle"><a style="CURSOR: pointer" data="34777" class="copybut" id="copybut34777" onclick="doCopy('code34777')"> 代码如下:<div class="codebody" id="code34777">
function textCounter(field,maxlimit) {//祝福内容限制在150个字符内
var StrValue = field.value;
var ByteCount = 0;
var StrLength = field.value.length;
var cutstr = '';
for (i=0;i<StrLength;i++){
ByteCount = (StrValue.charCodeAt(i)<=256) ? ByteCount + 1 : ByteCount + 2; //记算祝福文字个数,英文数字占1个字符,汉字占2个字
if( ByteCount<=maxlimit){
cutstr = StrValue.substring(0,i+1); //如果输入字符小于限制长度,截取当前输入字符i+1为输入字符个数
strtemp = cutstr;
} else {
cutstr=strtemp; //否则截取最大输入字符长度
}
}
if(ByteCount<=maxlimit){
document.getElementById('ContentSample').innerHTML = cutstr; //输出显示内容
countfield.value = maxlimit - ByteCount;
}else{
document.getElementById('content').value = cutstr; //限制输入框显示内容
document.getElementById('ContentSample').innerHTML = cutstr; //输出显示内容
countfield.value =0; //剩余字节数
}
}
在上面的代码中,“countfield.value”是用来计算输入字符串剩余的字符数,并将该值赋给textCounter()函数的第2个参数值“this.form.freeLength”,以此来实时计算当前许愿内容所允许输入的字符数量。
4,PHP验证码类当前页面校验验证码输入对与错
当前页面验证输入是否正确的方法Ajax,add.js<div class="codetitle"><a style="CURSOR: pointer" data="7669" class="copybut" id="copybut7669" onclick="doCopy('code7669')"> 代码如下:<div class="codebody" id="code7669">
function codecheck(){
var getVcode = document.getElementById('checkcode').value;//获取验证码输入框的内容
xmlhttp.open("get","codeChk.php?code="+getVcode,true); //将验证码发送到codeChk.php页面检验验证码是否正确
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4)
{
if(xmlhttp.status==200)
{
var msg=xmlhttp.responseText;
if(msg==1){
document.getElementById("messageImg").src="images/dui.gif"; //验证码正确,输出显示正确图片
document.getElementById('txt_hyan').value = getVcode;
}else{
document.getElementById("messageImg").src="images/cuo.gif"; //验证码错误,输出显示错误图片
document.getElementById('checkcode').focus();
return false;
}
}
}
}
xmlhttp.send(null);
}
codeChk.php验证码检验页面
<div class="codetitle"><a style="CURSOR: pointer" data="15550" class="copybut" id="copybut15550" onclick="doCopy('code15550')"> 代码如下:<div class="codebody" id="code15550">
<?php
session_start();
require 'secoder.class.php'; //先把类包含进来,实际路径根据实际情况进行修改。
$vcode = new YL_Security_Secoder(); //实例化一个对象
$code = $_GET['code'];
echo $vcode->check($code); //check($code)函数返回的是true或者false,返回true时,codeChk.php页面输出的是1,否则没有输出
?>
secoder.class.php验证码类中的check($code)函数
<div class="codetitle"><a style="CURSOR: pointer" data="65348" class="copybut" id="copybut65348" onclick="doCopy('code65348')"> 代码如下:<div class="codebody" id="code65348">
public static function check($code) {
isset($_SESSION) || session_start();
// 验证码不能为空
if(empty($code) || empty($_SESSION[self::$seKey])) {
return false;}
// session 过期
if(time() - $_SESSION[self::$seKey]['time'] > self::$expire) {
unset($_SESSION[self::$seKey]);
return false;
}
if(strtoupper($code) == $_SESSION[self::$seKey]['code']) { //不区分大小写比较
return true;
}
return false;}
5,定义生成指定范围的许愿条随机算法
本模块需要生成一个指定范围的随机算法,用来显示许愿字条的显示位置,以使每次展示在读者眼前的都是不同的许愿字条。本模块主要应用rand()函数控制许愿墙纸的显示位置。rand()函数用于产生一个随机整数
<FONT style="COLOR: #ff0000">语法:rand(min,max)
参数:
min,max可选,规定随机数产生的范围如果没有提供可选参数 min 和 max,rand() 返回 0 到 RAND_MAX 之间的伪随机整数。在某些平台下(例如 Windows)RAND_MAX 只有 32768。如果需要的范围大于 32768,那么指定 min 和 max 参数就可以生成大于 RAND_MAX 的数了,或者考虑用 mt_rand() 来替代它。
mt_rand() 使用 Mersenne Twister 算法返回随机整数
<FONT style="COLOR: #ff0000">语法:mt_rand(min,max)
如果没有提供可选参数 min 和 max,mt_rand() 返回 0 到 RAND_MAX 之间的伪随机数。很多老的libc的随机数发生器具有一些不确定和未知的特性而且很慢。php的rand()函数默认使用libc随机数发生器。mt_rand()函数是非正式用来替换它的。该函数用了Mersenne Twister中已知的特性作为随机数发生器,它可以产生随机数值的平均速度比libc提供的rand()快四倍。
随机显示许愿墙纸的关键代码如下:
<div class="codetitle"><a style="CURSOR: pointer" data="42513" class="copybut" id="copybut42513" onclick="doCopy('code42513')"> 代码如下:<div class="codebody" id="code42513">$T=rand(320,520);
$L=rand(5,790);
$Z=$page_count;
$Z = $Z - 3;
echo "
<DIV class='".$pagecolor."'style='left:".$L."px;top:".$T."px;z-index:".$Z.";' id='".$id."' onmousedown='Move(this,".$hits.")''>[祝福你]福气:".$hits." QQ:".$QQ."
6,解析IP获取用户所在城市
在PHP中,使用PHP预定义变量$_SERVER['REMOTE_ADDR']获取客户端的IP地址。然后将IP按照通用的算法将其解析成一个数字串(每个城市都有一个对应的数字串),通过这个数字串来确定查询用户所在的城市名称。在数据库中,IP区域的存储时一个数字串,并非实际的IP地址,这时就需要对客户端或服务器端的IP转换成指定数字串的格式,从而进行地域信息的查询。
<div class="codetitle"><a style="CURSOR: pointer" data="37577" class="copybut" id="copybut37577" onclick="doCopy('code37577')"> 代码如下:
$ip=getenv('REMOTE_ADDR');//获取客户端IP地址
/****解释IP区域/
$cip=cip($ip);
$csql="select from tb_ip where (ip1<'".$cip."' and ip2>'".$cip."') or (ip1=ip2 and ip2='".$cip."')";
//执行查询
$res = $DB->fetch_one_array($csql);
$cip1=$res['country'];
if($cip1==""){
$cip1="IP不详";
}