最近有个功能需要判断字数。PHP 中有很多函数可以计算字符串的长度,如strlen,mb_strlen,mb_strwidth。测试如下:
echo strlen("你好ABC") . ""; # 输出 9 echo mb_strlen("你好ABC", 'UTF-8') . ""; # 输出 5 echo mb_strwidth("你好ABC") . ""; #输出 7
可以看出,strlen 把中文字符算成3个字节;mb_strlen 不管中文还是英文,都算1个字节;而 mb_strwidth 则把中文算成2个字节。
我需要的是字数而不是字节数,所以mb_strlen是我想要的。但是要注意,“把汉字算做1个长度”必须指定为utf-8编码,否则它也会把汉字算做3个字节。
另外,截取字符串时,也可以用mb_substr指定utf-8编码,将汉字算做一个长度。如:
echo mb_substr('这样一来我的字符串就不会有乱码^_^', 0, 7, 'utf-8');
这个输出需要页面环境有编码才不会乱码。例如将此结果输出到html中,输出的字符会使用html页面的编码。如果单独写这一行php输出,还会是乱码。
php中如何判断字数
select控件就是下拉选择框,之前我没怎么试过对它进行js操作。今天看到有个add方法,可以向select控件里添加选项(option),记录一下。
var selectE=document.createElement("select"); selectE.id="selectE"; document.body.appendChild(selectE); var optionE=document.createElement("option"); optionE.text="optionE"; selectE.add(optionE);
上例演示了创建一个select控件并像其中添加了一个选项。在需要使用JavaScript创建控件时很有用。
add语法:
selectObject.add(option,before)
option就是option元素,before是个数字,指示新选项插入在第几个选项之前。
向表单的select控件中添加选项
<img src="/f/head15.jpg" id="stwRight"> <img src="/f/saber%E8%A1%A8%E6%83%85_1_1.jpg" id="stwCenter"> <img src="/f/x.png" id="swtClose"> <style type="text/css"> #LRdiv0,#LRdiv1{display:none !important;} #stwRight{position: fixed;right: 0;top: 60px;display: none;z-index: 999;cursor: pointer;} #stwCenter{position: fixed;display: none;width: 400px;height: 350px;left: 50%;margin-left: -200px;top: 50%;margin-top: -175px;z-index: 999;cursor: pointer;} #swtClose{position: fixed;display: none;width: 24px;height: 24px;left: 50%;margin-left: 175px;top: 50%;margin-top: -175px;z-index: 9999;cursor: pointer;} </style> <script type="text/javascript"> window.onload=function(){ function showSwtC(){ document.getElementById("stwCenter").style.display="block"; document.getElementById("swtClose").style.display="block"; } function showSwtR(){ document.getElementById("stwRight").style.display="block"; } function hideSwtC(){ document.getElementById("stwCenter").style.display="none"; document.getElementById("swtClose").style.display="none"; } function hideSwtR(){ document.getElementById("stwRight").style.display="none"; } function openSwt(){ LR_HideInvite();openZoosUrl();return false; } showSwtR(); setTimeout(function(){ hideSwtR(); showSwtC(); },4000); document.getElementById("stwRight").onclick=function(){ openSwt(); } document.getElementById("stwCenter").onclick=function(){ hideSwtC(); showSwtR(); openSwt(); setTimeout(function(){ hideSwtR(); showSwtC(); },8000); } document.getElementById("swtClose").onclick=function(){ hideSwtC(); showSwtR(); setTimeout(function(){ hideSwtR(); showSwtC(); },8000); } } </script>
侧边浮窗没做关闭按钮。
因为openSwt()里用了商务通自带的函数openZoosUrl(),所以页面上还是得加载商务通代码。如果把openSwt()改成直接用网址跳转,则不用加载商务通代码。
上面商务通不仅样式是我们自己做的,显示、隐藏的逻辑也需要自己定义。实际上对于有商务通代码的页面,我们可以直接利用商务通自身的函数来“偷梁换柱”,打开我们自己的商务通图片。
var sTimer = setInterval(function(){ if(typeof LR_showInviteDiv != "undefined"){ window.LR_showInviteDiv = function(){ //此处改写了商务通显示邀请框的函数 showSwt(); } clearInterval(sTimer); } },100);
LR_showInviteDiv是显示邀请框的函数,如果页面上有这个函数,则改写它,让它执行showSwt,也就是我们自己定义的一个函数,显示自己的邀请框。
恩……我对这这个代码研究了好久,发现这个办法并没有多方便,浪费时间。唯一的优点是不用写css来隐藏商务通的邀请框了。另外改写商务通的这个函数会导致商务通客户端发送邀请失败。麻烦。
简单的仿一下商务通效果
平时我们表单的提交多数是用action来指定提交到的文件,但这样会产生页面的刷新。用ajax提交可以避免刷新,但是需要我们自己组织要提交的数据。这就是表单序列化了。
jQuery有个serialize方法来做表单序列化,语法如下:
$(selector).serialize();
序列化之后,表单里需要提交的值会被组织成字符串,形如:
"name=124&company=baidu.com&fav=1,2,3"
如果里面有汉字之类,会自动进行url编码。表单序列化完全模拟了浏览器提交时的数据,这样我们就可以用ajax来提交表单了。
如一个id为“yy”的表单,它的提交的地址是"/plus/diy.php",提交按钮id是submit。那么表单序列化并提交的代码如下:
$("#submit").click(function(event) { event.preventDefault(); $.ajax({ type: "post", url: "/plus/diy.php", data: $("#yy").serialize(), success: function() { alert("信息提交成功。"); } }) })
注意用preventDefault()阻止浏览器默认事件(就是跳转到action页面,即使你没写action属性也会跳转的)。
后台对提交数据的处理和用action提交时的数据是一致的。
Read More →
JavaScript表单序列化
在表单里添加input的预设值是常见的做法。当用户点击输入框之后,预设值消失,同时文字颜色也要加深,变成正常的颜色。如果用户清空了输入的内容,则恢复默认值。
以前我做这个效果用的代码比较繁琐,现在有更简单的方法。下面的js代码直接写在input标签里就可以了。
onfocus="if(this.value==this.defaultValue){this.value='';this.style.color='#333'};" onblur="if(this.value==''){this.value=this.defaultValue;this.style.color='#aaa'}"
这里面有个defaultValue,这个属性是浏览器自动保存的,我们可以直接拿来用。以前我都是把默认值用js保存到一个变量里的,那样就麻烦了。
input输入时对值和颜色的处理
左:Safari上的按钮表现
右:pc和安卓上的按钮表现
我们在网站上做表单的时候,经常会给按钮自定义一些样式来美化它。例如我们把按钮做成了上图右侧的样式,在pc上和安卓的浏览器上看都很ok。
但是在睾贵的iphone上的睾贵的Safari浏览器上,按钮是有浏览器内置的默认样式的。Safari的内置样式会对我们自己做的按钮进行修改:
1.按钮的高度会改变
2.按钮有了大圆角
3.背景会在我们设置的背景色的基础上添加渐变效果。
解决办法是在css里将按钮元素的-webkit-appearance属性的值设置为none,这样可以取消浏览器对按钮应用内置样式。
input[type="button"],input[type="submit"],input[type="reset"] {-webkit-appearance: none;}
其实这个还不是最糟心的。前天发现某手机站上有些文字在Safari上特别的大,主要出现在文字太多一行放不下的情况。浏览器都会自动把文字换行,但是Safari上自动换行之后这行文字字号变得特别的大。这问题又是只在睾贵的Safari上出现。虽然这可能和网页本身有关系,但我一直没弄明白原因,百度谷歌搜来搜去,也没找到可以解决这个问题的办法。加班整了两小时,毫无进展。最后只能针对iphone特别设置一些样式,从表面上解决了问题。
解决iphone上的Safari会把表单按钮变成默认样式的办法
刚才看《JavaScript高级程序设计》,读到input控件的部分,看到了html5中对input增加了一些新的功能,试验了一番,这些实在让人excited!下面发点测试图。
1.新的type类型。
input有些type我们是很熟悉的,例如text、password等。html5中增加了一些新的type类型,而且这些type类型基本都可以承担一部分表单验证的工作,很实用。这些新的type有:
"email"、"url"、"number"、"range"、"datetime"、"datetime-local"、"date"、"month"、"week"、"time"。
举一些例子:
email类型,必须要有@符号:
url类型,必须要有协议:
number类型,只能输入数字:
date类型,只能输入日期:
range类型,会出现一个滑块以调节:
需要注意的是,浏览器(如果支持的话)会对这些控件的值进行检查。有些类型是在输入的时候进行检查,有些则是在提交表单时进行检查。所以,如果input没写在form里,有些类型可能起不到限制作用。
2.新的属性。
如required属性,当表单提交时,这个控件的内容不能为空。
对于数值类型的控件,还可以设置最小值、最大值、增量值等,如:
<input type="number" min="60" max="100" step="5">
3.新的方法。
主要是stepUp()和stepDown()方法。这两个方法分别使input控件的值增加或减少。不带参数默认为1,也可以带参数。如对range的调节:
html5中input的一些新特性
// ==UserScript== // @name 网站地图生成助手(Clearision主题专用) // @namespace https://saber.love // @version 0.1 // @description 自动生成当前网页的sitemap信息(文章页) // @author saber // @match https://saber.love/*.html // @grant none // ==/UserScript== var sitemap_url = window.location.href; //url var sitemap_pri = "0.5"; //权重 var changefreq = "Always"; //更新频率 var sitemap_year = new Date(); //年份 sitemap_year = sitemap_year.getFullYear(); // 因为主题生成的网页里没有包含年份,所以取当前年份 var sitemap_time_info = document.getElementsByClassName("post_time")[0].innerText.replace(/\n/g, "").replace(/\t/g, "").replace("/", "-").replace(" ", ""); var sitemap_date, sitemap_time; //时间和日期 if (sitemap_time_info.length === 9) { sitemap_date = sitemap_time_info.substring(0, 4).replace("-", "-0"); //天数在10号以下时前面没有0,所以需要补上0 sitemap_time = sitemap_time_info.substring(4, 9); } else if (sitemap_time_info.length === 10) { sitemap_date = sitemap_time_info.substring(0, 5); sitemap_time = sitemap_time_info.substring(5, 10); } window.stop(); //停止页面加载,可以节省图片流量 var this_sitemap_result = ("<url>" + "\r\n" + "<loc>" + sitemap_url + "</loc>" + "\r\n" + "<priority>" + sitemap_pri + "</priority>" + "\r\n" + ("<lastmod>" + sitemap_year + "-" + sitemap_date + "T" + sitemap_time + ":00+00:00</lastmod>") + "\r\n" + "<changefreq>" + changefreq + "</changefreq>" + "\r\n" + "</url>" + "\r\n"); //拼接出本页面的sitemap信息 localStorage.setItem("mymap", localStorage.getItem("mymap") + this_sitemap_result); //把本次的结果追加存储 var next_page = document.querySelector("#p_n_r a"); if (!!next_page) { //如果有下一页就自动打开下一页 next_page.click(); } else { //如果没有下一页就弹出结果 document.write("<xmp>" + localStorage.getItem("mymap") + "</xmp>"); alert("sitemap信息生成完毕"); localStorage.setItem("mymap", ""); //清空结果 }
本文代码是针对我这个网站写的,如果其他网站想要使用,可以对照自己网站进行修改。
使用方法:
在油猴里新建一个脚本,把下面的代码粘贴进去保存即可。之后打开或刷新本站任意一个网页,代码就会从这个页面一直抓取到最新的一篇文章,自动生成sitemap信息并存储到localStorage里。抓取完成后弹窗提醒,并把抓取结果输出到页面上。这样我们只需要等结果出来,最后复制结果就行了。
注意:
由于文章信息里没有包含年份,所以年份去的是当年。如果如在当年去获取之前的文章,那么年份就是错的。比如2018年1月去获取2017年12月的,结果会显示2018年12月。这个可以在获取后批量替换下。
使用之后记得关掉这个油猴脚本,以免影响正常浏览。
网站地图生成助手js版
<div id="demo"> <div class="scrollbox"> <div id="demo1"> <a href="">雪见雪见雪见雪见雪见雪见</a> <a href="">sabersabersabersaber</a> </div> <div id="demo2"></div> </div> </div> <style type="text/css"> #demo{width: 300px;overflow:hidden;} /*最外层box的宽度可以随意设置,但必须小于里面demo(如demo1)的宽度,否则滚动完一次会停止*/ #demo .scrollbox{width:1000%;}/*设置一个较大的范围,保证其宽度大于内部两个div宽度之和(如果宽度不够两个div就会错开)*/ #demo1,#demo2{display: inline-block;}/*浮动或设置display以保持在同一行*/ </style> <script type="text/javascript"> var demo = document.getElementById("demo"); var demo1 = document.getElementById("demo1"); var demo2 = document.getElementById("demo2"); demo2.innerHTML=document.getElementById("demo1").innerHTML; function Marquee(){ if(demo.scrollLeft-demo2.offsetWidth>=0){ demo.scrollLeft-=demo1.offsetWidth; } else{ demo.scrollLeft++; } } var myvar=setInterval(Marquee,30); demo.onmouseout=function (){myvar=setInterval(Marquee,30);} demo.onmouseover=function(){clearInterval(myvar);} </script>
我解释下dom结构:
id#demo是最外层,设置滚动区域的宽高。此代码中它的宽度需要比滚动内容的宽度小。
class.scrollbox是容纳两个滚动容器的,它的宽度需要设置得比较宽,以保证能容纳两个滚动内容。
id#demo1和#demo2就是滚动内容了,通过设置浮动或display让他们保持在同一行,循环滚动。
示例中给出的css样式都是基础的必须样式,如果需要其他样式请自行添加。