12 / 06 / 2018 buling

就不介绍前提了,直接正题吧
1、找一部android手机,usb连接到电脑,需要root
2、找到一个adb.exe
找到adb.exe的方式有很多,比如装一个PC应用宝,或者微信开发者工具下面也有,用everything搜一下就可以找到
3、cmd下面执行:
adb.exe devices
如果手机连接成功会显示设备
List of devices attached
71MBBL6228EU device
4、进入设备命令行:
adb.exe shell
5、提升权限到root:
su
如果提示没有这个命令,那说明设备还没有root,可以下载一个kingroot APP
6、切换到微信小程序代码包目录:
cd /data/data/com.tencent.mm/MicroMsg/{User}/appbrand/pkg
7、可以把你要破解的小程序删掉,重新搜索打开,再目录中 ll 看最新创建时间的就是目标小程序
8、因为 /data 目录为系统级目录,无法直接将其进行复制,需要重新挂载为可操作模式
mount -o remount,rw /data
9、拷贝小程序到手机SD卡中,可以用文件管理直接找到这个目标包
cd /data/data/com.tencent.mm/MicroMsg/{User}/appbrand/pkg/_-1946107229_14.wxapkg /mnt/sdcard
10、把apkg包传到电脑端
https://gist.github.com/feix/32ab8f0dfe99aa8efa84f81ed68a0f3e 使用这个脚本,直接解压apkg
11、还原各个加密文件:page-frame.html、app-service.js、app-config.json
参考这里:https://github.com/qwerty472123/wxappUnpacker
ok

从app页面选择手机中的图片一般都比较大,动则N个M,然后页面就挂在那里玩了,接下来就是讨论解决方案,之道的img压缩方案就是使用canvas压缩图片,那现在问题变为canvas压缩图片后如何上传的问题了
1、从input file中读出图片的方法

var loadImageFromFile = function(file, callback) {
    var reader = new FileReader();
    reader.onload = function (e) {
        callback(e.target.result);
    };
    reader.readAsDataURL(file);
};

参考链接:https://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/
2、使用canvas压缩图片同上链接已给出
3、canvas转为blob格式

var dataURItoBlob = function(dataURI){
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);
    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ia], {type:mimeString});
};

参考链接:http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
4、异步上传,新建一个formdata对象,添加blob到formdata中

var formdata = new FormData();
formdata.append('imgfile', blob);
var url = "upload.php";
$.ajax({
    type:'POST',
    url:url,
    data:formdata,
    contentType:false,
    processData:false,
    success : function(jdata){
        console.log(jdata);
    }
});

综上所述给一个Helper

var ScaleImageHelper = {
    //从FILE中加载img
    loadImageFromFile : function(file, callback) {
        var reader = new FileReader();
        reader.onload = function (e) {
            callback(e.target.result);
        };
        reader.readAsDataURL(file);
    },
    dataURItoBlob : function(dataURI){
        var byteString;
        if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
        else
            byteString = unescape(dataURI.split(',')[1]);
        // separate out the mime component
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
        // write the bytes of the string to a typed array
        var ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        return new Blob([ia], {type:mimeString});
    },
    resizeImgToCanvas : function(img, maxHeight, maxWidth){
        maxHeight = maxWidth||640;
        maxWidth = maxWidth||640;
        var width = img.width;
        var height = img.height;
        if(width > height){
            if (width > MAX_WIDTH) {
                height *= MAX_WIDTH / width;
                width = MAX_WIDTH;
            }
        }else{
            if (height > maxHeight) {
                width *= maxHeight / height;
                height = maxHeight;
            }
        }
        var canvas = document.createElement('canvas')
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, width, height);
        return canvas;
    },
    canvasToBlob : function(canvas){
        var dataURL = canvas.toDataURL('image/jpeg', 0.5);
        return this.dataURItoBlob(dataURL);
    },
    post : function(url, formdata, callback){
        $.ajax({
            type:'POST',
            url:url,
            data:formdata,
            contentType:false,
            processData:false,
            success : function(jdata){
                console.log(jdata);
            }
        });
    }
};

测试案例如下:


//监听文件变化
$('#J-file').on('change', function(){
    if(this.files.length<1){
        return ;
    }
    var file = this.files[0];
    //从文件中加载图片
    ScaleImageHelper.loadImageFromFile(file, function(src){
        var img = document.createElement('img');
        //插入图片到body中
        //$(document.body).append(img);
        //图片加载完成
        img.onload = function(){
            //通过canvas缩放图片
            var canvas = ScaleImageHelper.resizeImgToCanvas(this, 10, 10);
            //把canvas转成blob格式
            var blob = ScaleImageHelper.canvasToBlob(canvas);
            //插入到form中异步上传
            var formdata = new FormData();
            formdata.append('imgfile', blob);
            ScaleImageHelper.post('./scale-canvas.php', formdata);
        };
        img.src = src;
    });
});

最近一个小应用需要做播放器,当然首选jplayer,由于是手机应用,还是用zepto代替了jquery,昨晚折腾了很晚,也没找到为何出错了,比较晚耐心也不好,最终放到了今天。
官方文档,硬是把使用zepto代替jquery的说明拆成了几段,一不小心就跳过了重点

//如果使用了AMD module需要修改下面的代码
//替换define(['jquery'], factory); 为
define(['zepto'], factory);

那么zepto源码中是没有amd加载支持,这个时候我们需要补充一下

define("zepto", [], function(){return Zepto;});

但发现其实还是使用不了,设置如下可以使jplayer打印出错误日志

my_jPlayer.jPlayer({
    errorAlerts: true //显示错误信息
})

发现错误日志如下:

jPlayer 2.9.2 : id=’jquery_jplayer’ : Error!
Attempt to issue media playback commands, while no media url is set.
Use setMedia() to set the media URL.
Context: play

那么就是setMedia没有调用到,跟一下源码,在第57行代码var instance = $(this).data(name);得到的结果是”[object Object]”,一看zepto不支持data为object,然后我再看官方文档,重点来了

Zepto
Compatibility verified with:
Zepto 1.0 compiled with Data module

整个人都很难受,为何不仔细看文档,为何不仔细看文档

22 / 07 / 2015 buling

这几天一直在做XX活动,明天发,主要负责手Q平台,微信平台被人抢了,所以。有如下些点分享
1、页面字体大小,

html {font-size:62.5%}
/*未经调整的浏览器都符合: 1em=16px,所以10px=0.625em,设置html为62.5%,那1rem就是10px*/
/*之后页面布局均使用rem来布局,方便统一调整*/

2、音乐播放操作



(function(){
    //audio dom
    var videoMusic = $('#audio')[0];
    //监听回调
    var videoLoaded = function(){
        //控制按钮
        var $controll = $('#J_music-controller');
        //设置音量
        videoMusic.volume = 0.5;
        //开始播放
        videoMusic.play();
        $controll.show().on('tap', function(){
            var $this = $(this);
            if($this.hasClass('music-close')){
                $this.removeClass('music-close');
                videoMusic.play();
            }else{
                $this.addClass('music-close');
                videoMusic.pause();
            }
        });
    };
    //监听是否加载完成可以播放
    videoMusic.addEventListener('canplay', videoLoaded);
    if(videoMusic.readyState==4){
        videoLoaded();
    }
}());

3、陀螺仪模拟摇一摇

