标簽/Tag為[jQuery]的文章

簡單的編輯器閉包

閑暇無聊,簡單的把原來BBS的的編輯器進行了閉包處理。和原來的功能沒有啥區别,僅僅視簡單的 UBB支持和ajax 上傳。 純粹算是 字的 N 種寫法。

記錄下來,以免忘記,其中 editer 的 ID 為 document.FORM.inpost

代碼如下:

[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]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)來中轉了。

[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]網站改版和移動訪問優化

This is a SiteLog for 。

這也是3年以來第一次改版。 目标很單純, 抛棄 XHTML ,改投 HTML5

耗時一周,代碼基本上都是自己在改。 網站結構全部重構,但是盡量通過 CSS 讓大家感覺不出來界面有大的調整 :)

主要改動如下:

  1. 結構重寫,CSS也全部推翻重寫。 用 HTML5 的 header section nav article aside footer 等新标簽替換掉了原模闆中大量的 div 标簽。讓他顯的有意思,并大量删除了自帶模闆中多重嵌套的div。這樣一來大大的減少了網頁的容積 :P 評論框仿照 扶凱 大俠的網站,進行了仿寫。 不過貌似在手機上lable标簽有點變形~~
  2. 移動優化,也就是改寫了CSS,利用CSS3的特性,讓頁面布局可以根據不同的浏覽器分辨率進行自動切換,用我的 Mate7 看了一下,結果還是差強人意:)
  3. JS改寫, 因為LightBox升級,jQuery 庫徹底引入,自己的 ajax 提交評論以及一些自定義的JS都統統用 jQuery 庫重寫了。讓代碼更簡潔。
  4. QQ登錄的引入, 給整個網站加入了最熱門的 QQ互聯 功能,也就是用QQ帳号登錄評論功能。 代碼以 plugin 方式運行, 也算自己的原創 MT 插件,等稍後整理出來,于同好共享之。另外,評論登錄界面也做了修改,融合了 MT 4 的列表顯示來代替MT 5 的select選擇。更好看意見,大家可以點擊 /cgi-bin/mt/cp?__mode=login&blog_id=2 來看看結果。

基本上的改動就是這樣了。 一些東西,比如 ajax 提交評論、後台的的防止 SPAM 的SimpleComment 0.12 等自己折騰的東西,等有時間會寫成博文,方便大家也方便自己:)

--EOF--

[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--