分类目录归档:Coding

一个屌丝程序员,每天在不断的Coding,不断的debug,不断的各种。分享编程经验,分享编码乐趣。

Semantic UI中Sidebar边栏禁止自动隐藏

最近学习了Semantic UI,准备使用这套响应式框架改版博客,但研究之后发现改动量过大,而且这套框架的css和js加起来有1M,过于庞大,使用components方式又过于繁琐,很多组件的样式涉及到多个文件,于是最终放弃了。

期间研究了一下Sidebar的使用方法,个人并不喜欢自动隐藏方式,而是点一下出现,再点一下收回,分享一下解决方案。

首先是引入Semantic UI框架文件:

<script src="jQuery.js"></script>
<link rel="stylesheet" href="semantic.css">
<script src="semantic.js"></script>

然后是我们的HTML:

<div class="ui left sidebar inverted vertical visible uncover menu">
    <a class="item"><i class="home icon"></i> Home </a>
    <a class="item"><i class="block layout icon"></i> Topics </a>
    <a class="item"><i class="smile icon"></i> Friends </a>
    <a class="item"><i class="calendar icon"></i> History </a>
</div>
<div class="pusher">
    <button class="ui primary button" onclick="toggle()">
        toggle
    </button>
</div>

之后你应该看到如下的页面:

QQ截图20160718192749.png

现在我们需要在JS中控制它的显示与隐藏了:

function toggle() {
    $('.ui.sidebar').sidebar({
        context: 'body',
        dimPage : false,
        onVisible: function() {
            $('body').click(function(e){
                this.unbind(e);
            });
        },
        onShow: function() {
            $('.ui.sidebar').css("z-index",999);
        },
        onHide: function() {
            $('.ui.sidebar').css("z-index",1);
        }
    }).sidebar('toggle');
}

第一个 sidebar() 中进行了一些设置:

context:需要显示 sidebar 的容器的选择器

dimPage:sidebar 显示后是否对页面进行遮罩处理

onVisible:这里在 sidebar 开始显示后,取消 body 标签的 click 事件绑定,这样点击页面的任何区域后 sidebar 就不会自动隐藏了。

onShow:处理阴影效果的 z-index。

onHide:处理阴影效果的 z-index。

第二个 sidebar() 就是对侧边栏的切换操作了。

现在当点击 toggle 按钮后,点击页面其他区域 sidebar 就不会自动隐藏了。

Xamarin.Forms开发中的一些坑及解决办法

最近在学习使用Xamarin进行跨平台应用开发,遇到了不少问题,于是记录下来,方便以后回顾,并希望能够给大家带来帮助。

使用 Xamarin.Forms 首先遇到的问题是:

Unzipping failed. Please download https://dl-ssl.google.com/android/repository/android_m2repository_r22.zip and extract it to the C:\Users\用户名\AppData\Local\Xamarin\Xamarin.Android.Support.v7.MediaRouter\23.0.1.3\content directory.

你可能会看到很多航这样的问题。这个问题要解决其实很简单,首先你的电脑需要科学上网。

在成功科学上网之后,清理解决方案。

之后build,如果成功,那么恭喜你。如果不成功,检查

C:\Users\用户名\AppData\Local\Xamarin\zips

文件夹,看是否存在zip文件,存在的话清空,之后清理解决方案,然后build。一般情况下这样就可以了,如果不可以,那么我暂时也没有解决办法。

之后可能遇到的问题是:

Resource does not contain a definition for Animation

这个问题也很简单,只需要将安卓项目 Resources 文件夹下的 Resource.Designer.cs 文件从项目移除就可以了。如果依然存在问题,那么删除文件,清理解决方案,之后build,文件会自动重新生成。

剩下的问题可能就是:

Xamarin.Android.Support.v4
Xamarin.Android.Support.v7.AppCompat
......

等一系列包的问题,提示你安装包。你需要打开

工具 -> NuGet包管理器 -> 管理解决方案的NuGet程序包 -> 更新

之后更新所有可更新的包即可。

以上的问题都是 Xamarin.Forms 跨平台开发时会遇到的问题,包括PCL包和共享包,而单独开发Android程序,则不会遇到这些问题。当然更新NuGet包是必须的。

需要注意的一点是:当你更新NuGet包后,会提示你重启VS,这个时候你需要保存你的项目才能够让包正确的被更新。

【C#】List排序的方法List.Sort的使用

最近准备做一个回合制战斗的游戏,在游戏设计时,考虑到需要将所有可操作角色按照他们的速度进行排序,以来确定攻击顺序,用到了List.Sort方法,经过查看MSDN文档搞明白了怎么用,进行记录并分享。

List.Sort在默认不带参数的情况下,可以对String和Int等进行排序,而我的List中是一个类,我需要将List按照类中的Speed属性进行排序,具体方法是我们用到List.Sort 方法 (IComparer)来进行排序。

首先我们需要写一个继承自ICompare的排序函数:

/// <summary>
/// 一个针对IActItem的排序,按照Speed从大到小排序。
/// </summary>
public class SortBySpeed : IComparer<IActItem>
{
    /// <summary>
    /// 对比函数,名字不需要进行修改
    /// </summary>
    /// <param name="a">进行对比的左项</param>
    /// <param name="b">进行对比的右项</param>
    /// <returns>返回一个整形,这个整形代表左项需要移动的位置,列表顺序从左向右,-1为向左移(排在前面),1为向右移(排在后面),0为不移动</returns>
    public int Compare(IActItem a, IActItem b)
    {
        if (a == null)
        {
            if (b == null)
            {
                //如果两个都为null,则不进行排序
                return 0;
            }
            else
            {
                //a为null,b不是null,则b>a,将a向右移动1个位置
                return 1;
            }
        }
        else
        {
            if (b == null)
            {
                //b为null,a不是null,则a>b,将a向左移动1个位置
                return -1;
            }
            else
            {
                //如果a和b都不为null,则进行Speed属性对比
                if (a.Speed > b.Speed)
                {
                    //a的速度更快,排在b前面
                    return -1;
                }
                else
                {
                    //a的速度慢,则排在b后面
                    return 1;
                }
            }
        }
    }
}

