标签/Tag为[js]的文章

简单的编辑器闭包

闲暇无聊,简单的把原来BBS的的编辑器进行了闭包处理。和原来的功能没有啥区别,仅仅视简单的 UBB支持和ajax 上传。 纯粹算是 字的 N 种写法。

记录下来,以免忘记,其中 editer 的 ID 为 document.FORM.inpost

代码如下:

[SiteLog]新风格启用和 pjax 的再次使用

因为大屏幕的普及和数年没有更新界面,这次决定重新设计一个比较现代的风格。
Movable Type 的小众化导致想要的风格并不多,虽然,官方设计了比较人性化的换风格模式。但是禁不起风格稀少。。。。

本人对配色、审美啥的并不擅长,找了一圈,决定参考 屈光宇(JerryQu) 的网站风格进行移植,再次鸣谢 QuQu

修改风格其主要体现在以下:

  1. 布局由上下变成左右。
  2. 对于1024以下分辨率彻底移除 sidebar。
  3. 对于 sidebar,仅在主页、归档页、Tag页面显示,其他页面均为2栏。

其实,目的主要是适配1024以上大屏。 MT的框架还是不错的,换主题仅简单换了 css 和局部细小修改。。

评论模式的小小改变和JS重写 ,,

This is a sitelog of Easun.org.

因为 PSGI 运行 MT ,貌似服务器执行效率不再是瓶颈, so 渐渐取消了了一些为了节省资源的"优化",简单记录如下:

  1. 评论后博文重建的改变
    原来为了效率。我的博文页其实有两个。一个是博文本身,另一个是 json 格式的评论全集。 比如这个: http://easun.org/blog/archives/json/311.json。 当每次有新的评论发表时候,我的原设计是并不刷新本页,只是重载 json 罢了。 通过自写的 JSjson 中的所有评论更新一遍。 而且每个页面的评论也都加入了"刷新" 和"重载"两个按钮。 其中"刷新"的含义是重载 json 文件, "重载"则从数据库重载。 抓图如下:
    旧模式评论
    而现在,考虑再三, 取消了 json 格式的博文页, 减少一次服务器写文件的次数? 同理,改写了 JS,移除了在加载文件同时加载 json 文件。 当然,保留了从数据库直接重载评论的设计。 顺便改了一下 "重载" 的 UI,让它更 醒目 一点 (也许是更*丑陋*了一点。哈哈),抓图如下:
    新模式评论

增加 GitHub 账号登陆 Movable Type 及全站搜索页面恢复 ,

又是愚人节,只是这个愚人节需要上班, 但愿通知大家上班的信息不要当作愚人节信息而忽略,这样的话估计就欲哭无泪了。呵呵 :D

Blog 自从复活以来,一直修修补补,说说最近的一些变化吧:) 简单如下:

Movable Type 和 JS 删除 cookie 操作的弯路 ,

This is a sitelog of Easun.org.

话说: Movable Type 用户登录后退出貌似是http://easun.org/path_to_mt/mt.cp?__mode=logout&...

然后 302 回到当前页面。

这个过程究竟是干什么呢? 首先清理掉了 Session,这个是必须服务器支持的。

那么问题来了, 能不能不 302 ,直接我用 ajax 访问 上面的那个链接 OK ? 测试了一下。貌似 js 清除的 cookie 的值 mt_blog_user 为只是前台使用的。 后台使用还有 "mt_commenter","commenter_name","commenter_id" 这三个 cookie。 而 302 回原来界面的时候会清除这些 cookie.

知道了答案,于是开始修改,逻辑很清楚,ajax 访问上面的链接,清除服务器Session,然后自己写JS,清除这些 cookie,不就和原来逻辑一样了吗? 这样,点"退出"的时候页面不会跳转,会友好的多。