var AcceHelper = (function(){
    var lastAcceTime = 0,
        lastAcceInfo = false,
        firstAcceInfo = false,
        lastDistance = 5000,
        isStart = false,
        stopTimer = 0,
        config = {
            timeLimit : 100, //两次感应间隔时间为200
            speedLimit : 80, //速度限制为80
            stopLimit : 400
        };
    var getDistance = function(a, l){
        var powDis = Math.pow(a.x-l.x, 2) + Math.pow(a.y-l.y, 2);
        return Math.sqrt(powDis);
    };
    var doAccelerationIncludingGravity = function(acceleration, oncallback, stopcallback){
        var curTime = (new Date()).getTime(),
            a = acceleration,
            l = lastAcceInfo,
            time = curTime-lastAcceTime;
        if(time>config.timeLimit && lastAcceInfo){
            //debugFunc('on acceleration call['+(a.x+'_'+a.y+'_'+a.z)+']');
            lastAcceTime = curTime;
            var distance = getDistance(a, l),
                speed = distance/time*1000;
            if(speed>config.speedLimit){
                isStart = true;
                if(stopTimer){ //清除结束
                    clearTimeout(stopTimer);
                }
                if(!firstAcceInfo){ //设置第一次
                    firstAcceInfo = {
                        x : a.x,
                        y : a.y,
                        z : a.z
                    };
                }
                var aDistance = getDistance(a, firstAcceInfo);
                debugFunc('on acceleration call['+(aDistance+'_'+lastDistance+'_'+distance)+']');
                if(aDistance[[[[['+num+'
'); endcall && endcall.call(null, num, info, acceleration); num = 0; }); }; var removeAccelerometer = function(){ $(window).off('devicemotion'); }; return { on : endAccelerometer, remove : removeAccelerometer, init : function(options){ $.extend(config, options); } }; }()); //使用方法 AcceHelper.on(function(num, info, acceleration){ //晃动第几次 debugFunc('on acceleration num:' + num); }, function(num){ //结束 //结束时回调总共摇动了几次 debugFunc('on acceleration end num:' + num); });

3、分享一些动画

无标签信息 0 条
06 / 06 / 2015 buling

1、单行超出省略号方法
限定高宽, 设置css:overflow: hidden; text-overflow:ellipsis; white-space:nowrap;
2、多行超出省略号方法
css:overflow: hidden; display: -webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
3、rgba的向下兼容方法
css:background:#ccc; background:rgba(0, 0, 0, 0.8);
=========================JS============================
1、获取窗口大小

function getWindowHeightAndWidth(){
    var obj = window,
        sname = 'inner';
    if(!('innerWidth' in window)){
        sname = 'client';
        obj = document.documentElement || document.body;
    }
    return {
        width : obj[sname+'Width'],
        height : obj[sname+'Height']
    };
}

2、array-like object 在jquery中的使用方法。如果需要让一个object在console.log时看起来像一个数组

//The object has to have length and splice
var x = {length:2, '0':'foo', '1':'bar', splice:function(){}};
jQuery.fn.init.prototype.splice = [].splice;

3、摇一摇时禁止Iphone在页面提示“撤销键入”

$(window).off('devicemotion').on('devicemotion',function(eventData){
    //dosomething(eventData.accelerationIncludingGravity);
    eventData.preventDefault(); //就是这句了
});

4、禁止页面被拖动
//去掉IOS滚动到顶部回弹一下的效果


//这里是列表可以滚动
$('#J_userchat-list').on('touchmove', function(event){
    event.stopPropagation();
});
//全局阻止移动,防止页面被拽
$(document).on('touchmove', function(event){
    //$('#J_page-box-1').prepend('
move body
'); event.preventDefault(); });

5、查看表大小排序
SELECT TABLE_NAME,DATA_LENGTH+INDEX_LENGTH as SIZE,TABLE_ROWS,concat(round(data_length/1024/1024),’MB’) as data FROM information_schema.TABLES WHERE TABLE_SCHEMA=’child’ order by SIZE desc limit 10;

无标签信息 0 条

最近做了一个软管活动页面由于页面比较大,需要切小背景图,由于时间紧也就没有做太多思考,独立了一个div来做背景,其余做内容,上线后遇到两个问题
1、在缩小页面时,内容浮动和背景不一致
由于内容限制了1000px的宽度,而背景没有限制宽度,所以导致背景被overflow hidden掉了,而内容出现滚动条,解决很简单,背景也限制最小宽度即可,当然ie6那货不支持,我就直接放弃了
2、在iphone/ipad 的safari上访问时由于动画会改变页面的宽度,出现页面变形,头大,怎么会呢,下个pc版safari也没有问题,然后就开始google,stackoverflow:Does overflow:hidden applied to work on iPhone Safari?,好吧,解决了

/*create a wrapper on the whole website to achieve that; and add css*/
.wrapper{
    position:relative; //that's it
    overflow:hidden;
}

昨晚睡前看了一篇文章:有哪些经常被误用的 HTML、JavaScript、CSS 的元素、方法和属性?,文中提到清除浮动,以前经常用clearfix,但从来没有注意过原理,不过我也习惯用overflow来清除浮动,代码如下

.clearfix{*zoom:1;}
.clearfix:after{content:"\200B"; display:block; clear:both; height:0;}

用zoom来兼容IE6/IE7下不支持伪类after触发haslayout; after用于向float元素末端添加一个\200B的空元素,设置为block,clear both清除浮动,顺便设置height为0避免对布局造成影响。其实和在元素末尾添加
等同的效果

04 / 01 / 2015 buling

      之前看过很多去jquery开发的文章,前几天又看到,可惜没有了文章地址,大抵是说jQuery封装的实在太好以至于让我们变的越来越懒越来越愚钝。一直打算去jquery开发,但后来很多次都是迫于开发效率,还是使用了jquery来开发,最近又打算尝试去jquery化,刚开始使用工具库的方式提供大堆的工具函数,尤其是在对dom操作时,函数总是需要传入dom,显得很繁冗,最后就尝试向jquery靠拢,但后来写着写着就发现,其实去jquery的意义在于再建一个mini-jquery库而已,越开发越觉得没有意义,唯一的意义在于对底层的js更熟悉,兼容方法总结。下面来给之前还未写完的一些测试案例:

//test select
var itembox = $('div ul,.item-box', document.body)[0],
    lis = $('.item', itembox);
debug('selector > get dom length:'+lis.length, 'info');
//test json
var jsonobj = {name : 'hehe', age:12},
    jsonstr = $.stringify(jsonobj),
    njsonobj = $.parseJSON(jsonstr);
debug('json > parse get name:'+njsonobj.name, 'info');
//test each
$.each(lis, function(dom, i){
    debug('each > '+i+':'+dom.tagName, 'info');
});
//test extend
var nobj = $.extend(jsonobj, {desc: 'hello!'});
debug('extend > parse new object:'+$.stringify(nobj), 'info');
//test css
debug('css > get item-box height:'+$(itembox).css('height')+'; after 2 seconds change backgrund', 'info');
setTimeout(function(){
    $(lis).css({
        'background' : '#ff0',
        'color' : '#f00'
    });
    debug('css > get item-box color:'+$(lis).css('color')+';', 'info');
    $(itembox).fadeOut(function(){
        $(itembox).fadeIn(function(){
            //add class
            $(lis[0]).removeClass('item').addClass('bold');
        });
    });
}, 2000);
//test ajax
$.ajax({
    url : './ajax-api.php',
    timeout : 3500,
    method : 'post',
    data : {name:'hello', age:12},
    success : function(content, xhr){
        debug('json > get resonse header:'+xhr.getAllResponseHeaders());
        debug('json > get callback:'+content);
        var jobj = $.parseJSON(content);
        debug('json > get code:'+jobj.code);
    },
    error : function(info, xhr){
        debug('json > error callback:'+$.stringify(info), 'error');
    }
});
//test animat
//animate(callback, executeTime, intervalTime)
$.animate(function(percent, curtime){
    debug(percent);
}, 400, 200);

具体js代码如下,访问地址:http://mjix.com/code/varcom/
; 源码地址: http://mjix.com/code/varcom/uquery.src.js
昨晚睡觉前又看了一下:Javascript之旅系列 以及 《JavaScript高级程序设计》读书笔记,我也在看这本书,只是书中写的实在太细,没有能像这位整理的这么好,之后需要再把类继承章节重新阅读一次才行。

07 / 11 / 2014 buling

      港行iphone6预定有很多规则限制:1、每个apple id限抢一次;2、每个手机号码限抢一次;每个身份证限抢一次。第一次预定成功,结果通行证过期,只能放弃,之后又买了一张卡,连续早起N次都没有结果,昨天又买了一张卡,今天早上再次失败,痛定思痛,从脚本开始,跟黄牛比手工不靠谱。目前港行价格16G基本还是5000RMB左右,所以脚本来了

var storeNum = 'R428',            //ifc店
    modelNum = 'MG4H2ZP/A',  //银色64G
    govType  = 'entryExitPass',  //通行证
    govID    = 'C050XXXXX';      //证ID
//这里用于去除可用性检测
if(!window._fetchPostData){
    _fetchPostData = fetchPostData
    fetchPostData = function(eventId, params, callback){
       if(eventId=='availability'){
           return false;
       }
       _fetchPostData(eventId, params, callback);
    }
}
//选择店面
$('#productSelection [name=selectedStoreNumber]').val(storeNum ).change();
//选择iphone6
$('#product .box').eq(0).click();
$('#locked .box').eq(0).click();
//选择颜色,第一个银色
$('#color input.iPhone6').eq(0).parent().click();
//选择64G
$('#model').removeClass('disabled');
$('#model .loading-spinner').addClass('hidden');
$('#model .group').attr('style', '').find('input[value="'+modelNum+'"]').parent().click().parent().show();
//填写联系资料
$('#quantity [name="selectedQuantity"]').val(2);
$('#contact [name="selectedGovtIdType"]').val(govType);
$('#contact [name="govtId"]').val(govID);
//选择时间
$('.button-container a, #time').removeClass('disabled');
$('#time select option').eq(2).prop('selected', true);
//提交
$('#productSelection')[0].submit();

      如果预定成功,我再来更新成自动化脚本,如果没成功就算了,来,嘿、嘿、嘿,加油!

      有时候在ipad或者android等移动设备上需要查看网页源代码,但移动设备本身是不支持查看,只能通过代码方式,之前一直用国外一款工具(忘了名字),但感觉有点慢,所以就根据geshi提供的api,自己搭建了一个,访问地址:http://www.mjix.com/code/viewsource/
      有时候看一些电影下载网站,页面看不到下载链接,只能通过查看源代码的方式获取链接地址,在ipad上很是不方便,通过这个工具查看源代码就方便很多。
怎么安装呢?
方法一:通过电脑收藏夹同步到IPAD等设备。拖动下面的链接到你的收藏夹中:
View Source
方法二:直接添加到收藏夹
1、添加当前页面到你的收藏夹中
2、点击  这个文件查看收藏夹代码  并且复制代码
3、修改刚刚添加到收藏夹中的“查看源代码”,粘贴代码到URL中,保存。

提供api为:http://www.mjix.com/code/viewsource/?uri=$url

      之前一直想做一个文字粒子效果的淡出淡进,这两天事情不多就写了一下代码,效果地址:http://www.mjix.com/code/canvas-text/,按F11进入全屏,做屏保还可以,预览图

======================已更新==========================
      由于之前版本,像素点是通过fillRect来实现,性能有严重问题,会卡顿,cpu直接能飙到25左右,新版通过生成imagedata,再putImageData来达到更新效果。
      主要是在粒子(文字像素点)的位移问题上的处理方法。淡进前需要先获取到像素点的初始位置极其透明度,这个东东运用到数学左边换算问题,要遇到数学有点头大就跳过吧

     //获取渐进前的像素点位置
    getInData : function(data, min, offset){
        var xs = [],
            ys = [];
        this.each(data, function(info, index){
            xs.push(info[0]);
            ys.push(info[1]);
        });
        var max = Math.max.apply(xs, xs),
            mix = Math.min.apply(xs, xs),
            may = Math.max.apply(ys, ys),
            miy = Math.min.apply(ys, ys),
            //找出近似中间点
            midx = (max+mix) / 2,
            midy = (may+miy) / 2;
        var self = this,
            dis  = 0,
            len = 0,
            prop = 0,
            newData = [];
        this.each(data, function(info, index){
            alp = -self.random(0.1, 1);
            len = min+self.random(offset);
            dis = Math.sqrt(self.getDistance(info, [midx, midy]));
            prop = len/(dis+len);
            newData.push([]);
            var xy = Math.ceil((info[0]-prop*midx)/(1-prop));
            newData[index][0] = xy;
            xy = Math.ceil((info[1]-prop*midy)/(1-prop));
            newData[index][1] = xy;
            newData[index][2] = info[2].concat();
            newData[index][2][3] = alp;
        });
        return newData;
    },

      然后是更新像素点位置,方法是,随机一个前进长度,根据当前点和目标点及移动不长确定下一个移动目标点的位置,如下

    //获取指定长度点目标点位置
    getDestDot : function(data1, data2, length){
        if(data2[1]==data1[1] && data2[0]==data1[0]){
            return data2;
        }
        var xdis = Math.sqrt(this.getDistance(data1, data2)),
            prop = length/xdis;
        x = Math.ceil(prop*(data2[0]-data1[0])) + data1[0];
        y = Math.ceil(prop*(data2[1]-data1[1])) + data1[1];
        return [x, y];
    },

      直到所有的像素全部归位后,设置延迟,再淡出,淡出我就草草处理了,意思意思,效果自己看,源码就不说了。如所有的代码一样可能存在各种兼容性,BUG等等不可预料问题,留言反馈。
      之前1.0版本性能有严重问题,作为反例提供给大家:http://www.mjix.com/code/canvas-text/index1.0.html