JavaScript中要对小数取整的话(单纯舍弃小数部分,不涉及四舍五入),有原生函数parseInt()。不过除此之外还有两种“歪门邪道”的写法,这三种写法合起来比较一下:
parseInt(10/3) // 返回 3 ~~(10/3) // 返回 3 10/3|0 // 返回 3
其实第二种的波浪号和第三种的竖线都是“位操作符”。
注意:
第二种写法是两个波浪线哦。一个波浪线是达不到取整效果的。
第三种写法的竖线和0是一个整体哦,不然也是达不到取整效果的。

前两天做的项目中使用了SuperSlide,做了个焦点图切换效果和图片向左滚动展示的效果。使用时参照官方demo做了些细微改动,现在我再把代码单独存一份,方便以后使用。
1.焦点图切换(通屏):
2.图片向左滚动:
一直以来,JavaScript对于鼠标事件和触摸事件提供的支持都比较初级,此问题在pc端不是很明显,但是移动端的触摸手势就比较多样化了,为此我们有必要使用js库来帮助我们处理触摸事件。
Hammer.JS是一款轻量级的移动设备触摸手势库,不依赖其他js库,兼容性好(支持WP),支持常见的点击、拖动、缩放、旋转等触摸事件,也可支持多点触控。
Hammer.JS支持的六大事件:

Hammer.JS支持在pc端浏览器上用鼠标模拟触摸事件,这样我们开发时可以在pc上进行测试,极大提高了开发效率(看它官网的描述,似乎是可以在pc上模拟出全部的6种动作。不过缩放和旋转我试不出来,按下shift模拟双指操作也没反应①)。
下面是一个左右滑动的示例:
var myElement =document.querySelector("#a");
var mc = new Hammer(myElement);
mc.on("swipeleft swiperight", function(ev) {
if (ev.deltaTime>100) { // 判断一下延迟时间,小于100ms的不处理
if (ev.deltaX>0) { //向右滑动,展示左侧内容
// code
}else if (ev.deltaX<0) { //向左滑动,展示右侧内容
// code
}
}
console.log(ev);
});
hammer.js用起来还真是费了不少劲。
首先是它有好几个可以下载的地方,但不同的地方不但有的版本号不同,有些甚至完全不生效。我现在用的是https://hammerjs.github.io/dist/hammer.min.js。也可能是其他版本改了api?
第二是注意禁用浏览器自己的选择事件和拖动事件。
举个例子,网页中的图片是可以被拖动的。当你按下鼠标并移动来模拟滑动事件时,会发现图片变成了拖拽状态,这时候就触发不了hammer.js上绑定的事件了,所以要用css禁止拖动该元素。
拖动文字可能导致文字被选中,所以也要禁止选中该元素。
一开始我没发现这个事情,当我把可以正常使用的demo的代码移植到我的项目里之后,发现不生效,这让我郁闷了好久,最后琢磨出来是这个原因。
hammer.js会给直接绑定的元素自动增加禁止拖动和选择的属性,但如果该元素有子元素,则需要我们视情况对该处理的子元素进行处理。
hammer.js的使用说明也较少,所以有时候我们要输出ev来自己查看当前事件的一些属性。
参考资料1
移动端手势库hammerJS 2.0.4官方文档翻译
① 有资料说,pinch 和rotate 默认情况下是禁用的,因为他们会使元件闭锁(这里貌似是机翻),如有需要可以通过下面的方法调用:
hammertime.get('pinch').set({ enable: true });
hammertime.get('rotate').set({ enable: true });
不过我还没用到这个,没去试验。

WordPress设置网站副标题需要到后台的设置项里设置,操作起来太繁琐,于是我用php做了个设置网站副标题的接口。这个没什么技术含量,主要是熟悉下php对mysql数据库的基本操作流程。
首先是到数据库里找到网站副标题的字段:

找到之后写出用于修改它的sql语句,如下:
UPDATE wp_options SET option_value = '大好き' WHERE option_name = 'blogdescription'
接下来做一个html文件和一个php文件,用html文件给php文件发送要设置的副标题,php接到请求后执行数据库操作。
功能做好之后,把html传到网站上,并保存成书签。以后想修改修改副标题只要打开这个书签,输入文字就可以了。
Read More →
JavaScript原生的document.querySelector和document.querySelectorAll方法很好用,不过依旧摆脱不了原生方法名太长的麻烦。所以我们可以封装下,如:
function $(selector) {
return document.querySelector(selector)
}
function $$(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector))
}
这里用了$、$$作为方法名,分别对document.querySelector方法和document.querySelectorAll方法进行封装。
$方法返回单个元素(第一个符合的元素),$$以数组形式返回所有符合的元素(即使符合的元素只有一个)。
这样我们就可以方便的使用封装的方法来选择DOM元素了:
$("#div .class img")
$$("#div .class img")
不过如果$、$$的定义冲突了可能会出问题,所以如果页面上引用jQuery了的话,可以换个方法名。
ps:至于为什么方法名要用$和$$呢,并不是模仿jQuery,而是模仿chrome(至于chrome是不是模仿jQuery的方法名那我就不清楚了)。
chrome浏览器控制台里内置了封装好的$、$$方法,可以直接使用。(当然,如果$、$$的定义被页面上的代码覆盖了就不行了)
如图:


更新:两年过去了,现在推荐使用 vw + rem 自适应布局。
我们页面布局中,可以通过动态设置rem并使用rem单位来设置宽高,来使得页面元素的尺寸可以随设备宽度而变化,这样就能保持布局的一致性。
使用JavaScript动态设置rem的代码如下:
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = 100 * (clientWidth / 640) + 'px';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
公式是这样的:
100 * ( 浏览器页面宽度 / 设计稿宽度 )
第一部分:100是什么
这个100其实是我们使用的rem基础值,等于设置html标签的font-size=100px,这样,1rem也就是100px。
当1rem为100px时,页面上所有元素设置宽高大小时都除以100,就得出了该元素的rem值。比如设计稿上300px宽的元素,用rem设置就是width=3rem。
1rem并不是非要设置为100px,我们也可以设置成别的,比如设置1rem=50px,那么300px的元素是6rem。我们一般取1rem=100px是为了方便计算。如果实际项目中计算页面元素的rem值时不是按1rem=100px来算的,则需要修改公式里的100为实际使用的1rem值。
第二部分:浏览器页面宽度 / 设计稿宽度 是什么
这个可以理解为页面在设备上的缩放比例。比如iphone 6 plus的设备宽度是414px,我们的设计稿是640px。
414/640=0.646875,得出我们的页面在iphone 6 plus上应该显示为设计稿大小的0.646875倍。
最后我们把rem的基础值与页面缩放比例相乘,得出实际使用的rem基础值。rem的基础值变了,页面上所有元素的宽高、大小也会随之改变,这样就达到了页面自适应的效果。
Read More →
以往我们插入、移动DOM元素经常是使用appendChild和insertBefore方法。
appendChild:在父级元素内追加新元素。 insertBefore:在父级元素内的某个元素之前插入新元素。
但是这两个方法的参数只能接收元素对象,不能使用字符形式的html代码,而且它们插入元素的位置也不够灵活。我们可以使用insertAdjacentHTML方法来更方便的插入元素。
insertAdjacentHTML可以将字符串形式的html代码(需要能解析为DOM元素)解析为一个节点,并将其追加到指定元素的指定位置。
insertAdjacentHTML方法的语法如下:
element.insertAdjacentHTML(position, text);
position参数有以下四个值(都是字符串形式):
beforebegin:在元素的开始位置之前插入。 beforeend:在元素的结束位置之前插入。 afterbegin:在元素的开始位置之后插入。 afterend:在元素的结束位置之后插入。
text参数则是字符串形式的html代码。
根据position参数,我们可以将新元素插入到到指定元素的四个位置:

示例:
<div id="a">
<div></div>
</div>
<script type="text/javascript" defer>
var a=document.querySelector("#a");
a.insertAdjacentHTML("afterbegin","<a href='' >xxx</a");
</script>
结果如下:
<div id="a"> <a href="">xxx</a> <div></div> </div>
insertAdjacentHTML方法的兼容性表现良好,主流浏览器均已支持。我们也可以如下语句来检查浏览器是否支持方法:
document.documentElement.insertAdjacentHTML
此外,由于insertAdjacentHTML是根据位置插入元素的,因此它不能把新元素插入到img、input等单标签元素里(想这么做的人才是有毛病吧)。
相关文档:《https://developer.mozilla.org/zh-CN/docs/Web/API/Element/insertAdjacentHTML》
ps:与insertAdjacentHTML系列“同一系列”的还有insertAdjacentElement方法和insertAdjacentText方法。
insertAdjacentElement方法除了第二个参数是DOM节点(不能是字符串形式)外和insertAdjacentHTML方法都一样。
insertAdjacentText方法则只接收字符串格式的参数,并输出为字符串。其他地方也和insertAdjacentHTML方法一样。
今天fgo开了圣诞活动,bilibili上的活动页面上下着雪,于是我把代码扒了下来。
这个下雪的js依赖jquery,实际使用中感觉效果一般←_←
<body style="background: #000;">
<canvas class="snow-canvas" speed="1" interaction="true" size="8" count="40" start-color="rgba(253,252,251,1)" end-color="rgba(251,252,253,0.3)" opacity="0.00001" wind-power="2" image="false"></canvas>
<script src="//apps.bdimg.com/libs/jquery/1.9.0/jquery.js"></script>
<script src="//static.biligame.net/fgo/event_santa/pc/js/snow.js?v=d659f803.js"></script>
<script>
$(".snow-canvas").snow();
</script>
<style>
.snow-canvas { position: fixed; display: block; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; }
</style>
</body>
demo如下:
效果不是很好……不过如果像活动页面那样,有背景图片什么的,瑕疵应该不会很明显。

刚才在懒人之家找了一个JavaScript做的全国省市县三级联动的下拉选择插件,记录一下。
这个js文件的日期是2014年,使用方法如下:
<select id="s_province" name="s_province"></select> <select id="s_city" name="s_city" ></select> <select id="s_county" name="s_county"></select> <script src="form/area.js" type="text/javascript"></script> <script type="text/javascript">_init_area();</script>
本文要做的事情是,用户通过file控件选择一个文件,之后我们使用FileReader将其转换为base64编码,并储存在LocalStorage里。
如下代码,在用户选择一张图片时,程序会将图片以base64编码保存到LocalStorage里,然后把这张图作为网页的背景图片。
<input type="file" name="img">
<br>
<input type="button" name="clearMyBG" value="清除我的设置">
<script>
// 尝试读取localStorage中存储的背景图片,如果有就设置
var myBGStorage = localStorage.getItem("myBG");
if (myBGStorage) {
document.body.style.backgroundImage="url("+myBGStorage+")";
}
// 将选择的文件储存在localStorage里
document.querySelector("input[name=img]").addEventListener("change",function(){
if (!/image\/\w/.test(this.files[0].type)) {
alert("请确保文件为图像类型");
return false;
}
setMyBG(this.files[0]);
})
//清除存储的背景图片
document.querySelector("input[name=clearMyBG]").addEventListener("click",function(){
localStorage.removeItem("myBG");
alert("设置已清除");
location.reload();
})
//转换、存储和设置背景图片
function setMyBG (imgfile){
var fileReader = new FileReader();
fileReader.readAsDataURL(imgfile);
fileReader.onload=function(){
var result = this.result;
document.body.style.backgroundImage="url("+result+")";
try {
localStorage.setItem("myBG", result);
}catch (e) {
console.log("Storage failed: " + e);
}
}
}
</script>
如下图,是localStorage中存储的键值对。注意localStorage的值都会被转换成string类型的。

相关资料:
FileReader localStorage
有一个检测localStorage容量上限的工具:
Test of localStorage
它会在你的localStorage里存储数据,直到塞满为止。chrome约为5M。据说opera和firefox可以自己调整限制,厉害了。
Read More →