修改如下:

  1. 增加 clear_login_cookie 函数:如下

    javascriptfunction clear_login_cookie() {
    var name_array = ["mt_commenter","commenter_name","commenter_id"];
    var i = name_array.length;
    while (i--) {
    var name= name_array[i];
    mtDeleteCookie(name,mtCookiePath, mtCookieDomain,
    location.protocol == 'https:');
    }
    }
    ```
    
  2. 修改 mtSignOut 函数。
    定位 location.href = url; 修改为:

    code//location.href = url;
    clear_login_cookie();
    $.get(url, {ajax:'1'});
    mtFireEvent('usersignin');
    

    以为万事大吉,结果,运行之,发现虽然显示退出了, 但是mt_commenter","commenter_name","commenter_id 三个 cookie 并没有清理掉???

多处 Debug 无果, 最后又回归到了原来的模式,仔细研究了一下直接访问 302cookie 设定:

mt_commenter=; path=/; expires=Fri, 25-Sep-2015 02:02:10 GMT

commenter_name=; path=/; expires=Fri, 25-Sep-2015 02:02:10 GMT

commenter_id=; path=/; expires=Fri, 25-Sep-2015 02:02:10 GMT

呃,貌似根本没有 CookieDomain 设定。。。。 根本原因在于:

JS如果要删除(重新设置)某个 cookie ,必须知道原来设置的 pathdomain,不然会认为是完全不同的两个 cookie , 而悲催的事情是 js 无法获知原来设置的 cookie 的 pathdomain的。

原因知道了,只好硬编码了。幸好 mtCookiePath 定义的本身就是 /,回到 function clear_login_cookie(),重写如下:

code <!--lang:javascript-->
function clear_login_cookie() {
var name_array = ["mt_commenter","commenter_name","commenter_id"];
var i = name_array.length;
while (i--) {
var name= name_array[i];
mtDeleteCookie(name,mtCookiePath);
}
}

再次测试,一切 OK 。 但是弯路浪费了我 N 长时间。 记下来供同好者鉴。

吐槽一下: 为什么 Movable Type 设定这些 cookie 要和 公开的 cookie (mt_blog_user) 设定不同的 pathdomain 呢? 费解。

--EOF--

[JS随笔]网站评论、显示界面细微调整和杂谈 ,,

随笔写下一些东西,作为 SiteLog 和备忘。

都是一些评论、显示界面的调整,一个意图:用户体验。 说的不好听的就是"路杨的强迫症又犯了",反正是折腾无极限。。

这两个月, 整个 Blog 的 js 估计被我修改过不下10次,有些是纯粹为了闭包,有些是为了美观和清晰流程。。。

简单记下曾经的修改吧。

先说前端:

  1. ajax提交优化。 所有流程彻底闭包为一个函数,和 json 显示本地评论互动,增加了提交成功后如果通过审查的话,动态加载新评论及动画,并同时重置评论提交表单。
  2. 多说评论界面优化。 绑定了原来系统的显示/隐藏评论、 显示/隐藏评论框的函数,让原来界面的操作同时操作两个系统的界面。 在 SOTHINK提示下,虽然依然设置多说评论框为默认,但是登录本地系统(包括QQ等本地系统支持的社交帐号)的朋友则显示"本地评论系统评论框"。 代码片段为:

    codevar check_mt_user = function(u) {
    if(typeof duoshuoQuery.is_ds_hide =='undefined') {
    if (!u) u = w.mtGetUser();
    if (u && u.is_authenticated) { duoshuoQuery.is_ds_hide=true;}
    else duoshuoQuery.is_ds_hide=false;
    }
    };
    
  3. 本地json评论界面优化。 彻底完成本地评论js的闭包。进一步和多说评论界面糅合, 增加了刷新重载 两个操作界面,前者从本地文本静态json cache中重新获取本地评论,后者读取 MySQL 库实时获取本地评论。

  4. 延迟加载图片重写。 也完成了一次JS闭包。 美化了延迟加载图片时候占位的动画,因为目前本站仅在评论者头像上使用延迟加载图片技术,也许大家并不能彻底体验到界面的加载过程(因为加载的太快了)。。。

上面的所有修改,均可以查看本站现有 JS 来获得代码。 本站的 JS 并无加密 :P

再说后台:

  1. 彻底解决了QQ头像、Gravatar 头像显示问题。 并缓存Gravatar 头像到本地。 不同原来的做法。这次写 插件,直接 hook 了 MT::Author::userpic_url 。 比较极端的做法。 代码如下:

    codeour($old);
    {
    no warnings 'redefine';
    no strict 'refs';
    require MT::Author;
    If ($old = MT::Author->can('userpic_url')) {
    *MT::Author::userpic_url = sub{
    my ($author) = @_;
    if ( ($author->auth_type =~ m/^QQ/ ) && $author->hint && ($author->hint=~ m!^https?://!) ) { return $author->hint. '#QQ' ;}
    my ($oldurl) = $old->(@_);
    return $oldurl if ($oldurl);
    my $email = $author->email;
    return &_hdlr_gravatar_url_mail($email);
    };
    }
    }
    
  2. 更换了后台插入图片后的显示,适应 HTML5。 这个没有写插件,直接Hacklib/MT/Asset/Image.pm 中的 can_html 。 更加的简单粗暴。 代码片段如下:

    code$text = sprintf(
    '<figure class="post-image"><img title="%s" src="%s" %s %s /></figure>',
    MT::Util::encode_html( $asset->label ),
    MT::Util::encode_html( $asset->url ),
    undef,undef,
    );
    

要查看详细的修改文件,可以移步到我的 GitHub

其他:

话说,多说 服务器维护了。 貌似以为会好一点,结果似乎结果一样? 另外,多说评论加载不出来时候,下面的加载动画一直显示的时候, 这个时候刷新就OK了,觉很奇怪, 查看了一下 log。 结果,100% 的在出现这个状态的时候,浏览器报错:

17:24:55.691 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://easun.duoshuo.com/api/threads/listPosts.json?thread_key=301&author_key=1&url=http%3A%2F%2Feasun.org%2Fblog%2Farchives%2Fgodaddy_cpanel_perl_dbdmysql.html&title=Godaddy%20cPanel%20%E4%B8%BB%E6%9C%BA%E5%92%8C%20Perl%E6%A8%A1%E5%9D%97%20DBD%3Amysql&require=site%2Cvisitor%2Cnonce%2Clang%2Cunread%2Clog%2CextraCss&site_ims=1442293934&lang_ims=1442293934&referer=http%3A%2F%2Feasun.org%2Fblog%2F&v=15.4.27. (Reason: CORS header 'Access-Control-Allow-Origin' missing).1

干啥子嘛~~
明显的服务器响应问题。。。
判断跨域的服务端脚本的得到没有执行。。
其实listPosts.json 返回数据了,可惜被浏览器拒绝了。 难怪不显示。。。。。。
话说,抛开 服务器 判断跨域的服务端脚本的问题。 listPosts.json 难道一定要用 JSON 模式? 又不是 POST, GET 而已,换成 JSONP 模式不就万事大吉了,而且也能节省服务器的判断跨域,输出 Access-Control-Allow-Origin header。。。。。。

另外,服务器维护了, 貌似脚本的版本还是 2015-04-27 。。。。

--EOF--

[JS] 静态输出的评论也显示UA ,

就像本站的本地评论一样。 虽然,本地评论我修改了后台程序,一样存储了评论者 Useragent 。但是除非 JS 方式显示。 不然默认是不会显示的。

原因很简单。 本站解析 UA 是用的这个JS库,而非后台的 Perl 程序。 而本站的本地评论现在显示是动静结合的。 简单的说,每篇文章都是一个静态的HTML页面,定期更新评论在这个页面上。同时JS载入评论,进行判断是否写入静态页面并动态更新之。 显然静态页面解析不可能对 Useragent 字符串进行处理。 而路杨并不像完全对静态评论进行JS替换。。 复杂的的办法就是在后台用 Perl 再写一个解析 UA 的程序出来作为静态HTML的 UA 解析输出。但是 UA 的构造太杂乱了。。。。

今天想了想,其实很简单,还是前段解决吧。 一个 JQ each搞定。 代码如下:

code$("span[rel='ua']").each(function(){
if ( $(this).hasClass("done") ) return;
var $el = $(this).closest(".comment");
var _id= $el.attr("data-comment-id");
$(this).replaceWith(tt.show_ua_by_id(_id))
// $(this).html( tt.show_ua_by_id(_id) ).addClass("done").removeAttr("rel");
});

tt.show_ua_by_id() 代码片段如下:

codeshow_ua_by_id: function(idx){
var s = json_data.comments[idx];
if (!s) return '';
if (s.agent) return tt.show_ua(s.agent);
return '';
},

而静态网页在要显示 UA 的位置加入 <span rel="ua"></span> 就一切OK了。

上面的 JS 都是片段, 完整可以查看本站 评论JS:http://static.easunlee.cn/js/new_mt_comments.js

记录下来,给自己备忘。

--EOF--

[随笔]关于 JS 和 ajax 提交评论等等 ,

This is a sitelog of Easun.org.

因为 本地评论 JS 化,又重写了一遍 MTajax 提交过程。梳理了一下流程。

主要是删除了 MT 提交过程的 2次服务器认证,把第一次服务器认证(登录信息预提交验证) mtCommentSessionVerify 有限度地交给 JS + cookie

简单的说,就是设置全局变量 usernull,然后重新在 cookie 中读取 user 来判断登录信息是否正常? 然后其他的认证在 提交表格 时完成就好。 简单 JS 片段如下:

code var refresh_user = function(u) {
if (u) mtSetUser(u);
if (!u) { user = null; mtFireEvent('usersignin'); u = mtGetUser(); }
if ( u && u.is_authenticated ) { /* do nothing*/ }
else { $f.find(':input[name="sid"]').attr("value","") ; ShowCommentsOpenData(); }
};

然后发现 JQ $.ajax 的小问题:

我的 $.ajax 如下:

code$.ajax({
type: 'POST',
cache:false,
url: url,
context: el,
xhrFields: { withCredentials: true },
data: $f.serialize(),
success: successfuc,
beforeSend:beforefun,
error: errorfun,
complete:completefuc
});

本来是吧 refresh_user 写到 beforeSend 中的,但是执行的时候发现 refresh_user 中对 $f 的改变,并没有在 data: $f.serialize() 中 体现出来。 所以只好显式在 $.ajax 前调用此函数了。

笔记下来,为自己提醒。

另外,本来对 JS 全面进行 JQ 改写来着,但是实际对 form 元素操作中发现,同样对

code<form name="comments_form" id="comments-form">
<input type="hidden" name="preview" value="" />
...
</form>

中 的 name="preview"value 操作。 原来的代码是

codevar f = document['comments_form'];
if (f.preview.value == '') f.preview.value = '1';

JQ 呢? 貌似。。。。。

codevar $f = $("#comments-form");
var $preview= $f.find(':input[name="preview"]');
if ($preview.attr("value") == '') $preview.attr("value","1");

f$f 是为了方便操作预先定义好的。 貌似还是不用 JQ 操作的快一点。或者就现在这样混合用吧。。。。

另外,给 ajax 提交完成后刷新新评论搞了一段简单的 JQ 特效: 代码如下:

code var animate_item = function(id) {
var $el =$("#comments-content .comment#comment-"+id);
var _top = $el.offset().top - ( $(window).height() - $el.height() )/2;
$("html,body").animate({scrollTop:_top},1000);
$el.addClass("notice")
.animate({left:'30px',opacity:'0.2'},"slow")
.animate({left:'0px',right:'30px',opacity:'0.8'},"slow")
.animate({left:'0px',right:'0px',top:'30px',opacity:'0.2'},"slow")
.animate({left:'0px',right:'0px',top:'0px',bottom:'30px',opacity:'0.8'},"slow")
.animate({left:'0px',right:'0px',top:'0px',bottom:'0px',opacity:'1'},"slow");
var total= parseInt( $("#comments").attr("data-total"));
function c() { $el.removeClass("notice").addClass( (total%2) ? "odd":"even" ); }
$el.one('click',c).one('mouseover',c);
};

没有抓 gif ,简单完成效果如下:

jq_submit_png.png

--EOF--

[SiteLog]近日网站折腾小记 ,

8月快过去了。时间真的是。。。。
顺便记下这几天对网站的一些小小的折腾吧。

1. 多说评论显示逻辑调整:

还是要从多说说起: 路杨已经基本上实现了把所有的多说评论同步到了本地。 默认同步到多说评论处于未发布状态,防止和多说JS载入的评论形成重复评论。 定时把本地数据库的多说评论转成发布状态,以防止多说服务器抽风导致评论不显示。

但是问题来了: 怎么让同步并本地发布的同一条评论只显示一次呢? 原来的实现办法是在 多说JS 中识别这条评论是否已经本地发布,如果发布则 hook 多说JStemplates.post 函数,让它不生成这条评论
核心代码如下:

codevar DSinMTids = [];
function check_ds_in_mts() {
DSinMTids = [];
$("#comments-content div.ds-post-self").each(function()
{
if ( ( $(this).attr("data-source") == 'duoshuo' ))
{
DSinMTids.push($(this).attr("data-post-id"));
}
});
}
check_ds_in_mts();
var _D_post=DUOSHUO.templates.post;
DUOSHUO.templates.post=function (e,t){
var rs=_D_post(e,t);
if ( $.inArray(e.post.post_id, DSinMTids) != -1 return '';
/* sth others*/
return rs;
}

网站启用ajax无刷新技术(pjax)和多说的一些小技巧 ,

先说ajax无刷新技术吧
因为 Godaddy 空间中资源和国内访问速度的原因,能节省一点资源就节省一点资源吧。虽然对于传统的 ajax 来说,更新版的 pjax 可以同时写入浏览器历史( pushState )和动态更换 url 显示,但是对于我来说,貌似还有一下不足:

  1. 浏览器缓存(内存)不会释放,会让老爷机的朋友感觉到机器卡。
  2. 不利于SEO(当然比 ajax 已经很好了)。 pjax 再先进也只更新某个容器,对于 head 内的一些 meta 是不会处理的,强迫症的伤不起啊。
  3. url 虽然写进了浏览器历史( pushState ),但是在 FireFox 下用 Backspace 返回时候。很多时间只是浏览器的url变了,但是内容还需要再次刷新。

好处也就不说了。减小重复资源的http请求
言归正传,简单说说本站是怎么启用这个吧:
直接用了 defunkt/jquery-pjax 这位大神的成熟方案。对本站的链接(a)做了处理。 代码如下:

code$.getScript("http://Path/to//js/jquery.pjax.js", function() { $(function() { easun_pjax(); }); });

其中 easun_pjax(); 为核心函数。 简单如下:

codefunction easun_pjax()
{
$(document).pjax('a[target!=_blank]', '#content', {fragment:'#content', timeout:6000});
$(document).on('pjax:send', function() {
$('#content').fadeTo(700,0.0);
});
$(document).on('pjax:complete', function() { $('#content').fadeTo(700,1); });
}

这样基本完成, 如果一些需要在替换#content(<div id="content">...<div>)的内容需要 js 实现的。请在pjax:complete中(上面有示例)中重新运行一次。

成功后实例可以参见本站的各博文之间的切换。

再说多说的一些小技巧吧

用多说一段时间了。乱七八糟的改了一起。多说的自定义其实还很强的,只是官方似乎不是很重视这些小技巧? (官方现在都长草了)

  • 彻底自定义CSS。
    不是官方说的在某些位置加入CSS,而是彻底把多说的CSS 放在自己的网站。 其实很简单。就是定义duoshuoQuery.theme= 'none' 即可。
    再说的清楚点就是这样定义duoshuoQuery:
    var duoshuoQuery = { short_name: "YOURKEY", theme:'none'};

这样,多说就不会加载任何 CSS ,变成了一张白纸,自己享受重头定义本地 CSS 的乐趣吧。

  • 让评论加载不在颤抖。
    大家也许都注意到,有时间加载多说的评论会先从没有任何 CSS 样式再切换到有CSS样式。
    原来以为是 CSS 没有及时加载进来。 后来一看官方的 CSS 才知道。 CSS 根本没有定义 .ds-thread(class="ds-thread")而只定义了#ds-thread(id="ds-thread")。
    而多说的机制是找到.ds-thread 并以其做为容器加载评论文章,最后再给这个容器加上id(#ds-thread)。
    奇怪的逻辑~~ 为什么不直接以 ID 操作呢? 多说自己的不自信?
    知道原因了,让评论加载不颤抖也就很简单,把加载评论的 <div class="ds-thread" ...> 提前改成 <div class="ds-thread" id="ds-thread" ...> 就可以了。 或者,你也可以按照彻底定义CSS的办法重新对 .ds-thread 做 CSS定义。

  • pjax 动态加载 评论。
    其实也就是上面的问题的延伸。 在pjax:complete中加载即可。 代码为

    if ($('.ds-thread').length > 0) { if (typeof DUOSHUO !== 'undefined') DUOSHUO.EmbedThread('.ds-thread'); else $.getScript("//static.duoshuo.com/embed.js"); }

完整代码如下:

code$(document).on('pjax:complete', function() { $('#content').fadeTo(700,1);
if ( $('.ds-thread').length > 0 ) {
if (typeof DUOSHUO !== 'undefined') DUOSHUO.EmbedThread('.ds-thread');
else $.getScript("//static.duoshuo.com/embed.js");
}
});
}

--EOF--

[SiteLog]JQ AJAX 跨子域Post再总结 ,

为了配合 CDN 前台。 后台的域名改成了 mt.easun.org/cgi-bin。 之所以启用子域而不是独立域名,是因为同域不同子域间可以天然共享 cookie ,而MT的POST必须带有 cookie ,不然登录信息验证不过。

测试一下正常的POST,没有任何问题。cookie 由于 CookieDomain 为 .easun.org ,所以cookie信息正常传递给了 mt.easun.org 后台。

但是接下来用 JQ $.post 进行 AJAX POST 的时候,就出现跨域问题了。 如果是Get,很简单,可以参考我上篇( [JQ+Perl]JQ AJAX跨域请求HTML/JS页面内容总结 )解决之。 POST 就必须设置跨域请求了。

不想回归 iframe 。幸好服务器部分配置可以自己控制。在后台脚本目录建立 .htaccess,内容如下:

code<IfModule mod_headers.c>
Header set Access-Control-Allow-Credentials: true
Header set Access-Control-Allow-Origin "http://easun.org"
</IfModule>

这下应该可以 $.post 了吧?

但是结果依然很悲哀,这次 POST 成功, 但是 JQ 并不传递 Cookie。导致身份认证出错。 Google之。发现跨域(包括子域), 如果要传递Cookie, JQ AJAX 还需要手动发送认证凭证,设置 withCredentials ,这样才会传递 Cookie.

根据这些信息。 重写 $.post$.ajax 模式,代码如下:

code$.ajax({
type: 'POST',
cache:false,
url: url,
data: $("#comments-form").serialize(),
success: function(data){
if (f.preview.value =='1' ) { EasunisPreReturn(data);}
else {EasunisPostReturn(JSON.parse(data));}
},
xhrFields: { withCredentials: true },
});
return false;

调试之,一切OK。

参考资料:

1.【前端笔记】使用ajax跨域withCredentials的作用

后记:

对于IE8,9 来说。JQ AJAX 跨子域Post 即使设置了上述也会失败。原因很奇葩,跨域提交需要使用 XDomainRequest 对象。

幸好有 JQ 插件 jQuery-ajaxTransport-XDomainRequest 可以解决。 在 $.ajax 前引入:

code<!--[if lte IE 9]>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js"></script>
<![endif]-->

同时,为了兼容出错信息,当$.ajax 失败的时候,设定正常方式POST。虽然这样界面乱了,但是保证功能正常。

codeerror: function(){ f.submit(); }

--EOF--

[JQ+Perl]JQ AJAX跨域请求HTML/JS页面内容总结 ,

路杨有2个域名,[easun.org](http://easun.org) [easunlee.org](http://easunlee.org) 统统指向同一个地址。
而小站的 [blog 主页](http://easun.org/blog) 的分页获取是通过 [jQuery](http://jquery.com/) 的AJAX完成的。 见抓图。 index_15_6_5.png ###核心代码为自写。如下: function ajax_get (url, mode,callback) { var sdiv = $("#search-results"); if (!sdiv) return true; $.ajax({ url:url, data: {'format':'js'}, success: function(data){ if ( data.error == null ){ if (mode == 'append') sdiv.append(data.result.content); else sdiv.html(data.result.content); if (data.result.next_url) { next_url = data.result.next_url; } else { $('#show-more').hide(); } return false; }else { location.href = url;return true;} }, error:function(req, status, obj){ location.href = url; return true;}, beforeSend: function(xh){ /*do sth before send*/ }, complete: function(xh){ /*do sth for complete*/ } , }); } 其中url 为本站后台地址,大致为: `http://easun.org/{path-to-mt}/mt-search.cgi?IncludeBlogs=2&archive_type=Index&template_id={main_index_tmp_id}&page={num}` 加上`format=js`参数则为JSON结构, 返回的数据大致为 {"error":null,"result":{"next_url":"下一页的地址","content":"本页展示数据"}} 如果出错,则在本页面打开没有 `format=js` 参数的完整 HTML 版本。 ## 但是,这个脚本还是有问题的。 如果以域名 访问,则毫无问题, 一旦用 则基本上不能完成。 不用说后期路杨打算给后台设置不同的子域名。 原因很简单: **ajax 不能跨域**。(当然某些BT 的 ie 版本正常跨域,汗。) ###有没有办法解决这个问题呢? 研究了一番,发现使用 [jQuery](http://jquery.com/) 的 JSONP 方式即可完成。 即让后台返回的数据为 mycallback( {"error":null,"result":{"next_url":"下一页的地址","content":"本页展示数据"}} ); ###当然需要修改核心代码,让 $.ajax 工作在 JSONP 下: function ajax_get (url, mode,callback) { var sdiv = $("#search-results"); if (!sdiv) return true; $.ajax({ url:url, data: {'format':'js'}, dataType: "jsonp", /*定义dataType*/ jsonpCallback:"mycallback", /*定义jsop 回调函数*/ success: function(data){ if ( data.error == null ){ if (mode == 'append') sdiv.append(data.result.content); else sdiv.html(data.result.content); if (data.result.next_url) { next_url = data.result.next_url; } else { $('#show-more').hide(); } return false; }else { location.href = url;return true;} }, error:function(req, status, obj){ location.href = url; return true;}, beforeSend: function(xh){ /*do sth before send*/ }, complete: function(xh){ /*do sth for complete*/ } , }); } 不用担心返回的 JSONP 数据在 `success: function(data)` 中无法解析,只要定义了 `dataType: "jsonp",jsonpCallback:"mycallback",` 则 `success: function(data)`中的 data 自动为 JSONP 中包含的 JSON数据。 而不是 JSONP 数据串。 现在的问题,是后台的 mt-search.cgi 不具备输出 JSONP 格式的能力, `format=js` 只能输出 JSON 格式,这个时候如果不想修改 mt 代码。则只能通过自己写的脚本(Perl)来中转了。

