UEditor扩展:添加新的支持code标签的按钮

在默认的UEditor中,是不能添加code标签的,而作为一名程序员,文章中经常会有代码段和代码字符。代码段可以使用pre标签,但代码字符使用pre就太不方便了,而且现在很多的CSS框架中都对code标签有了默认的样式定义,所以决定在UEditor中加入一个新的按钮,来给选中文字添加code标签。

首先编辑器肯定是UEditor了,我选择的是编译好的版本而非源码,因为UEditor现在基本完善了,改动也不大了,所以这样改起来方便。

需要修改的文件分别是ueditor.all.jsthemes\default\css\ueditor.css,另外需要一张code图标,你可以网上寻找,挑选自己喜欢的。

ueditor.all.js中,我们注册一个按钮:

UE.registerUI('code', function(editor, uiName) {
    var btn = new UE.ui.Button({
        name: "code",
        title: "设为代码",
        cssRules: 'background-position: center center;',
        onclick: function() {
            editor.execCommand('code');
        }
    });
    editor.addListener('selectionchange', function() {
        var state = editor.queryCommandState(uiName);
        if (state == -1) {
            btn.setDisabled(true);
            btn.setChecked(false);
        } else {
            btn.setDisabled(false);
            btn.setChecked(state);
        }
    });
    return btn;
});

上面的代码可以参考官方文档,基本需要改的就是标签名字、标题和onclick事件调用的命令。

之后我们添加code命令,因为code命令和加粗b斜体i是类似的功能,所以我们在加粗和斜体的地方添加code命令。

你可以通过搜索bolditalicsubscript等来找到下面的代码:

var basestyles = {
    'bold':['strong','b'],
    'italic':['em','i'],
    'subscript':['sub'],
    'superscript':['sup'],
    //这一行就是我们添加的code功能,注意上面一行末尾加上 " , "
    'code':['code']
}

这样我们就完成了添加一个按钮的功能,不过现在按钮显示的图标还是默认样式的,我们需要定义自己的图标,添加下面的代码到css文件:

.edui-for-code .edui-box.edui-icon.edui-default {
    background: url(../images/code.png) no-repeat transparent;
    background-size: 15px 15px;
    background-position: center center;
}

并将url中的图片地址改为你的code图片地址,建议保存在images目录下。

完成以上步骤,我们就完成了添加code按钮的功能,接下来只需要压缩jscss文件即可,你可以选择自己喜欢的工具进行压缩,并覆盖同目录下的min.jsmin.css后缀的文件。

使用Javascript进行图片或视频上传前的预览

最近在做的一个APP转H5微信网站的项目,其中有APP中批量上传图片并预览的功能,之前没有做过类似的,于是研究了一下,并总结分享。

首先推荐使用jQuery File Upload插件来处理上传事件。

首先引入jQuery、jQuery File Upload及其依赖项:

<script src="js/jquery-1.11.2.min.js" type="text/javascript"></script>
<script src="plugins/jquery.ui.widget.js"></script>
<script src="plugins/jquery.iframe-transport.js"></script>
<script src="plugins/jquery.fileupload.js"></script>

HTML内容如下:

<input class="fileinput" name="files[]" id="fileupload" type="file" multiple>
<div class="pics">
    <ul>
        <li id="pic_one" class="pic_one" style="display:none;">
            <img src="images/circle-new/tupian.png" alt="">
        </li>
        <li id="uploadicon" onclick="openFileUpload();">
            <img src="images/circle-new/zhengjia.png" alt="">
        </li>
        <div class="clearboth"></div>
    </ul>
</div>

ul列表中第一项是我们要使用的模板,默认不显示。添加图片后,我们会克隆此节点,修改图片地址,并加入列表。

第二项是我们上传图片的按钮,用来替代input标签的,不过在此示例中,我们直接使用input来上传。

$(function () {
    'use strict';
    // 服务器地址
    var url = 'server/php/';
    $('#fileupload').fileupload({
        url: url,
        dataType: 'json',
        add: function (e, data) {
            var f = data.files[0];
            var src = window.URL.createObjectURL(f);
            var node = $("#pic_one").clone(true).show();
            node.children("img").attr("src",src);
            $("#uploadicon").before(node);
        }
    }).prop('disabled', !$.support.fileInput)
        .parent().addClass($.support.fileInput ? undefined : 'disabled');
});

我们在fileupload事件中进行处理,add为当使用input选择完图片后的操作,我们先获取选择的文件,之后创建对象URL,你会得到一个blob协议的URL地址,之后便可以克隆模板节点并修改图片地址了,再之后加入ul就可以了。

我们不能使用file协议的URL地址来进行图片预览,因为移动端并不支持。

视频方面,和上面的方法是一致的,只不过视频使用的是video标签,并且当选中视频文件后,需要给video标签添加controls属性,来方便对视频进行预览。

add事件会自动识别选中的文件数量并进行遍历,这都是jQuery File Upload插件带来的便利。

上面的代码中我们只对add事件做了处理,你还可以处理上传完成done事件、上传中progress事件等。

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文档