之后我们只需要进行Sort调用即可:

SortBySpeed sbs = new SortBySpeed();
actList.Sort(sbs);

这样我们就完成对actList的排序,速度越大的排在越前面,按照顺序进行攻击。

更详细的使用方法可以查看MSDN文档

WordPress后台无法登录的解决办法

新买的主机,装上wordpress后,有时会出现无法登录的问题。一直没有找到原因,今天实在受不了了,分析了一下wordpress的登录代码,最终找到了解决办法。

现象:

在网址后输入 wp-admin 后,跳转到登录也,输入用户名和密码,密码正确,提交后,刷新当前页面,不进入后台(仪表盘)。

解决办法:

在博客根目录下,有一个文件 wp-login.php ,这个文件是实现登录的。在我们输入 /wp-admin 这个网址后,会默认跳到 wp-login.php 以实现登录。问题就出在这里。

用编辑器(记事本也可)打开 wp-login.php 文件,找到以下代码:

<input type="hidden" name="redirect_to" value="<?phpecho esc_attr($redirect_to);?>" />

在这行代码之前,有一行代码:

<?php } else { ?>

将其修改为:

<?php
} else {
if (!strpos($redirect_to,'index.php')){
$redirect_to = $redirect_to.'index.php';
}
?>

保存,备份原文件,将修改后的文件上传覆盖即可。

————————————————————————————————————————

以下之前在百度搜出来的解决办法,试用后无效。

登陆后台目录 打开文件/wp-includes/pluggable.php ,修改wp_set_auth_cookie函数 在pluggable.php文件找到以下代码:
setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true);
把它替换成: setcookie($auth_cookie_name, $auth_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure, true);

 

Lua中协同程序coroutine与yield用法详解

Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

而现在很多地方都会用到Lua语言,例如魔兽插件、剑网三插件、各种其他程序扩展、热更新等,所以这几天正在学习一下Lua语言,做技术储备。

而在Lua的学习过程中,大部分都很容易理解,唯独协同程序Coroutine一直理解不了。于是上网查了很多人的解释,加上测试,最终明白了其用法,分享出来,与大家交流。

本文只解释一下遇到的问题,所以你需要看过基本的Lua语法,了解基本的协程运作方式。

首先看下面的代码:

function foo (a)
    print("foo 函数输出", a)
    return coroutine.yield(2 * a) -- 返回  2*a 的值
end
 
co = coroutine.create(function (a , b)
    print("第一次协同程序执行输出", a, b) -- co-body 1 10
    local r = foo(a + 1)
     
    print("第二次协同程序执行输出", r)
    local r, s = coroutine.yield(a + b, a - b)  -- a,b的值为第一次调用协同程序时传入
     
    print("第三次协同程序执行输出", r, s)
    return b, "结束协同程序"                   -- b的值为第二次调用协同程序时传入
end)
        
print("main", coroutine.resume(co, 1, 10)) -- true, 4
print("--分割线----")
print("main", coroutine.resume(co, "r")) -- true 11 -9
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- true 10 end
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine
print("---分割线---")

在协程coroutine中,当调用coroutine.yield方法时,协程coroutine会挂起,当下一次调用coroutine时会从yeild的地方继续执行。而其中让我摸不着头脑的地方,便是resume时和yield时的参数传递了。

如果coroutine.create里的函数有参数的话,那么第一次在resume中传递的参数,便是给create中函数传递的参数。

之后会执行到return coroutine.yield(2 * a),这时需要注意:协程coroutine被挂起,print会输出协程coroutine的执行结果,而且会输出coroutine.yield(2 * a)的结果。所以第一次分割线之前的输出是这样的:

第一次协同程序执行输出	1	10
foo 函数输出	2
main	true	4

之后,虽然有local r = foo(a + 1),但foo函数中的return并没有将coroutine.yield中的参数(或者说返回给resume的执行结果)返回,所以2 * a并没有赋值给r。而赋值给r的其实是第二次调用resume时传递的参数。

在第二次调用resume时,除了co还传递了一个字符串参数"r",而这个参数将会成为foo函数的返回值,并被赋值给r。resume时可以传递多个参数进去,但之前的yield中只有一个参数,其余的参数会被忽略。如果在resume时不传递参数,而yield中有参数,那么返回值则为nil,则r为nil。在这一次的yield中有两个参数,a+b和a-b,a和b是第一次调用时传递进来的参数,所以会返回他们计算的结果。

当传递参数为"r"时,第二次分割线之前的输出是这样的:

第二次协同程序执行输出	r
main	true	11	-9

搞懂了这两次的输出,后面的也就不难理解了。

当创建协程coroutine时,默认会挂起,只有在调用resume时才会被执行,当yield时会被再次挂起。第一次传递的参数会被传入create的函数中,而之后的参数传递,都是传递给yield的。并且yield中的参数会加入到resume的返回结果。

上面代码的所有输出如下:

第一次协同程序执行输出	1	10
foo 函数输出	2
main	true	4
--分割线----
第二次协同程序执行输出	r
main	true	11	-9
---分割线---
第三次协同程序执行输出	x	y
main	true	10	结束协同程序
---分割线---
main	false	cannot resume dead coroutine
---分割线---

以上分享为个人理解,如有错误欢迎指正。希望对大家有所帮助。