[多说]不本地化embed.js使多说评论显示UA ,

title.jpg

个性化 多说显示,让多说显示评论者的 UA,貌似教程很多。


比如: 我的那些事 - 多说回复后显示浏览器及操作系统信息(Useragent) 这里。


但是方案都是 本地化 embed.js 然后修改 embed.js 完成。

不想本地化 embed.js ,搜索了一下网络, 发现有不本地化 用 JS Hook 方式修改的办法,见
https://github.com/huhuime/make_duoshuo_show_ua

但是,根据这个修改后无效, 检测了多说的 embed.js 代码,发现是因为版本更新导致变量失效,修改 e.agent 为e.post.agent 即可。

简单整理如下。

在 多说 自己的 JS 导入后面的任意位置添加以下代码:

<script src="您的网站地址/ua-parser.min.js"></script>

<script type="text/javascript">
    if (typeof DUOSHUO !== 'undefined')hookDUOSHUO_tp();
    else $('[src="http://static.duoshuo.com/embed.js"]')[0].onload=hookDUOSHUO_tp;
    function hookDUOSHUO_tp(){
        var _D_post=DUOSHUO.templates.post
        DUOSHUO.templates.post=function (e,t){
            var rs=_D_post(e,t);
            var agent=e.post.agent;
            if(agent&&/^Mozilla/.test(agent))rs=rs.replace(/<\/div><p>/,show_ua(agent)+'</div><p>');
            return rs;
        }
    }
    function show_ua(string){
        console.log(string)
        $.ua.set(string);
        var sua=$.ua;
        if(sua.os.version=='x86_64')sua.os.version='x64';
        return '<span class="this_ua platform '+sua.os.name+'">'+sua.os.name+' '+sua.os.version+'</span><span class="this_ua browser '+sua.browser.name+'">'+sua.browser.name+'|'+sua.browser.version+'</span>';
    }
    </script>

