微信小程序TGIT检出远程master到本地master

先配置小程序开发工具中的版本控制
设置中用户信息填写由小程序后台TGIT添加的用户,需要填写全名,在小程序后台TGIT项目控制的链接进入腾讯云DEV,点击项目进入工蜂,查看全名通常比较长最后一个下划线后接的是后台输入的用户名。
邮箱是腾讯云分配的,通常是你的很长的用户名@git.cloud.tencent.com。
网络认证,认证方式选择最后一项填入用户名密码,即小程序后台新建用户的时候填入的账号密码,账号就是工蜂用户名,很长的那个。
远程,点添加将工蜂中的项目地址填入,名称跟工蜂中的名称一致即可。
配置正确之后,点击抓取,抓取项目,能看见项目中分支信息出现在左侧远程下面,然后拉取可以拉取源代码。
注意,第一拉取时,比如远程git项目为Estate/master分支。
从Tgit终端控制台中输入

1
git checkout -b master Estate/master

注意如果Tgit上有代码则需要将本地所有文件先删除,留空项目目录。如果没有应该首先提交本地代码,再推送,产生新git分支

JavaScript中的高精度计时

HRT(High Resolution Timing, 高精度计时)在一些场合有很大的作用,比如游戏开发中,需要精确的计算两帧之间的时间差。

在JS中常常用(new Date()).getTime()来获取毫秒级的时间戳,虽然是毫秒级,但事实上它的真实精度只能达到大概16ms的级别。例如

1
2
3
while (true){
  console.log((new Date()).getTime()); // 这样死循环浏览器会跪的,责任自负
}

会发现它事实上大概16ms才跳一次,也许是17ms、又或者15ms吧,反正实际精度是有限的——什么?你跟我说是1ms?我告诉你那是因为新的系统或者浏览器使用了更高精度——但这不影响这篇文章的内容……

这对于日常应用来说完全够用了,但是对于游戏这样的场合,高精度计时就有它不可取代的意义了。

故事从这里开始
上面的获得毫秒级时间戳的方式之所以精度有限,是因为它的实现方式,以及它“绝对时间”的定义。
以Windows为例,这一类时间戳所使用的系统调用,比如GetSystemTime()MSDN、GetTickCount()MSDN,其函数的取值并不是实时的,而是通过硬件的时钟中断被动刷新的,这里的刷新间隔“正好”就是上面那个16ms。以GetSystemTime()为例,它返回的是SYSTEMTIME结构体,这用来进行时间日期处理的,因为时间日期处理通常根本不需要也不应该用那么高的精度(甚至很多时候只需要秒级别的精度),所以(new Date()).getTime()通过它们实现的确是可以胜任的。

现在我们明白了,靠这个时间戳是不能实现高精度计时的。
在Windows上,常常有两种高精度计时的方式:
第一种是timeGetTime()MSDN,它能返回系统启动到现在所经过的毫秒数,精度是1ms,因为它是32位的,所以大概49.71天会溢出清零。
第二种QueryPerformanceCounter()配合QueryPerformanceFrequency()MSDN实现,能够实现微秒级别的计时精度,对于大多数场合而言都够了。
当然还有更先进的方法,是通过CPU中的硬件计数器,和CPU每个时钟周期的时间,计算出更精确的时间(通常是纳秒级别的),对精度要求极高的场合这是最精确的选择了。

通常在使用固定位数的情况下,精度越高意味着计时的范围越小,这就不罗嗦了。

回到JavaScript中来
上面那些乱七八糟系统调用其实更咱们都没什么太大关系,我们能干什么完全看运行环境乐意给什么。
在webkit中提供了performance.now()参考文献来获取一个毫秒级的浮点数时间戳,我没查到资料它的有效精度是多少,不过既然给了个浮点数那就这么用着吧,我们就当它是微秒级的了!
在node.js中,有process.hrtime()DOC,返回的是一个数组[seconds, nanoseconds],看起来它具有纳秒级别的精度?且信了吧。

综合一下,我写了下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
exports.time = (function(){
  if (typeof window !== 'undefined'){
    // 浏览器
    if (typeof window.performance !== 'undefined' && typeof performance.now !== 'undefined'){
      // support hrt
      return function(){
        return performance.now();
      };
    }else{
      // oh no..
      return function(){
        return (new Date()).getTime();
      };
    }
  }else{
    // node.js
    return function(){
      var diff = process.hrtime();
      return (diff[0] * 1e9 + diff[1]) / 1e6; // nano second -> ms
    };
  }
})();

有了上面的代码(gist),我们就能写一个秒表神马的,在做性能测试的时候就用得上了。

