预备知识点:
二进制数值: 0的二进制数值是 0 1的二进制数值是 1 2的二进制数值是 10 3的二进制数值是 11 4的二进制数值是 100 5的二进制数值是 101 6的二进制数值是 110 ... 在 php 中可以通过 decbin() 函数将十进制数字转换为二进制数字. 位运算符 & (按位与), 什么是 & 运算呢? 以 $c = $a & $b 表达式为例, & 运算是将 $a, $b 的二进制数值相比较, 只要两个二进制数中某位都是1, 则结果的二进制数中该位都为1, 否则结果为 0. 假设: $a 的值为 2 (十进制), 它的二进制数值为 10 $b 的值为 4 (十进制), 它的二进制数值为 100 那么 $c 为 0 (十进制) 因数 $a & $b 的结果为 000(二进制数值), 转换为十进制数值就为 0 假设: $a 的值为 2 (十进制), 它的二进制数值为 10 $b 的值为 6 (十进制), 它的二进制数值为 110 那么 $c 为 2 (十进制) 因数 $a & $b 的结果为 010(二进制数值), 转换为十进制数值就为 2 Javascript/php/mysql 都支持 & 运算.
OK. 进入正题:
我们现在要记录用户的兴趣爱好, 兴趣爱好有很多选项, 可以复选, 表现在页面上就是一堆的 checkbox , 它看起来像是这样子的
<input type="checkbox" name="hobby[]" value="aa">爱好1 <br> <input type="checkbox" name="hobby[]" value="bb">爱好2 <br> <input type="checkbox" name="hobby[]" value="cc">爱好3 <br> <input type="checkbox" name="hobby[]" value="dd">爱好4 <br> <input type="checkbox" name="hobby[]" value="ee">爱好5 <br> <input type="checkbox" name="hobby[]" value="ff">爱好6 <br> <input type="checkbox" name="hobby[]" value="gg">爱好7 <br>
假设用户勾选的是 "爱好1", "爱好3", "爱好5", 我们要怎么把用户勾选的值保存到数据库呢?
方法1:
用特定的分隔符(比如,)把用户勾选的 value 值串连起来? 那么保存到数据库中的值应该是 "aa,cc,ee" 还有别的方法吗?
方法2:
保存到数据库的值是 "1010100" , 这个字串是怎么得来的呢? 设计这种方法的思想是这样的: 数据库中保存一个长度与复选框个数一样的字符串, 这个字串中的第一位就表示第一个复选框, 如果第一个复选框的勾选了, 那字串的第一位就是1. 同样的道理所以字串的第3位,第5位值为1, 其它位值为0. 还有别的方法吗?
我用的是方法3:
重新设计 checkbox 的值, 将它们设置成2的N(N>=0)次方. 它看起来像这样子: <input type="checkbox" name="hobby[]" value="1" >爱好1 <br> <input type="checkbox" name="hobby[]" value="2" >爱好2 <br> <input type="checkbox" name="hobby[]" value="4" >爱好3 <br> <input type="checkbox" name="hobby[]" value="8" >爱好4 <br> <input type="checkbox" name="hobby[]" value="16">爱好5 <br> <input type="checkbox" name="hobby[]" value="32">爱好6 <br> <input type="checkbox" name="hobby[]" value="64">爱好7 <br> 而我要保存到数据库中的值是 21, 没错, 它是一个数字, 它是怎么来的呢? 1+4+16 = 21, 它就是将用户勾选的复选框 value 值累加而以.
为什么是2的N(N>=0)次方? ( 1, 2, 4, 8, 16, 32, ... )
<?php //我们来看看它们的二进制数值有什么特点. echo decbin(1)."<br>"; // 1 echo decbin(2)."<br>"; // 10 echo decbin(4)."<br>"; // 100 echo decbin(8)."<br>"; // 1000 echo decbin(16)."<br>"; // 10000 echo decbin(32)."<br>"; // 100000 echo decbin(64)."<br>"; // 1000000 //来看问题: 为什么要把 value 值设置为2的N(N>=0)次方? //因为2的N(N>=0)次方数字的二进制表示一定是最左边第一位是1, 其它位是0, //而正是这样的特性, 使得任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况. //什么意思? 举个例子: //1+2+4 二进制表示是 1+10+100 //1+2+3 二进制表示是 1+10+11 <-- 这样会使右边第一位,第二位出现进位 //再来看个例子 echo decbin(1+2)."<br>"; // 11 echo decbin(1+2+4)."<br>"; // 111 echo decbin(4+8)."<br>"; // 1100 echo decbin(1+4+16)."<br>"; // 10101 //结合"任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况"的特性, 很容易分析出上面例子中的规律: //结果值的二进制数值中如果右边第一位是1, 那么结果值的十进制数值一定是 1+*** //结果值的二进制数值中如果右边第二位是1, 那么结果值的十进制数值一定是 2+*** //结果值的二进制数值中如果右边第一位是1,右边第二位也是1, 那么结果值的十进制数值一定是 1+2+*** //我们回到用户勾选爱好复选框保存到数据库中的值 21 (十进制) //通俗点, 我们可以这样理解: //2的N(N>=0)次方数字的和(例如21) 的二进制表示(10101), 从右至左如果第n位为1, 那它十进制一定是 2 的 n-1 次方与其它2的N(N>=0)次方数字的和 //所以 21(二进制表示为 10101) 应该是 (2的(1-1)次方)+(2的(3-1)次方)+(2的(5-1)次方) = 1+4+16 //同样根据"任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况"的特性, 结合我们已知的 & 运算, 我们能很方便的判断 任意2的N(N>=0)次方数字相加的和中是否存在一个确定的2的N(N>=0)次方数字 echo (21 & 1)."<br>"; // 1 echo (21 & 2)."<br>"; // 0 echo (21 & 4)."<br>"; // 4 echo (21 & 8)."<br>"; // 0 echo (21 & 16)."<br>"; // 16 echo (21 & 32)."<br>"; // 0 echo (21 & 64)."<br>"; // 0 ?>
我们来看看页面前端 javascript 是怎么保存和还原用户勾选的选项的:
在线实例
<input type="button" value="要保存到数据库中的值" onclick="get_save_value('hobby[]')">
<input type="button" value="清除勾选" onclick="clear_all('hobby[]')"> <br>
<br>还原勾选框<br>
<input type="text" name="set_check_value" id="set_check_value"><br>
<input type="button" value='先点击 "清除勾选" 再点我' onclick="set_check('hobby[]', document.getElementById('set_check_value').value)"> <br>
<script language="JavaScript">
/* 重点 */
//还原用户的选取项
function set_check(name, value){
var obj = document.getElementsByName(name);
for(var i=0; i<obj.length; i++){
if( (obj[i].value & value) == obj[i].value ){
obj[i].checked = true;
}
}
}
/* 这不是重点 */
function get_save_value(name){
var obj = document.getElementsByName(name);
var saveValue = 0;
for (var i=0; i<obj.length; i++){
if (obj[i].checked){
saveValue += parseInt(obj[i].value);
}
}
document.getElementById("set_check_value").value = saveValue;
alert(saveValue); //这个就是要存到数据表里的值
}
function clear_all(name){
var obj = document.getElementsByName(name);
for (var i=0; i<obj.length; i++){
obj[i].checked = false;
}
}
</script>
我们来看看后端数据库是查询用户勾选项的:
假设我们 tableName 中的 hobby 字段是保存用户的兴趣爱好值
一个用户一第记录, 如果前面的例子成功记录到数据库中, 那么 tableName 中应该有一条 hobby==21 的值的记录.
--要查询选择了"爱好1"或者"爱好3"的用户: --爱好1(value=1) --爱好3(value=4) SQL: SELECT * FROM tableName WHERE (hobby&1) OR (hobby&4); --要查询选择了"爱好1"并且"爱好3"的用户: --爱好1(value=1) --爱好3(value=4) SQL: SELECT * FROM tableName WHERE (hobby&1) AND (hobby&4); --要查询只选择了"爱好1"和"爱好3"的用户: --爱好1(value=1) --爱好3(value=4) SQL: SELECT * FROM tableName WHERE hobby=(1+4)
常用的 jQuery 插件
自己整理的一些常用的 jQuery 的插件:
http://www.malsup.com/jquery/ [对话框插件/推荐]
http://dev.iceburg.net/jquery/jqModal/ [对话框插件]
http://www.kelvinluck.com/assets/jquery/datePicker/v2/demo/ [日历插件]
http://jquery.bassistance.de/validate/demo/ [表单验证]
http://jquery.com/demo/thickbox/ [图片层/对话框]
http://demos.flesler.com/jquery/scrollTo/ [锚点特效]
http://15daysofjquery.com/examples/jqueryEditInPlace/demo.php [div编辑]
http://www.davehauenstein.com/code/jquery-edit-in-place/example/ [div编辑&保存]
http://www.appelsiini.net/projects/jeditable/default.html [div编辑&保存]
http://www.jdempster.com/category/jquery/disableTextSelect/ [禁止鼠标选取]
http://www.phpletter.com/contents/ajaximageeditor/ajax_image_editor.php [图片放大缩小/加图解]
http://www.phpletter.com/Demo/Jquery-Floating-Box-Plugin/ [页面四角浮停DIV]
http://www.visual-blast.com/javascript/jcrop-jquery-image-crop-plugin/ [图片裁切]
http://stanlemon.net/projects/jgrowl.html [类似 163 BLOG右上角提示信息插件]
http://jquery.lukelutman.com/plugins/flash/ [Flash IE7 无虚框插件]