[MT Hack]修改模板来完成MT的AJAX提交评论 ,

曾经,本站在MT3时代,曾经写过以AJAX提交评论预览 的帖子。

那个也是通过修改模板+自写js实现,没有对MT的源代码进行任何修改,绿色无污染,不影响升级。

后来,通过自己摸索,也实现了 ajax 方式提交评论。但是一直都没有写出教程,今天有点时间。特意写出分享之。

具体效果见本站评论提交(预览和发表)。

言归正传,要实现 ajax 方式首先要定义一系列 js 函数。 由于 本站已经迁移到了 JQuery 平台,所以在改写 mt.js 需要先加入 JQ 支持,即加入:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

[SiteLog]一则js错误寻找和 jQuery ,

本站的图片显示一直使用 LightBox
最近升级,才发现 LightBox悄悄迁移到了 jQuery 平台。
笑ing, jQuery 貌似越来越份额多了。

想到既然是要导入 jQuery ,干脆把自己的一些 js 也用 jQuery 重写一下,尤其是 ajax 方式提交评论的代码。
于是,打开 mt.js ,看见了大量的

var f = document['comments_form'];

于是就想当然了。把原来的代码改成
$.post("http://easun.org/path/to/mt-cms.cgi",
$.param($("#comments_form").serializeArray())
).success(function(data) {
if (f.preview.value =='1' ) { EasunisPreReturn(data);}
else {EasunisPostReturn(JSON.parse(data));}
}) ;