最后还是要唠叨一句,HRT是用来计算时间差的,不是用来计算现实中时间(挂钟时间)的。

下一篇文章中,将会对JS中的时间精度进行进一步的讨论,对象自然就是setTimeout/setInterval了!

实时监听页面变化的Chrome Extenstion案例

工程名Chrome_Extenstion_Bider
适用于chrome内核的浏览器
目录结构

1
2
3
4
5
6
7
Chrome_Extenstion_Bider/Bider/css
|-Chrome_Extenstion_Bider/Bider/css/common.css
Chrome_Extenstion_Bider/Bider/include
|-Chrome_Extenstion_Bider/Bider/include/jquery-1.11.0.min.js
Chrome_Extenstion_Bider/Bider/scripts
|-Chrome_Extenstion_Bider/Bider/scripts/main.js
Chrome_Extenstion_Bider/Bider/manifest.json

Chrome_Extenstion_Bider/Bider/manifest.json

1
2
3
4
5
6
7
8
9
10
11
12
{
    "manifest_version": 2,
    "name": "Bider",
    "version": "0.1.0",
    "description": "Bider.",
    "content_scripts": [{
        "matches": ["http://www.hillmatrix.com/*"],
        "css": ["css/common.css"],
        "js": ["include/jquery-1.11.0.min.js", "scripts/main.js"],
        "all_frames": true
    }]
}

Chrome_Extenstion_Bider/Bider/css/common.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#ls_box {
    position: absolute;
    width: 500px;
    height: 300px;
    background-color: #fff;
    border-radius: 5px;
    border: 1px solid #ccc;
    left: 50%;
    top: 50%;
    margin-left: -250px;
    margin-top: -150px;
    z-index: 99999;
    padding: 10px;
}

#ls_box h3 {
    height: 30px;
    line-height: 30px;
    border-bottom: 1px solid #ccc;
    margin: 0 0 5px 0;
    padding: 0;
}

#ls_box #ls_panel {
    height: 105px;
    margin: 10px 0;
}

#ls_box #ls_panel #ls_ms {
    color: blue;
    display: inline-block;
}

#ls_box #ls_panel #ls_warn {
    color: red;
    width: 312px;
    text-align: right;
    display: inline-block;
}

#ls_box #ls_panel #ls_list {
    overflow-x: hidden;
    overflow-y: scroll;
    height: 90px;
    margin: 0;
    padding: 0;
}

#ls_box #ls_panel #ls_list ul li {
    height: 24px;
    line-height: 24px;
    border-bottom: 1px dotted #efefef;
}

#ls_box #ls_panel #ls_list ul li span {
    float: right;
    cursor: pointer;
}

#ls_box #ls_form {
    background-color: #efefef;
    border-radius: 5px;
    padding: 10px;
}

#ls_box #ls_form label {
    padding: 0 5px;
    display: inline-block;
}

#ls_box #ls_form #ls_panel {
    padding: 0 5px;
}

#ls_box #ls_form input {
    width: 120px;
    padding: 5px 10px;
    display: inline-block;
}

#ls_box #ls_form #ls_btnc {
    width: auto;
    padding: 5px 10px;
    text-align: center;
}

#ls_box #ls_form button {
    padding: 5px 10px;
    display: inline-block;
    margin-right: 20px;
}

Chrome_Extenstion_Bider/Bider/include/jquery-1.11.0.min.js

