标簽/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 .

因為 PSGI 運行 MT ,貌似服務器執行效率不再是瓶頸, so 漸漸取消了了一些為了節省資源的"優化",簡單記錄如下:

  1. 評論後博文重建的改變
    原來為了效率。我的博文頁其實有兩個。一個是博文本身,另一個是 json 格式的評論全集。 比如這個: /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 .

話說: Movable Type 用戶登錄後退出貌似是/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%2F%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%2F%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:../../js/new_mt_comments.js

記錄下來,給自己備忘。

--EOF--

[随筆]關于 JS 和 ajax 提交評論等等 ,

This is a sitelog of .

因為 本地評論 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./cgi-bin。 之所以啟用子域而不是獨立域名,是因為同域不同子域間可以天然共享 cookie ,而MT的POST必須帶有 cookie ,不然登錄信息驗證不過。

測試一下正常的POST,沒有任何問題。cookie 由于 CookieDomain 為 . ,所以cookie信息正常傳遞給了 mt. 後台。

但是接下來用 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 ""
</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個域名, easunlee.org 統統指向同一個地址。
而小站的 blog 主頁 的分頁獲取是通過 jQuery 的AJAX完成的。 見抓圖。
index_15_6_5.png

核心代碼為自寫。如下:

codefunction 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 為本站後台地址,大緻為:
/{path-to-mt}/mt-search.cgi?IncludeBlogs=2&archive_type=Index&template_id={main_index_tmp_id}&page={num}

加上format=js參數則為JSON結構, 返回的數據大緻為

code{"error":null,"result":{"next_url":"下一頁的地址","content":"本頁展示數據"}}

如果出錯,則在本頁面打開沒有 format=js 參數的完整 HTML 版本。

但是,這個腳本還是有問題的。

如果以域名 /blog/ 訪問,則毫無問題, 一旦用 http://easunlee.org/blog/ 則基本上不能完成。 不用說後期路楊打算給後台設置不同的子域名。
原因很簡單: ajax 不能跨域。(當然某些BT 的 ie 版本正常跨域,汗。)

有沒有辦法解決這個問題呢?

研究了一番,發現使用 jQuery 的 JSONP 方式即可完成。
即讓後台返回的數據為

codemycallback( {"error":null,"result":{"next_url":"下一頁的地址","content":"本頁展示數據"}} );

當然需要修改核心代碼,讓 $.ajax 工作在 JSONP 下:

codefunction 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("/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 .
大家都知道, 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方式調用的。。。