结果运行不能正常获取返回值,百思不的其解。
最后,打开 模板的 form 部分。发现 代码如下
<form ... name="comments_form" id="comments-form" ... >

我倒~, id 根本就不对。难怪出错。
回到 mt.js 改成
$("#comments-form")

运行,一切OK。

笔记之,给自己再次修改提个醒。

--EOF--

[MT 模板]MT 4.x/5.x 之Search Results 官方默认版本的两处小错误。 ,

This is a SiteLog for Easun.org.
大家都知道, MT 4.x/5.x 的搜索所有返回多页的时候,翻页(仅仅是 PreviousNext 链接)其实是支持 ajax 的,但是实际使用中,翻页结果往往是直接跳出页面,而非ajax获取。

今天抽空看了看 系统模板中的 【Search Results】 模板代码,发现貌似有两处错误,这个应该是导致 ajax 方式经常意外跳出的原因。特意发出来,以供同好者分享。

第一处是 <div id="search-results">...</div> 的反复嵌套,看 js 来看, 是通过给<div id="search-results"></div> 块中插入新内容来更新页面的,但是 ajax 返回的数据居然还有一个 <div id="search-results">? 显然是模板错误,JS返回的模板不应该再用 <div id="search-results"> 块定义。具体抓图如下:
20120220_2.png
知道原因了,解决办法很简单: 删除图中 <mt:SetVarTemplate id="search_results" name="search_results">...</mt:SetVarTemplate>中嵌套的 <div id="search-results"> (图中69行)和 最后一个 </div> (88 行),然后找到 <$mt:Var name="search_results"$>,改成