Chrome_Extenstion_Bider/Bider/scripts/main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
var main = {
    flag: false,
    flash: 200,
    money: 0,
    // 初始化
    init: function(target) {
        // 创建界面
        this.create(target);

        // 获取页面数据
        this.listenPage();

        //绑定按钮
        this.bindBtn();
    },

    //绑定BTN
    bindBtn: function() {
        _this = this;

        var ls_start = $('#ls_start');
        var ls_stop = $('#ls_stop');
        var ls_max = $('#ls_max');
        var ls_step = $('#ls_step');

        if (!_this.flag) {
            ls_stop.attr("disabled", "disabled");
            ls_start.removeAttr("disabled");
            ls_max.removeAttr("disabled");
            ls_step.removeAttr("disabled");
        } else {
            ls_start.attr("disabled", "disabled");
            ls_stop.removeAttr("disabled");
            ls_max.attr("disabled", "disabled");
            ls_step.attr("disabled", "disabled");
        }

        ls_start.bind("click", function() {
            if (!_this.flag) {
                ls_start.attr("disabled", "disabled");
                ls_stop.removeAttr("disabled");
                ls_max.attr("disabled", "disabled");
                ls_step.attr("disabled", "disabled");
                _this.flag = true;
            }
        });

        ls_stop.bind("click", function() {
            if (_this.flag) {
                ls_stop.attr("disabled", "disabled");
                ls_start.removeAttr("disabled");
                ls_max.removeAttr("disabled");
                ls_step.removeAttr("disabled");
                _this.flag = false;
            }
        });
    },

    //动态竞标价
    activePrice: function() {
        _this = this;
        var page_sendbtn = $('#bidBtnId');
        var page_pi = $('.TB_priceInput');

        var ls_max = parseInt($('#ls_max').val());
        var ls_step = parseInt($('#ls_step').val());
        //console.log(_this.flag);
        if (_this.flag && ls_max > 0 && ls_step > 0) {
            var cmoney = parseInt(_this.money);
            var m1 = cmoney + ls_step;
            var m2 = ls_max + ls_step;
            if (m1 <= ls_max) {
                page_pi.val(m1);
                $('#ls_warn').html('当前出价:' + m1);
            } else if (cmoney == ls_max) {
                page_pi.val(m2);
                $('#ls_warn').html('当前出价(MAX+1):' + m2);
            } else {
                $('#ls_warn').html('已经超出最大限额+1步长,停止竞标');
                $('#ls_stop').delay(500).click();
            }
        } else if (!_this.flag) {
            $('#ls_warn').html('自动竞标系统停止中');
        } else {
            $('#ls_warn').html('请设置正确的参数');
        }
    },

    // 创建界面
    create: function(target) {
        var _html = '<div id="ls_box">' + '<h3>' + 'Bider' + '</h3>' + '<div id="ls_panel">' + '<div>毫秒计数器:<span id="ls_ms">0</span><span id="ls_warn"></span></div>' + '<ul id="ls_list">正在加载数据...' + '</ul>' + '</div>' + '<div id="ls_form">' + '<div id="ls_panel">' + '<h3>' + '策略' + '</h3>' + '<label>' + '最高价: ' + '</label>' + '<input type="text" id="ls_max" value="0" />' + '<label>' + '步长: ' + '</label>' + '<input type="text" id="ls_step" value="10" />' + '<br />' + '<div id="ls_btnc"><button id="ls_start">开始</button><button id="ls_stop">停止</button></div>' + '</div>' + '</div>' + '</div>';
        target.closest("body").append(_html);
    },

    /**
     * 监听页面数据变化
     */

    listenPage: function() {
        _this = this;
        var page_countDown = $('#countDown_counting'); //the element I want to monitor

        page_countDown.bind('DOMCharacterDataModified DOMSubtreeModified', function(e) {
            var page_cp = $('#currentPrice').html();
            var price_arr = page_cp.split("/");
            var page_cp_total = price_arr[0];
            var page_cp_single = price_arr[1];
            _this.money = page_cp_single;

            var dataList = ['当前状态:总价:' + page_cp_total + ',单价:' + page_cp_single];
            dataList.push('倒计时:' + $('#countDown_counting').html() + '秒');
            _this.printData(dataList);
        });
    },

    /**
     * 将已有数据写到页面上
     */

    printData: function(dataList) {
        if (!dataList || dataList.length == 0) {
            $("#ls_list").html('<p>获取数据失败</p>');
            return;
        }
        // 遍历对象,构建输出html
        var _html = [];
        for (var i in dataList) {
            _html.push('<li>' + dataList[i] + '</li>');
        }
        $("#ls_list").html(_html.join(''));
    },
}

var ext_c = $('#countDown_counting');
//console.log(ext_c[0]);
if (ext_c[0] != undefined) {
    main.init(ext_c);
    var ext_t = parseInt(ext_c.html()) * 1000;
    var ext_isclick = false;
    ext_c.bind('DOMCharacterDataModified DOMSubtreeModified', function(e) {
        if ($.isNumeric($(this).html())) {
            ext_t = parseInt($(this).html()) * 1000;
        }
    });

    var ext_ms = function() {
            var ext_s = 0;
            if (ext_t > 0) {
                ext_t -= 17;
                ext_s = ext_t;
            }
            if (ext_c.html() == '0') {
                ext_c.unbind();
                clearInterval(ext_run);
            }
            console.log(ext_s);
            $('#ls_ms').html(ext_s);
            if (ext_s <= main.flash && !ext_isclick && main.flag) {
                ext_isclick = true;
                console.log('倒计时剩余:' + ext_s + '毫秒,提交请求!');
                ext_c.unbind();
                clearInterval(ext_run);
                $('#bidBtnId').click();
            }
            main.activePrice();
        }

        //毫秒级计数器
    var ext_run = setInterval(ext_ms, 15);
}

