Saber 酱的抱枕

Fly me to the moon

09/5
2015
学习

修改表单中file控件的外观

表单中的file上传控件在各个浏览器中的外观都不太一样,所以我们可以自己做一个外观。原理是隐藏file控件,然后自己做出文件名的显示区域,以及选择按钮。

<form id="form0">
	<input type="file" id="fileinput1">
	<span id="showfile">尚未选择文件</span>
	<span title="选择文件" id="selectbtn1">选择文件</span>
	<span class="tip">图片必须为jpg格式,体积小于2M,文件名不能包含“sox”三个字</span>
</form>
<style>
	#fileinput1{display: none;}
	#form0 span{border-radius: 5px;font-family: '微软雅黑';display: inline-block;}
	#showfile{width: 300px;height: 34px;line-height: 34px;color: #aaa;padding:0 5px 0 10px;border:1px solid #0c0;white-space:nowrap;  text-overflow:ellipsis;overflow: hidden;vertical-align:top;}
	#selectbtn1{width: 100px;height: 36px;line-height: 36px;background:#4DB849;color: #fff;text-align: center;cursor: pointer;vertical-align:top;}
	.tip{margin-left: 5px;color: #aaa;height: 36px;line-height: 44px;}
</style>
<script>
	document.getElementById("selectbtn1").onclick=function  () {
		document.getElementById("fileinput1").click();
	}
	document.getElementById("fileinput1").onchange=function(){
		if (this.files[0].type!="image/jpeg") {
			alert("文件格式不正确!");
			return false;
		}else if(this.files[0].size>2000000){
			alert("文件体积过大!");
			return false;
		}else if (this.files[0].name.toLowerCase().indexOf("sox")>-1) {
			alert("文件名包含非法字符!");
			return false;
		};
		document.getElementById("showfile").innerHTML=this.files[0].name;//这里没有用value,因为获取不到真实的绝对路径的,不如只显示文件名
		document.getElementById("showfile").style.color="#333";
	}
</script>

点击选择文件按钮的时候用js去触发file控件;在选取文件之后,将文件信息显示到文件名区域里。

你可能会注意到files[]这个集合:

this.files[0]

这是html5中为file控件增加的属性,通用的有name、size、type、lastModified这几个属性。这些属性可以用来对上传的文件做一些检测。

注意,size的单位是Byte(字节)。

修改表单中file控件的外观

09/2
2015
学习

对js随机数的实验

var result=[0,0,0,0,0,0,0,0,0,0];
for (var i = 0; i < 1000000; i++) { var num=Math.floor(Math.random()*10); switch(num){ case 0: result[0]+=1; break; case 1: result[1]+=1; break; case 2: result[2]+=1; break; case 3: result[3]+=1; break; case 4: result[4]+=1; break; case 5: result[5]+=1; break; case 6: result[6]+=1; break; case 7: result[7]+=1; break; case 8: result[8]+=1; break; case 9: result[9]+=1; break; } }; var resultstring=""; for (var i = 0; i < result.length; i++) { resultstring+=i+"-"+(i+1)+"有"+result[i]+"次"+"\n"; }; alert(resultstring);[/code] 10亿次测试的一次结果:

我不得不承认这是闲的蛋疼。做这个东西的起因还是在本站。本站设置了十来张背景图,但有时候刷新几次都只反复出现某几张图。于是我做了上面的测试功能,来验证一下(虽然早知道注定失败)。后来我测试过随机10亿次,但即便测试基数这么高,最高和最低的结果之间也最少相差两万左右。上图可能较为极端,差别是39420。看来在随机里面追求公平真是脑子有病。

对js随机数的实验

08/30
2015
学习

使用js的new Image()来预加载图片

当我第一次看到new Image()的时候,我很好骑。查了查资料,发现可以用new Image()来做图片的预加载。简单的示例:

var img1=new Image();
img1.src="/f/%E7%A9%B9%E5%A6%B9%E7%BE%8E%E5%9B%BE.jpg";
img1.onload=function  () {
	document.body.appendChild(img1);
}

这个图片加载完毕之后,追加到body里,就不会再有加载过程了(废话
Read More →

使用js的new Image()来预加载图片

08/28
2015
学习

js的条件操作符(三元运算符)

在js中,假设有两个数值,我们要选出一个大的存入某个变量中。一般我们是用if写的:

var num1=3;
var num2=5;
var num;

if (num1>num2) {
	num=num1;
}else{
	num=num2;
};

今天看到一个教程上说到了“条件操作符”(三元运算符),可以代替上例中的if部分。试了下果然好使:

num=(num1>num2)?num1:num2;

语法:

variable = boolean_expression ? true_value : false_value;

感觉不能用在if里面有复杂操作的场景,用来赋值倒是极好的。

容我吐槽一下,现在这个代码高亮插件的着色效果太差了,上面两条让我以为我选的是text模式呢。

与之相关的还有||运算符,除了在条件判断中使用,它也可以在赋值的时候使用:

var a=document.documentElement.scrollTop|| document.body.scrollTop;

判断为真的值才会保存到变量里,这个例子是用来解决兼容性问题的。

js的条件操作符(三元运算符)

08/27
2015
学习

使用js来判断浏览器

function getOs() 
{ 
    var OsObject = ""; 
   if(navigator.userAgent.indexOf("MSIE")>0||navigator.userAgent.indexOf("Trident")>0) { 
        return "MSIE"; 
   } 
   else if(isFirefox=navigator.userAgent.indexOf("Firefox")>0){ 
        return "Firefox"; 
   } 
   else if(isMozilla=navigator.userAgent.indexOf("Opera")>0){ //这个也被判断为chrome
        return "Opera"; 
   } 
   else if(isFirefox=navigator.userAgent.indexOf("Chrome")>0){ 
        return "Chrome"; 
   } 
   else if(isSafari=navigator.userAgent.indexOf("Safari")>0) { 
        return "Safari"; 
   }  
   else if(isCamino=navigator.userAgent.indexOf("Camino")>0){ 
        return "Camino"; 
   } 
   else if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){ 
        return "Gecko"; 
   }
    
} 
 alert("您的浏览器类型为:"+getOs());

这是使用js判断浏览器的代码,查找IE11的Trident字符是我填上去的,不然IE11就undefined的。恩,其他版本IE还不清楚状况如何。

ps:有的浏览器的UA是符合复数的条件的,比如pc上chrome的UA里就有"Safari"字符。不过好在代码里在"Safari"之前先判断了chrome,这样就不会错把chrome当做safari了。
所以实际使用中不要单独摘出一条就去用,否则可能会出错。

使用js来判断浏览器

08/26
2015
学习

使用CSS滤镜做模糊效果

今天在张鑫旭的网站看到了使用css的blur滤镜做模糊效果的例子:

.blur {    
    -webkit-filter: blur(10px); /* Chrome, Opera */
       -moz-filter: blur(10px);
        -ms-filter: blur(10px);    
            filter: blur(10px);    
}

拿来测试了下,单靠这个的话,IE的一些版本会悲剧。不过可以尝试其他方法来弥补。

查看原文


使用CSS滤镜做模糊效果

08/24
2015
学习

网页使用固定宽度布局,适应不同宽度的手机屏幕

今天完成了一个手机站专题的排版,然后到手机上测试缩放的时候出了问题,折腾半个上午,摸索出一些心得(后来发现,这就是固定宽度布局嘛)。

1.排版的时候用px排,在css里把body宽度固定,可以定成和设计稿一样,例如360px,640px。其他元素也都用px。

2.使用js动态设置viewport:

var scale=document.documentElement.clientWidth/640;
// var scale=window.screen.width/640;
var metaEl = document.createElement('meta');
document.querySelector("head").appendChild(metaEl);
metaEl.setAttribute('name','viewport');
metaEl.setAttribute('content', 'width=device-width ,initial-scale=' + scale + ',maximum-scale=1.0, minimum-scale=0 ,user-scalable=no');

这里面的640改成自己给body定的的宽度。这个代码的意思就是把initial-scale倍数设置为浏览器device-width/网页固定的宽度,使得页面被缩放到适应屏幕宽度。

ps:本文最近做过更新,第二步动态设置viewport,虽然理论上是正确的,但我还没实践过。我现在尝试用rem布局。

网页使用固定宽度布局,适应不同宽度的手机屏幕

08/22
2015
学习

jq中获取checkbox的checked值

$("#box").change(function  () {
		//此时获取的已经是change后的值了
		if($(this).prop("checked")){//如果全选按钮已经被选中
			$(".sub").prop("checked",this.checked); 
		}else{//如果全选按钮未被选中
			$(".sub").prop("checked",false); 
		}
});

#box是全选按钮(它也是个复选框),.sub是底下各个条目的复选框。用的是jq的.prop()方法。

刚才同学做全选功能,出了问题,来问我。我拿到代码试了试,点击全选按钮,然后获取并判断它的checked值,结果没反应。

然后去调试,发现发现获取到的复选框(checkbox)的checked值始终是undefined,选中了也不变。这还怎么做?

难道要把复选框放到form标签里才行?或者是需要手动加上checked这个属性?都试了试,完全没用

想想两年前还在学校的时候,就做过全选和反选这样的功能,怎么现在就做不出来了呢?这个郁闷啊

于是去百度“jq怎么获取checked值”,百度出来的各个教程的方法和我一样啊,怎么人家能用我就不能用?

最后直接百度“checkbox checked undefined”,总算找到答案了。

原来,在jquery1.6版本有了变更:

checked属性在页面初始化的时候已经初始化好了,不会随着状态的改变而改变。

也就是说如果checkbox在页面加载完毕时是选中的,那么返回的永远都是checked,如果一开始没被选中,则返回的永远是undefined。

然后怎么办呢, 用jq的.prop()方法。例子就是上边的代码了。

真想说过期信息害死人,以后搜索技术问题的时候最好去搜索选项里,把结果限制在最近一年之内。

jq中获取checkbox的checked值

08/21
2015
学习

制作色彩不同的tag标签

单独查看demo

比较简单的一个小玩意,昨天做的网站里需要这个类似的功能,于是改了下单独发出来。 代码如下:

<div id="wrap">
	<a href="">hug_(artist)</a><a href="">single_shoe</a><a href="">豊聡耳神子</a><a href="">東方 東方project 東方プロジェクト touhou Touhou 东方 东方project</a><a href="">百合 レズ</a><a href="">碧眼</a><a href="">青髪 青い髪 水色髪</a><a href="">髪飾り</a><a href="">花 はな フラワー</a><a href="">short_sleeves</a><a href="">short_sleeves</a><a href="">御札</a>
</div>
<style>
	#wrap{width: 900px;}
	#wrap a{display: inline-block; padding: 0 10px;margin:0 8px 8px 0;font-family: "Microsoft YaHei";font-size: 13px;color: #fff;line-height: 26px;text-decoration: none;border-radius: 2px;}
	#wrap a:hover{opacity: 0.8;transition:all .3s;}
</style>
<script>
		function setbg (id,allColor) {//参数为容器id和颜色数组

		var alla=document.getElementById("wrap").getElementsByTagName("a");

		/*如果展示的区域太窄,可以截取字数以控制a标签的长度,以确保一行最少能有2个或几个
		for (var i = 0; i < alla.length; i++) {
			if(alla[i].innerHTML.length>8){
				alla[i].innerHTML=alla[i].innerHTML.substr(0,7);
			}
		};
		*/

		//设置背景颜色
		var allcolor=allColor;
		usedColor=null;	//上次用到的颜色
		nowColor=null;//当前随机到的颜色
		allaBgIndex=0;//给a标签设置背景颜色时,a的索引数字
		bgindex = Math.floor((Math.random()*allcolor.length));
		usedColor=allcolor[bgindex];	//先随机一个颜色设置为用过的颜色

		for (var i = 0; i < 999; i++) {
				bgindex = Math.floor((Math.random()*allcolor.length));
				nowColor=allcolor[bgindex];	//随机一个颜色
				if (usedColor!=nowColor) {	//如果当前颜色和上一个用过的颜色不同,则设置背景色
					alla[allaBgIndex].style.backgroundColor=nowColor;
					usedColor=nowColor;//把这次用的颜色设置为上次用到的
					allaBgIndex++;
					if (allaBgIndex==alla.length) {//如果a标签已经全部设置了背景颜色
						break;
					};
				};
			};

		};

		setbg ("wrap",["#448EEF","#E95555","#1369C0","#1AB4C1","#F49129","#2C9F42"]);
</script>

主要的功能就是设置相邻的a标签的背景色不重复了,样式上没有什么难度。

注释里有个蛋疼的截取字数的功能,那是昨天在做网站时弄的。当时的展示区域非常小,宽度只有270多px,但是调取的还是文章标题,都不算短。要求一行最少有两个a标签,只好截取了。截取的缺点就是肯定有一些标签宽度是一样的,这显得很死板,展示区域越窄越明显。

display: inline-block;如果相邻的两个元素不对齐,可以使用vertical-align: top;

制作色彩不同的tag标签

08/20
2015
学习

解决火狐不支持jq动画的backgroundPosition属性的方法

现在排版的网站中有一个地方,指示器的位置需要变化,我用jQuery做了动画,把这个指示器设置为背景图,然后使用backgroundPosition属性来使其移动。

可是今天测试兼容性的时候发现在火狐下这个动画无效。百度一番,找到了解决办法。参见此处

解决这个问题之前(火狐中无效)的动画代码如下:

$("#anlilist").animate({
	backgroundPositionX:bgLeft+"px",
	backgroundPositionY:"0px"
},100);

这时候X和Y值要分别定义,否则chrome中是无效的。

要解决火狐中无效的问题,先在动画的代码之前加入以下代码:

/**
 * 自定义backgroundPosition的animate,支持火狐,jQuery1.8以上版本
 * @author Meleong
 * v1.00
 */
(function($) {
    $.fx.step["backgroundPosition"] = function(fx) {
        if (typeof fx.end == 'string') {
            fx.start = getBgPos(fx.elem);
            //fx.end原本是一个string,这里将它转换成数组,就不会再进入这个if,也方便我们下面的计算
            //例 "0px -21px"
            fx.end = [parseFloat(fx.end.split(" ")[0]), parseFloat(fx.end.split(" ")[1])];
        }
        //这里fx.pos是根据传入的时间参数,从0到1变化的浮点数
        var nowPosX = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit;
        var nowPosY = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit;
        fx.elem.style.backgroundPosition = nowPosX + ' ' + nowPosY;
        
        /**
         * 获取backgroundPosition数组[top, left],没有单位
         */
        function getBgPos(elem) {
            var top  = 0.0;
            var left = 0.0;
            if ($(elem).css("backgroundPosition")) {
                //例 "0px -21px"
                top  = parseFloat($(elem).css("backgroundPosition").split(" ")[0]);
                left = parseFloat($(elem).css("backgroundPosition").split(" ")[1]);
            }else{
                top  = parseFloat($(elem).css("backgroundPositionX"));
                left = parseFloat($(elem).css("backgroundPositionY"));
            }
            return [top, left];
        }
    }
})(jQuery);

然后改一下动画的代码,把X和Y的值写在一起就行了。

$("#anlilist").animate({
		backgroundPosition: bgLeft.toString()+"px 0px"
},100);

这样写一起chrome里也是能用的,分开写chrome里反而无效了。此时,IE、chrome、firefox三大浏览器里都可以正常实现动画效果了。
Read More →

解决火狐不支持jq动画的backgroundPosition属性的方法