<div id="search-results"><$mt:Var name="search_results"$></div>


第2处,是 加载完本页后,自动1000 毫秒后获取下一页数据的 js 程序有错,代码为下:
var timer = window.setTimeout("getResults(" + <$mt:CurrentPage$> + ")", 1*1000);

抓图:

20120220_1.png

呃, + <$mt:CurrentPage$> + ,官方真以为 <$mt:CurrentPage$> 是js变量啊。还 + 呢。修改成:

var timer = window.setTimeout("getResults(<$mt:CurrentPage$> )", 1*1000);

修改完后,直接搜索一个返回好多页的文件,略微等待(等待后台获取下一页数据成功),点击 Next, OK ,成功了。
因为每页默认有20个条目返回,所以如果真正的搜素者,当看完这20个的时候,点 Next 的时候,次页数据早以后台传输完成,则直接 通过 js 显示,一般不会出现因为没有数据而跳出成普通模式的问题。

PS: MT 搜索模板的 ajax 机制是载于当前页后, 设定一个定时器,后台获取下一页数据存储于js 数组,当 Next 或者 Previous 的时候,直接从 js 数据中提取,如果提取失败,则会直接跳出,以普通模式向后台获取数据。 所以,只有 PreviousNext 链接 是 ajax 的 。

--EOF--