Chrome_Extenstion_Bider

JS原生方法监听DOM结构改变事件

https://developer.mozilla.org/en-US/docs/XUL/Events#Mutation_DOM_events

1
2
3
document.addEventListener('DOMNodeInserted',function(){alert(1)},false);
document.addEventListener('DOMAttrModified',function(){alert(1)},false);
document.addEventListener('DOMNodeRemoved',function(){alert(1)},false);

变动事件包括以下不同事件类型:

1
2
3
4
5
6
7
DOMSubtreeModified; //在DOM结构中发生任何变化时触发
DOMNodeInserted; //在一个节点作为子节点被插入到另一个节点中时触发
DOMNodeRemoved; //在节点从其父节点中被移除时触发
DOMNodeRemovedFromDocument; //在一个节点被直接从文档中移除或通过子树间接从文档中移除之前触发
DOMNodeInsertedIntoDocument; //在一个节点被直接插入文档或通过子树间接插入文档之后触发
DOMAttrModified; //在属性被修改之后触发
DOMCharacterDataModified; //在文本节点的值发生变化时触发

让DedeCMS完美兼容PHP5.4 解决织梦后台空白问题

或者大家在用dede的时候会发现,程序装好后,登录后台却发现是一片空白的。但换其他机器又没问题。那是织梦默认的是不支持php5.4版本的。
无法正常登录,将下面代码粘贴到/include/helpers/util.helper.php中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Fix for removed Session functions

function fix_session_register() {
    function session_register() {
        $args = func_get_args();
        foreach($args as $key) {
            $_SESSION[$key] = $GLOBALS[$key];
        }
    }

    function session_is_registered($key) {
        return isset($_SESSION[$key]);
    }

    function session_unregister($key) {
        unset($_SESSION[$key]);
    }
}
if (!function_exists('session_register')){
    fix_session_register();
}

怎样实现织梦dede搜索结果页按频道模型显示不同模板

大家知道怎样实现dede搜索结果页按频道模型显示不同模板吗,这问题网上看到不少朋友都在问,究竟怎样才能实现呢,下面是笔者总结的些方法:
dedecms门户模板的时候经常会有图片模型、文章模型、软件模型之类的,要是给搜索框加一个判定,例如搜索软件模型的时候显示一个模板,搜索文章模型的时候显示一个模板。
具体实现代码:
1 在head区域加入

1
2
3
4
5
6
7
8
9
10
<script language="javascript" type="text/javascript">
<!--
 function check(){
  if(document.formsearch.channeltype.value=="3")
  document.formsearch.action="{dede:field name='phpurl'/}/search_images.php"
  else
  document.formsearch.action="{dede:field name='phpurl'/}/search.php"
 }
-->
</script>

2 更改搜索代码

1
2
3
4
5
6
7
8
9
10
11
<form  name="formsearch" action="" *****ubmit="check();">
    <div class="form">
        <input type="hidden" name="kwtype" value="0" />
        <input name="q" type="text" class="search-keyword" id="search-keyword" value="{dede:global name='keyword' function='RemoveXSS(@me)'/}" />
        <select name="channeltype" id="channeltype" >
            <option value='1' selected='1'>新闻</option>
            <option value='3'>软件</option>
        </select>
        <button type="submit" class="search-submit">搜索</button>
     </div>
</form>

其中重点就是

1
2
3
4
<select name="channeltype" id="channeltype" >
    <option value='1' selected='1'>新闻</option>
    <option value='3'>软件</option>
</select>

关键设置:这里设置的按游戏模型搜索 1是文章模型 3是软件模型

3 复制serach.php 更名为 search_images.php
4 打开 search_images.php

1
require_once(DEDEINC."/arc.searchview.class.php");

更改为

1
require_once(DEDEINC."/arc.searchimg.class.php");

5复制 arc.searchview.class.php 更名为 arc.searchimg.class.php

6 打开 arc.searchimg.class.php
修改

1
2
 $tempfile = $GLOBALS['cfg_basedir'].$GLOBALS['cfg_templets_dir']."/".$GLOBALS['cfg_df_style']."/search.htm";
 $tempfile = $GLOBALS['cfg_basedir'].$GLOBALS['cfg_templets_dir']."/".$GLOBALS['cfg_df_style']."/search_images.htm";

核心的修改已经结束了,剩下的就是在search_images.htm这个模板里自由发挥了。
同理也可以实现按栏目type搜索显示不同风格的结果页得。