浏览器中预览即将上传的图片

$("input[type=file]").on("change", function(){
	if( /^.+\.(jpg|jpeg|png)$/.test(this.value) ){
		var r = new FileReader(),
			name = this.name;
		r.onloadend = function(e){
			$("img[for="+name+"]").attr("src", e.target.result).addClass("loadend");
		};
		r.readAsDataURL(this.files[0]);
	}else{
		this.value = "";
		alert("仅支持(jpg、png)格式图片!");
	}
});

SQL变量

https://leetcode-cn.com/problems/department-top-three-salaries/description/

SELECT
    d.Name AS Department,
    e.Name AS Employee,
    e.Salary AS Salary
FROM
    Department AS d
JOIN(
      SELECT
        t.*,
        (CASE @k WHEN DepartmentId THEN @n := IF(@s=Salary,@n,@n+1) ELSE @n := 1 END) AS n,
        IF(@k = DepartmentId, @k, @k := DepartmentId) AS k,
        @s := Salary AS s
      FROM
        (SELECT @n := 0, @k := 0, @s := 0) AS _,
        (SELECT * FROM Employee ORDER BY DepartmentId ASC, Salary DESC) AS t
    ) AS e ON d.Id = e.DepartmentId
WHERE e.n < 4;

浏览器多标签页之间通信

打开多个加载以下JS代码的标签页,当其中一个标签页调用 window.localStorage.setItem 方法时,其他标签页的 storage 事件就会被触发,event 变量中包含修改前后的值,可实现不同标签页之间的消息传递,调用 window.localStorage.setItem 方法的标签页的 storage 事件不会被触发(Win10中的IE11除外)!!!

var data = {"type":"message", "data":"abc"};
window.localStorage.setItem("message", JSON.stringify(data));
window.addEventListener("storage", function(e){
	console.log(e);
}, false);

MySQL使用存储过程随机获取数据表中若干条记录

DROP PROCEDURE `get_rand_result`;
CREATE DEFINER=`root`@`localhost` PROCEDURE `get_rand_result`(IN `i` INT UNSIGNED) NOT DETERMINISTIC READS SQL DATA SQL SECURITY DEFINER BEGIN

DECLARE mx INT;
DECLARE mi INT;
DECLARE var TEXT DEFAULT '';

SELECT MAX(`id`) INTO @mx FROM `users_profile`;
SELECT MIN(`id`) INTO @mi FROM `users_profile`;

DROP TEMPORARY TABLE IF EXISTS `tmp_table`;
CREATE TEMPORARY TABLE `tmp_table` (
  `id` bigint(20) unsigned NOT NULL
) ENGINE = MEMORY;

WHILE i>0 DO
  SELECT FLOOR(@mi + RAND() * (@mx-@mi)) INTO @var;
  INSERT INTO `tmp_table` VALUES(@var);
  SET i=i-1;
END WHILE;

SELECT `users_profile`.* FROM `users_profile` INNER JOIN `tmp_table` ON `users_profile`.`id` = `tmp_table`.`id`;

END

数据表 `users_profile` 记录数 100W+
存储过程中最后一条SQL查询性能优化过程:in(±80ms) > right join(±40ms) > inner join(±3ms) ;

cordova 开发 app 使用 touch 事件替换 click 事件

使用 ul li 做导航条时,由于 click 事件的处理时机要晚于 touchstart ,并且 click 事件能明显使用户感觉到延迟,因此使用 touch 事件代替 click 事件。
由此又带来一个问题:用户滑动导航条时,本意可能是让导航条滚动,但是却触发了导航中某一项的点击事件。下面的代码使用 touchstart 与 touchmove 相结合的方式解决二者的冲突。

var nav = document.querySelector(".nav");

nav.addEventListener("touchstart", function(e){
if(e.target.tagName == "LI"){
    app.navTouchEventTimer = setTimeout(function(){
        // 100毫秒后处理 ul.nav 内部 li 的 touch 事件
    },100);
}
}, false);

nav.addEventListener("touchmove", function(e){
if(app.navTouchEventTimer != false){
    // 在 ul.nav 的 touchmove 事件监听器中取消 li 的 touch 事件
    clearTimeout(app.navTouchEventTimer);
    app.navTouchEventTimer = false;
}
// 处理 ul.nav 的 touchmove 事件
}, false);

CSS3 实现图片翻转动画效果

@-webkit-keyframes navSelecterBtnUp {
from { -webkit-transform: rotate(0deg); }
to   { -webkit-transform: rotate(-180deg); }
}

@-webkit-keyframes navSelecterBtnDown {
from { -webkit-transform: rotate(-180deg); }
to   { -webkit-transform: rotate(0deg); }
}

.navselecter-btn img {
margin: 0.9em 0.5em;
width: 18px;
height: 12px;
}

.navselecter-btn img.up {
-webkit-animation: navSelecterBtnUp 0.3s;
-webkit-transform: rotate(-180deg);
}

.navselecter-btn img.down {
-webkit-animation: navSelecterBtnDown 0.3s;
-webkit-transform: rotate(0deg);
}

配置 xbmc-addons-chinese 镜像地址

国内的网络几乎已经墙掉了Google的所有服务,googlecode也不例外。

XBMC中文扩展插件存放在 googlecode 上,已被墙。配置了一个镜像地址供 raspberry pi 搭建的多媒体中心使用。

<info compressed=”false”>http://xbmc.nt00.com/svn/addons/eden_src/addons.xml</info>
<checksum>http://xbmc.nt00.com/svn/addons/eden_src/addons.xml.md5</checksum>
<datadir zip=”false”>http://xbmc.nt00.com/svn/addons/eden_src</datadir>

javascript 计算中英混合字符串长度及截取函数

产品的BT需求:当输入框限制最多可输入10个字时,达到的效果为输入框可输入5个汉字加10个字母,中文按1个字计算,英文按0.5个字计算,并且超出长度要自动截断。

String.prototype.mb_len = function(){
	var len = 0;
	for(var i=0;i<this.length;i++){
 		len = len+(this.charCodeAt(i)>255?1:0.5);
	}
	return len;
};
String.prototype.mb_sub = function(start, length){
	var str = "";
	for(var i=start;i<this.length;i++){
 		length = length-(this.charCodeAt(i)>255?1:0.5);
		if(length<0)break;
		str = str+this[i];
	}
	return str;
};