IE脚本错误,可以尝试以下办法

IE 脚本错误是个很麻烦的问题,一般定位都是 JS 引擎 和 VB 引擎出错。但是有时间反复注册 jscript.dll 和 vbscript.dll 也不能解决问题。具体表现 部分 js 解析正常,而部分就不行,尤其是基于 Web2.0的网站。
不说别的,就连 ie7/ie8 本身第一次运行向导的"保存设置"也出错。
其实研究下,貌似都出现在 XML 解释上?
重新注册 msxml3.dll 一般都能解决问题。

特意归纳下通用解决办法:
依次注册以下dll:
regsvr32 jscript.dll
regsvr32 vbscript.dll
regsvr32 actxprxy.dll
regsvr32 shdocvw.dll
regsvr32 msxml3.dll

如果还不能解决, 尝试重新安装MSXML。地址在:http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=993c0bcf-3bcf-4009-be21-27e85e1857b1
安装完后可以继续尝试注册 regsvr32 msxml3.dll

PS: 最近单位电脑出现大量的类似症状,都是这样解决问题的。原因初步定位为单位使用的某杀软的所谓系统加固 错误的拦截了 Windows update 对 MSXML3更新时候的注册表修改导致。。。。。

--EOF--

[MT Plugin]LightBox for MTOS

