しかし、いくつかの問題もあります。第一に、カレンダーの描画が少し遅いこと、第二に、IE との互換性があまり良くないこと、第三に、jQuery ベースではないことです。
;(function($) {
var userAgent = window.navigator.userAgent.toLowerCase();
$.browser.msie8 = $.browser.msie && /msie 8.0/i. test(userAgent);
$.browser.msie7 = $.browser.msie && /msie 7.0/i.test(userAgent);
$.browser.msie6 = !$.browser.msie8 && !$。 browser.msie7 && $.browser.msie && /msie 6.0/i.test(userAgent);
Date.prototype.Format = function(format) {
var o = {
"M ": this .getMonth() 1、
"d ": this.getDate()、
"h ": this.getHours()、
"H ": this.getHours()、
"m ": this.getMinutes(),
"s ": this.getSeconds(),
"q ": Math.floor((this.getMonth() 3) / 3),
"w" : "0123456".indexOf(this.getDay()),
"S": this.getMilliseconds()
};
if (/(y )/.test(format)) {
format = format.replace(RegExp.$1, (this.getFull Year() "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" k ")").test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length == 1 ? o[k] :
("00" o[k]).substr(("" o[k]).length));
}
形式を返します。
};
関数 DateAdd(間隔, 数値, idate) {
数値 = parseInt(数値);
変数日付;
if (typeof (idate) == "string") {
date = idate.split(/D/);
eval("var date = new Date(" date.join(",") ")");
}
if (typeof (idate) == "オブジェクト") {
date = new Date(idate.toString());
}
switch (interval) {
case "y": date.setFullyear(date.getFull Year() 数値);壊す;
case "m": date.setMonth(date.getMonth() 数値);壊す;
ケース "d": date.setDate(date.getDate() 数値);壊す;
case "w": date.setDate(date.getDate() 7 * number);壊す;
ケース "h": date.setHours(date.getHours() 数値);壊す;
ケース "n": date.setMinutes(date.getMinutes() 数値);壊す;
case "s": date.setSeconds(date.getSeconds()number);壊す;
case "l": date.setMilliseconds(date.getMilli秒() 数値);壊す;
}
返却日;
};
$.fn.datepicker = function(o) {
var def = {
weekStart: 0,
weekName: ["日", "一", "二", "三", "四", "五", "六"], //星期的格式
monthName: ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"], //月份的格式
monthp: "月",
年: new Date().getFull Year (), //定义年の变量の初期値
月: new Date().getMonth() 1, //所定义月の变量の初期値
日: new Date().getDate(), //定日の变量的初期值
today: new Date(),
btnOk: " 确定 ",
btnCancel: " 取消 ",
btnToday: "今天",
inputDate : null、
onReturn: false、
バージョン: "1.1"、
applyrule: false、//function(){};return rules={startdate,endate};
showtarget: null、
ピッカー: ""
};
$.extend(def, o);
var cp = $("#BBIT_DP_CONTAINER");
if (cp.length == 0) {
var cpHA = [];
cpHA.push("
");
if ($.browser.msie6) {
cpHA.push('
');
}
cpHA.push("
"); //头哟 cpHA.push(""); cpHA.push(""); cpHA.push(" |
"); //周 cpHA.push(""); // 生成周 for (var i = def.weekStart, j = 0; j cpHA.push("
", def .weekName[i], " | "); if (i == 6) { i = 0; } else { i ; } } cpHA.push(" "); //生成tBody,需要重新生成的 cpHA.push(" "); //生成tBody结束 cpHA.push(" |
");
cpHA.push(" |
");
cpHA.push("
");
//输出下来框
cpHA.push("
");
cpHA.push("");
//1月,7月 按钮两个
cpHA.push("", def.monthName[0], " | ", def.monthName[6], " | | | ");
cpHA.push("
");
cpHA.push("");
cpHA.push("", def.monthName[1], " | ", def.monthName[7], " | | | ");
cpHA.push("
");
cpHA.push("");
cpHA.push("", def.monthName[2], " | ", def.monthName[8], " | | | ");
cpHA.push("
");
cpHA.push("");
cpHA.push("", def.monthName[3], " | ", def.monthName[9], " | | | ");
cpHA.push("
");
cpHA.push("");
cpHA.push("", def.monthName[4], " | ", def.monthName[10], " | | | ");
cpHA.push("
");
cpHA.push("");
cpHA.push("", def.monthName[5], " | ", def.monthName[11], " | | | ");
cpHA.push("
");
cpHA.push("");
cpHA.push(" | ");
cpHA.push("
");
cpHA.push("
");
cpHA.push("
");
cpHA.push("
");
var s = cpHA.join("");
$(document.body).append(s);
var cp = $("#BBIT_DP_CONTAINER");
initevents();
}
function initevents() {
//1 今日 btn;
$("#BBIT-DP-TODAY").click(returntoday); click(returnfalse);
$("#BBIT_DP_INNER tbody").click(tbhandler);
$("#BBIT_DP_RIGHTBTN").click (nextm);
$("#BBIT_DP_YMBTN").click(showym);
$("#BBIT-DP-MP"); -MP-PREV").click(mpprevy);
$("#BBIT-DP-MP-NEXT").click(mpnexty);
$("#BBIT-DP-MP-OKBTN") .click(mpok);
$("#BBIT-DP-MP-CANCELBTN").click(mpcancel);
}
関数 mpcancel() {
$("#BBIT-DP -MP").animate({ トップ: -193 }, { 継続時間: 200, complete: function() { $("#BBIT-DP-MP").hide(); } });
return false ;
}
関数 mpok() {
def.年 = def.cy;
def.日 = 1; "#BBIT-DP-MP").animate({ トップ: -193 }, { 継続時間: 200, complete: function() { $("#BBIT-DP-MP").hide(); } });
writecb();
return false;
}
関数 mpprevy() {
var y = def.ty - 10
def.ty = y;
rr年(y);
false を返します。
}
function mpnexty() {
var y = def.ty 10
def.ty = y;
rr年(y);
false を返します。
}
関数 rryear(y) {
var s = y - 4;
var ar = [];
for (var i = 0; i ar.push(s i);
ar.push(s i 5);
}
$("#BBIT-DP-MP td.bbit-dp-mp-year").each(function(i) {
if (def. Year == ar[i]) {
$(this).addClass("bbit-dp-mp-sel");
}
else {
$(this).removeClass("bbit-dp-mp-sel") );
}
$(this).html("
" ar[i] "").attr(" xyear", ar[i]);
});
}
関数 mpclick(e) {
var パネル = $(this);
var et = e.target || e.src要素;
var td = getTd(et);
if (td == null) {
return false;
}
if ($(td).hasClass("bbit-dp-mp-month")) {
if (!$(td).hasClass("bbit-dp-mp-sel" )) {
var ctd =panel.find("td.bbit-dp-mp-month.bbit-dp-mp-sel");
if (ctd.length > 0) {
ctd.removeClass("bbit-dp-mp-sel");
}
$(td).addClass("bbit-dp-mp-sel")
def.cm = parseInt($(td).attr("xmonth"));
}
}
if ($(td).hasClass("bbit-dp-mp-year")) {
if (!$(td).hasClass("bbit-dp- mp-sel")) {
var ctd =panel.find("td.bbit-dp-mp-year.bbit-dp-mp-sel");
if (ctd.length > 0) {
ctd.removeClass("bbit-dp-mp-sel");
}
$(td).addClass("bbit-dp-mp-sel")
def.cy = parseInt($(td).attr("xyear"));
}
}
false を返します。
}
function showym() {
var mp = $("#BBIT-DP-MP");
var y = def.年;
def.cy = def.ty = y;
var m = def.Month - 1;
def.cm = m;
var ms = $("#BBIT-DP-MP td.bbit-dp-mp-month");
for (var i = ms.length - 1; i >= 0; i--) {
var ch = $(ms[i]).attr("xmonth");
if (ch == m) {
$(ms[i]).addClass("bbit-dp-mp-sel");
}
else {
$(ms[i]).removeClass("bbit-dp-mp-sel");
}
}
rryear(y);
mp.css("トップ", -193).show().animate({ トップ: 0 }, { 継続時間: 200 });
}
function getTd(elm) {
if (elm.tagName.toUpperCase() == "TD") {
return elm;
}
else if (elm.tagName.toUpperCase() == "BODY") {
return null;
}
else {
var p = $(elm).parent();
if (p.length > 0) {
if (p[0].tagName.toUpperCase() != "TD") {
return getTd(p[0]);
}
else {
return p[0];
}
}
}
null を返します。
}
function tbhandler(e) {
var et = e.target || e.src要素;
var td = getTd(et);
if (td == null) {
return false;
}
var $td = $(td);
if (!$(td).hasClass("bbit-dp-disabled")) {
var s = $td.attr("xdate");
var arrs = s.split("-");
cp.data("indata", new Date(arrs[0], parseInt(arrs[1], 10) - 1, arrs[2]));
returndate();
}
false を返します。
}
関数 returnfalse() {
return false;
}
function prevm() {
if (def.Month == 1) {
def. Year--;
def.Month = 12;
}
else {
def.Month--
}
writecb();
false を返します。
}
関数 nextm() {
if (def.Month == 12) {
def. Year ;
def.Month = 1;
}
else {
def.Month
}
writecb();
false を返します。
}
function returntoday() {
cp.data("indata", new Date());
returndate();
}
関数 returndate() {
var ct = cp.data("ctarget");
var ck = cp.data("cpk");
var re = cp.data("onReturn");
var ndate = cp.data("indata")
var ads = cp.data("ads");
var ade = cp.data("ade");
var dis = false;
if (広告 && ndate < 広告) {
dis = true;
}
if (ade && ndate > ade) {
dis = true;
}
if (dis) {
return;
}
if (re && jQuery.isFunction(re)) {
re.call(ct[0], cp.data("indata"));
}
else {
ct.val(cp.data("indata").Format("yyyy-MM-dd"));
}
ck.attr("isshow", "0");
cp.removeData("ctarget").removeData("cpk").removeData("indata").removeData("onReturn")
.removeData("ads").removeData("ade");
cp.css("可視性", "非表示");
ct = ck = null;
}
function writecb() {
var tb = $("#BBIT_DP_INNER tbody");
$("#BBIT_DP_YMBTN").html(def.monthName[def.Month - 1] def.monthp " " def. Year);
var firstdate = new Date(def. Year, def.Month - 1, 1);
var diffday = def.weekStart - firstdate.getDay();
var showmonth = def.Month - 1;
if (diffday > 0) {
diffday -= 7;
}
var startdate = DateAdd("d", diffday, firstdate);
var enddate = DateAdd("d", 42, startdate);
var ads = cp.data("ads");
var ade = cp.data("ade");
var bhm = [];
var tds = def.today.Format("yyyy-MM-dd");
var indata = cp.data("indata");
var ins = indata != null ? indata.Format("yyyy-MM-dd") : "";
for (var i = 1; i if (i % 7 == 1) {
bhm.push("
");
}
var ndate = DateAdd("d", i - 1, startdate);
var tdc = [];
var dis = false;
if (広告 && ndate < 広告) {
dis = true;
}
if (ade && ndate > ade) {
dis = true;
}
if (ndate.getMonth() < showmonth) {
tdc.push("bbit-dp-prevday");
}
else if (ndate.getMonth() > showmonth) {
tdc.push("bbit-dp-nextday");
}
if (dis) {
tdc.push("bbit-dp-disabled");
}
else {
tdc.push("bbit-dp-active");
}
var s = ndate.Format("yyyy-MM-dd");
if (s == tds) {
tdc.push("bbit-dp-today");
}
if (s == ins) {
tdc.push("bbit-dp-selected");
}
bhm.push("", ndate.getDate( ), " | ");
if (i % 7 == 0) {
bhm.push("
");
}
}
tb.html(bhm.join(""));
}
var dateReg = /^(d{1,4})(-|/|.)(d{1,2})2(d{1,2})$/;
return $(this).each(function() {
var obj = $(this).addClass("bbit-dp-input");
var picker = $(def.picker);
def.showtarget == null && obj.after(picker);
picker.click(function(e) {
var isshow = $(this).attr("isshow");
//先隐藏
var me = $(this);
if (cp.css("visibility") == "visible") {
cp.css("avisibility", "hidden") ;
}
if (isshow == "1") {
me.attr("isshow", "0");
cp.removeData("ctarget").removeData("cpk") ").removeData("indata").removeData("onReturn");
return false;
}
var v = obj.val();
if (v != "") {
v = v.match(dateReg);
}
if (v == null || v == "") {
def. Year = new Date().getFull Year() ;
def.Month = new Date().getMonth() 1;
def.Day = new Date().getDate();
def.inputDate = null
}
else {
def. Year = parseInt(v[1], 10);
def.Month = parseInt(v[3], 10);
def.Day = parseInt(v[4], 10); );
def.inputDate = new Date(def.年, def.月 - 1, def.日);
cp.data("ctarget", obj).data("cpk" 、me).data("indata", def.inputDate).data("onReturn", def.onReturn);
if (def.applyrule && $.isFunction(def.applyrule)) {
var rules = def.applyrule.call(obj, obj[0].id);
if (rule) {
if (rule.startdate) {
cp.data("ads", rules.startdate);
}
else {
cp.removeData("ads");
}
if (rule.enddate) {
cp.data("ade", rules.enddate);
}
else {
cp.removeData("ade");
}
}
}
else {
cp.removeData("ads").removeData("ade")
}
writecb();
$("#BBIT-DP-T").height(cp.height());
var t = def.showtarget ||オブジェクト;
var pos = t.offset();
var height = t.outerHeight();
var newpos = { left: pos.left、top: pos.top height };
var w = cp.width();
var h = cp.height();
var bw = document.documentElement.clientWidth;
var bh = document.documentElement.clientHeight;
if ((newpos.left w) >= bw) {
newpos.left = bw - w - 2;
}
if ((newpos.top h) >= bh) {
newpos.top = pos.top - h - 2;
}
if (newpos.left newpos.left = 10;
}
if (newpos.top newpos.top = 10;
}
$("#BBIT-DP-MP").hide();
newpos.visibility = "可視";
cp.css(newpos);
//cp.show();
$(this).attr("isshow", "1");
$(document).one("click", function(e) {
me.attr("isshow", "0");
cp.removeData("ctarget").removeData(" cpk").removeData("indata");
cp.css("visibility", "hidden");
});
false を返します。
});
});
};
})(jQuery);
那は次に分析の主要な手順といくつかの注意事項:
首先も套版化编写jQuery控訴の子:
复制代码代码如下:
;(function($) {
//$.fn.extend(datepicker:function(o){})
$.fn.datepicker= function(o) も使用できます{
} ( これらのパラメーターの意味を説明するコメントがコードに追加されました。weekName、monthName など、複数のパラメーターが多言語用に設定されています
コードをコピーします
コードは次のとおりです: var def = { weekStart: 0,//週が始まる曜日、0日曜日を表します weekName: ["Day", "Monday" , "two", "three", "four", "five", "six"], //週形式
monthName: ["one" , "two", "three", "four", " Five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"], //形式月の
monthp: "month",// 月のサフィックス
年: new Date().getFull Year(), // 年
月を定義する変数の初期値: new Date().getMonth() 1, //月を定義する変数の初期値
Day: new Date().getDate(), //日を定義する変数の初期値
today: new Date(),//today
btnOk: "OK",//OK ボタンのテキスト
btnCancel: "Cancel", //キャンセル ボタンのテキスト
btnToday: "Today" , //今日のボタンのテキスト
inputDate: null, //役に立たない、コード内のストレージにのみ使用されます Data
onReturn: false, //日付が選択されたときに呼び出される関数
version: "1.0", //Version
applyrule: false, //日付選択ルール、選択可能な日付範囲を設定できます function (){};return rules={startdate,endate};
showtarget: null , // 表示キャリア、カレンダー展開が依存するオブジェクト、デフォルトはオブジェクト自体です
picker: "" // 追加のクリックイベント Object
$.extend(def, o); ;//渡されたパラメータを使用してデフォルトの値を入力します
2 番目の部分は、月ビューと年と月の選択を初期化することです。ビューの HTML は
コードをコピーします
コードは次のとおりです:
cpHA.push("
"); .msie6) { / /IE6 ポップアップ レイヤー カバーの場合は、
cpHA.push('
');
}
cpHA.push("< table class='dp-maintable' cellpacing='0' cellpadding='0' style='width:175px;'>
"); //头よ cpHA.push(" "); cpHA.push(""); cpHA.push(" |
"); //week cpHA.push (""); //週を生成 for (var i = def.weekStart, j = 0; j cpHA.push("
", def.weekName[i], "< ;/span>< ;/th>"); if (i == 6) { i = 0; } else { i ; } } ....//一部のコードを省略 cpHA.push(""); cpHA.push(""); "); var s = cpHA.join(""); $(document.body).append(s); //本文に追加 cp = $("#BBIT_DP_CONTAINER"); //再度取得する Once initevents() //初期化イベント }
ここで重要な点は、HTML 出力と日付のイベント初期化は基本的に同じページで同時に 2 つ開かれないため、HTML 出力と日付のイベント初期化が 1 回だけ行われるということです。生成された HTML には特別なカスタム属性もいくつかあります。注意深く見ると、これらの属性が後続の処理で大きな役割を果たすことがわかります。それでは、イベントを見てみましょう
$("#BBIT- DP-TODAY").click(returntoday);//今日のボタン イベント cp.click(returnfalse);//バブリングを防止 $("#BBIT_DP_INNER tbody").click( tbhandler);/ /各 td に $("#BBIT_DP_LEFTBTN").click(prevm) を追加する代わりに、月ビューの途中で本文にクリック イベントを追加します;//先月 $( "#BBIT_DP_RIGHTBTN").click( nextm);//来月 $("#BBIT_DP_YMBTN").click(showym);//年月表示に切り替える $("#BBIT-DP- MP").click(mpclick) ;//年月ビューのクリックイベントも配信に使用します $("#BBIT-DP-MP-PREV").click(mpprevy);//前へyear $("#BBIT-DP-MP-NEXT").click(mpnexty);//来年 $("#BBIT-DP-MP-OKBTN").click(mpok);/ /OK ボタンのイベント $ ("#BBIT-DP-MP-CANCELBTN").click(mpcancel);//キャンセル ボタン イベント
必要な各要素にイベントを追加しますここには 2 つの場所があります。月次ビューのクリック ビューの場合、従来の方法では、イベントが存在しません。 TDが生成されるたびに追加されるとパフォーマンスに影響するため、クリックイベントをコンテナに直接追加し、別の年と月のビューを選択してイベントを配布することも上記と同じロジックです。では、月ビューのクリック イベントを 分析してみましょう。実際、各 TD が生成されると、xdate カスタム属性 が登録されます。tbhandler 関数を見てみましょう。
function tbhandler(e) { var et = e.target || e.srcElement; //イベント ソースを検索します var td = getTd(et); //イベント ソースは td を再帰的に検索します if (td == null) { return false; } var $td = $(td); if (!$(td).hasClass("bbit-dp-disabled")) {無効ではありません var s = $td.attr("xdate");//td の自身の値を取得します属性日付データを定義します var arrs = s.split("-"); .data("indata", new Date(arrs[0], parseInt(arrs[1], 10) - 1, arrs[2])); returndate();//日付 を返します。 🎜>} return false; }
すべての日付選択時間 初期化 (1 回) 後、クリック イベントを各ピッカーに追加する必要があります
var obj = $(this).addClass("bbit-dp-input");//入力にスタイルを追加しますvar picker = $(def.picker);//ピッカー オブジェクトを取得します //If showtarget は null ではありません。これにより、入力の背後にピッカーが登録されます //それ以外の場合、ユーザーはピッカーの位置、つまりピッカーを自分で処理します。これはページ自体にすでに存在します //違いを確認できます例の呼び出し 1 と 3 の間 def.showtarget == null && obj.after(picker) picker.click(function( e) { ....//コードを省略します });
ピッカーのクリック イベントは比較的長いので、別個に説明した方がよいと思います。最初のポイントは、実際の非表示イベントの処理です。 2 番目はウィンドウ エッジの問題の処理、3 番目は日付範囲ルールの処理です。
コードをコピー コードは次のとおりです: function(e) { //現在表示されているかどうかを取得します var isshow = $(this).attr("isshow") var me = $(this); ; // 表示されている場合は、ピッカーをクリックして表示し、ピッカーをクリックして非表示にするロジックを処理するために使用されます。 if (cp.css("visibility") == "visible" ) { css(" Visibility", "hidden"); } //同様に表示される場合 if (isshow == "1") { me. attr("isshow", " 0"); //一時データを削除します。シングルトンであるため、現在どの入力であるかを示す必要があります。 cp.removeData("ctarget").removeData("cpk ").removeData("indata").removeData("onReturn"); return false; //バブリングを防止します } //非表示の場合は入力値を取得します var v = obj .val(); if (v != "") { v = v.match(dateReg);//形式が正しいかどうかを確認します } if (v == null || v == "") { //形式が間違っているか空の場合は、現在の日付を使用します。 def. Year = new Date().getFull Year(); .getMonth() 1; def.Day = new Date().getDate(); def.inputDate = null } //それ以外の場合は、入力された日付を使用します🎜>def. Year = parseInt(v[1], 10); def.Month = parseInt(v[3], 10); def.Day = parseInt(v[4], 10); def.inputDate = new Date(def . Year, def.Month - 1, def.Day); } //一時データを登録 cp.data("ctarget", obj) .data("cpk", me).data ("indata", def.inputDate).data("onReturn", def.onReturn); //ルールを呼び出し、オプションの日付範囲を返します if (def.applyrule && $.isFunction(def.applyrule)) { var rules = def.applyrule.call(obj, obj[0].id); if (ルール) { if ( rules.startdate) { cp.data ("ads", rules.startdate); else { cp.removeData("ads"); if (rule.enddate) { cp.data("ade", rules.enddate); else { cp.removeData("ade"); } } else { //制限が存在しない場合は制限を削除します cp.removeData("ads").removeData("ade") } //月間カレンダーの内容は td writecb();$("#BBIT-DP-T").height(cp.height()); //表示されている添付オブジェクトを取得します var t = def.showtarget || obj; / /オブジェクトの位置を取得します var pos = t.offset() //オブジェクトの高さを取得します var height = t.outerHeight(); //日付選択ボックスの位置が付加されます オブジェクトの位置にその高さを加えた値 var newpos = { left: pos.left, top: pos.top height } ; //以下はすべてウィンドウ境界の問題を扱っています var h = cp.height(); ; var bh = document.documentElement.clientHeight; if ((newpos.left w) > ;= bw) { newpos.left = } if ((newpos.top h) >= bh) { newpos.top = pos.top - h - 2; } if (newpos.left newpos .left = 10; } if (newpos.top < 0) { newpos.top = 10; } // デフォルトを月の日付ビューに強制します $("#BBIT-DP-MP").hide(); newpos.visibility = "visible" ; cp.css(newpos); //既知の位置に移動して表示します //cp.show(); $(this).attr("isshow", "1"); // 日付ピッカーを非表示にする問題を解決するには、ドキュメントにシングル クリック イベントを登録します。日付ピッカーを開いた後に他の場所をクリックした $(document).one("click", function(e) { me.attr("isshow", "0"); cp.removeData(" ctarget").removeData("cpk").removeData("indata"); cp.css("visibility ", "hidden"); }); return false;//組織バブル }
その他のコードは、先月や来月などの日付操作の関数です。しばらく紹介しません。コードについて質問がある場合は、お問い合わせください。メッセージを残してください。最後に例を示します。
最初の例は、デモの例です。呼び出しメソッドの説明もあります。 > http://jscs.cloudapp.net/ControlsSample/dpdemo
2 番目の例は、私が作成したアプリケーションとスケジュール管理コントロールを組み合わせた日付ピッカーです (最初にこれを見てください) )
http://xuanye.cloudapp.net/
の位置は、
および です。
は私の作成した datepicker のアプリケーションです。 最後に、この記事が役に立ったと思われる場合は、[おすすめ] をクリックしてください。 コードパッケージ化スクリプトのホーム
|
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
-
2024-10-22 09:46:29
-
2024-10-13 13:53:41
-
2024-10-12 12:15:51
-
2024-10-11 22:47:31
-
2024-10-11 19:36:51
-
2024-10-11 15:50:41
-
2024-10-11 15:07:41
-
2024-10-11 14:21:21
-
2024-10-11 12:59:11
-
2024-10-11 12:17:31
|