这也许是喜欢使用 LightBox 的朋友福音,尤其喜欢发布图片类文章的 MT 4.x 用户们:)

插件地址在这里: http://mixelandia.com/2008/09/lightbox-para-mtos-mi-primer-plugin.php

简单的插件,作用很简单:
1。自动生成 LightBox JS 模版 和 css 模版。
2。在上传文件的时候,自动加入 rel="lightbox" 标签。

注意:
1. 本插件的 js 和 css 是生成两个 Index Templates ,目标在你的Blog发布目录下,你可以手动修改地址:)
2. 从代码来看,这个插件(Plugin) 应该只支持 MT 4.0 + 。
3. 部分JS是远程引用 Google 网站,也许会拖慢速度,你可以手动修改代码把JS脚本下载到本地。

==
BTW: 本插件貌似不需要什么演示,因为本Blog已经启用了,效果可以看本站有图片存在的文章的效果 :D

--EOF--

[重发旧文]论坛开发和HTML/JS兼容

整理硬盘,删除掉些东西。干脆重发到BBS上作为备份。

标题: [讨论]关于论坛开发的几点建议。
近来研究HTML和js语法。对leo程序的HTML语法和js代码有点小小的看法。
1,尽量少用只有ie支持的HTML扩展HTML代码。。
leobbsx现在的forums.cgi上面的介绍就用了非正规的HTML代码。使在NS和Mozilla下界面难看的厉害。。。
2。JS要操作<div> 和<span> 的内容。。请使用符合CSS2+HTML3标准的DOM接口。现在的forums.cgi展开帖子(就是哪个+号)和帖子里广告和虚拟形象和COOL字体转化都采用了all.name方式的调用。但是all方式只有ie支持。。所以在非ie下这个都不能显示。。。。
正确的应该用document.getElementById方式调用的。。。