iT邦幫忙

0

jquery 如何設置限制器當有變動時才更新

RT 繼上次的cover call問題解決後這次又有新的問題了

一樣先附上還沒新增前的程式碼

function requestlist_call()
{
	$("#load_img_r").show();

	$.getJSON("data/requestlist.json",
		function(b)
		{
			request_json=b.requestlist;
			request_length=request_json.length;
			request_total_time=0;
			request_total_number=0;
			request_html="<table class=list><tr><th width=3%></th><th width=5%>動作</th><th width=25%>歌手</th><th width=30%>歌名</th><th width=34%>專輯</th><th width=3%>時間</th></tr>";
			for(q=0;q<request_length-1;q++)
			{
				request_html+="<tr><td>"+request_json[q].index+"</td>";
			
			 	if(request_json[q].is_requested=="1")
				{
					request_html+='<td><a href="javascript:void(0)" ';
					request_html+='onclick="request('+request_json[q].list_id+","+request_json[q].song_id+",'rem');return false;\">取消</a></td>";
				}
				else
				{
					request_html+='<td>';
					request_html+=''+"列隊中</td>";
				}
			 	request_html+='<td><a href="javascript:void(0)" onclick="artist_name(\''+request_json[q].artist+"');return false;\">"+request_json[q].artist+"</a></td>";
				request_html+="<td title=\""+"\">"+request_json[q].title+"</td>";
				request_html+='<td><a href="javascript:void(0)" onclick="album_name(\''+request_json[q].album+"');return false;\">"+request_json[q].album+"</a></td>";
				request_html+="<td>"+request_json[q].length+"</td></tr>";
				request_total_time+=parseInt(request_json[q].length_seconds);
				request_total_number++;
			}
			request_html+="</table>";
			
			$("#request_list").html(request_html);
			req_time_h=Math.floor(request_total_time/3600);
			req_time_m=Math.floor((request_total_time-req_time_h*3600)/60);
			req_time_s=request_total_time-((req_time_h*3600)+(req_time_m*60));
			 
			if(req_time_h<10){req_time_h="0"+req_time_h}
			if(req_time_m<10){req_time_m="0"+req_time_m}
			if(req_time_s<10){req_time_s="0"+req_time_s}
			
			$("#req_time").html(request_total_number+"<span class=usu> songs   total </span>"+req_time_h+":"+req_time_m+":"+req_time_s);
			$("#req_time2").html(request_total_number+"/20"+"<span class=usu2> songs   Total </span>"+req_time_h+":"+req_time_m+":"+req_time_s);
			$("#load_img_r").hide();
		}
	)
}

瀏覽器端的自動更新函式

function myrefresh()
	{
	setInterval(function(){
	history_call();
	playing_call();
	requestlist_call();
	subplaylist_call();
	fixcover_call();
	return false},3000);
	}	

這次主要是想減少網站流量 所以想設置一些"限制器"
限制器主要的功用就是當有變動時才更新不然就不更新
不過這次屬性比較多 不像上次只要改src

2 個回答

0
跟著鄉民看熱鬧
iT邦研究生 2 級 ‧ 2018-06-11 16:37:31
最佳解答

一樣把request_html 字串的部份寫成獨立的function,只要比較request_html和原來的table,不一樣再更新就可以了

看更多先前的回應...收起先前的回應...

恩 我一開始也是有想過這個的 可是寫了後結果嘛......如果有這麼順利的話我就不會來這發問了

程式碼如下

function limiter()
{
	$.getJSON("data/requestlist.json",
		function(b)
		{
			if($("#request_list").html().replace("<tbody>","").replace("</tbody>","").replace(/"/g,"")!=(request_html.replace(/"/g,"")))
			{
				requestlist_call();
				console.log($("#request_list").html().replace("<tbody>","").replace("</tbody>","").replace(/"/g,""));
				console.log(request_html.replace(/"/g,""));
			}
		}
	)
}

我在行動裝置上測試時是無變化的

沒變化的時候,$("#request_list").html() 應該會等於 request_html

恩 問題是我在行動裝置上執行時 變化的只有行動裝置上的$("#request_list").html() 電腦上的不會變化

要兩種裝置上都有變化就需要request_call的那一大串 可是這樣一來$("#request_list").html()就又等於request_html了

等於就不會更新了丫,不等於才更新

所以我要把request call那一大串也移過來?

總之作法跟上次一樣,只是變成處理request_html字串,然後判斷request_html跟$("#request_list").html()是否一樣,一樣的話就更新$("#request_list").html()

還是一樣 不會更新

function requestlist_limiter()
{
	$.getJSON("data/requestlist.json",
		function(b)
		{	
			var requestlist_json = b.requestlist;
			var oldrequestlist = $("#request_list").html().replace("<tbody>","").replace("</tbody>","").replace(/"/g,"");
			var newrequestlist = request_html.replace(/"/g,"");
			if(oldrequestlist != newrequestlist)
			{
				$("#request_list").html(request_html);
			}
		}
	)
}

是這樣吧

var oldrequestlist = $("#request_list").html().replace(/"/g,"");
var newrequestlist = request_html.replace(/"/g,"");
Homura iT邦新手 2 級 ‧ 2018-06-11 17:38:53 檢舉

直接把抓回來的json做比對,不要用html加工後的如何?

$("#request_list").html()我用console.log看過了 會多出tbody標籤 不移除就永遠不一樣

那問題是移除了就會一樣嗎?

有另外一種作法。將取到的值儲存到一個參數上。
第一次空值當然就不判斷了。
之後每一次就跟這個值做比較就行了。
這樣就不用擔心取html會跟原來的不太一樣。也可以很容易的判斷現在抓的值是否跟之前一樣。

@kksugsay 抱歉昨天到了回復上限無法回復 我是用console.log看的 這樣replace後兩個確實會一樣

@浩瀚星空 所以你的意思是說設個變數儲存song_id 剛開始先不存 之後如果不一樣就更新然後存值?

對了 有沒有辦法設定更新完就讓getJson停止阿 不然我request數還是一樣多
http://puu.sh/ADBZU/156b9d547f.jpg

你說會一樣,那一樣就不要更新,不一樣再更新,不就可以了?
還是看起來一樣,實際上不一樣?

更新完就讓getJson停止,那就變成只會更新一次了,或是你需要控制讓它更新的次數? 控制要不要更新的方式如下:

var flag = false;

function requestlist_limiter()
{
   if(!flag)
	$.getJSON("data/requestlist.json",
		function(b)
		{	
			var requestlist_json = b.requestlist;
			var oldrequestlist = $("#request_list").html().replace("<tbody>","").replace("</tbody>","").replace(/"/g,"");
			var newrequestlist = request_html.replace(/"/g,"");
			if(oldrequestlist != newrequestlist)
			{
				$("#request_list").html(request_html);
                flag = true;
			}
		}
	)
}

恩 不過這串代碼的$("#request_list").html()除非如果在其他裝置上點的話除非重整不然不會起變化阿 因為他不像request_call()是整個重新建構 request_html也不會變化 現在就是卡在這裡啊

簡單來講request_html之所以會變化是因為有request_call的那一大串重新建構才得以實現,所以就算直接用limiter去call也沒用

要這樣才對~
/images/emoticon/emoticon06.gif

var flag = false;

function requestlist_limiter()
{
   if(!flag)
	$.getJSON("data/requestlist.json",
		function(b)
		{	
		
			request_json=b.requestlist;
			request_length=request_json.length;
			request_total_time=0;
			request_total_number=0;
			request_html="<table class=list><tr><th width=3%></th><th width=5%>動作</th><th width=25%>歌手</th><th width=30%>歌名</th><th width=34%>專輯</th><th width=3%>時間</th></tr>";
			for(q=0;q<request_length-1;q++)
			{
				request_html+="<tr><td>"+request_json[q].index+"</td>";

				if(request_json[q].is_requested=="1")
				{
					request_html+='<td><a href="javascript:void(0)" ';
					request_html+='onclick="request('+request_json[q].list_id+","+request_json[q].song_id+",'rem');return false;\">取消</a></td>";
				}
				else
				{
					request_html+='<td>';
					request_html+=''+"列隊中</td>";
				}
				request_html+='<td><a href="javascript:void(0)" onclick="artist_name(\''+request_json[q].artist+"');return false;\">"+request_json[q].artist+"</a></td>";
				request_html+="<td title=\""+"\">"+request_json[q].title+"</td>";
				request_html+='<td><a href="javascript:void(0)" onclick="album_name(\''+request_json[q].album+"');return false;\">"+request_json[q].album+"</a></td>";
				request_html+="<td>"+request_json[q].length+"</td></tr>";
				request_total_time+=parseInt(request_json[q].length_seconds);
				request_total_number++;
			}
			request_html+="</table>";
			var requestlist_json = b.requestlist;
			var oldrequestlist = $("#request_list").html().replace("<tbody>","").replace("</tbody>","").replace(/"/g,"");
			var newrequestlist = request_html.replace(/"/g,"");
			if(oldrequestlist != newrequestlist)
			{
				$("#request_list").html(request_html);
                flag = true;
			}
		}
	)
}

恩 一樣耶 還是不會自己更新 我用console.log看看問題出在哪.......

判斷拿掉,直接用下面那行執行,看它會不會清空,就知道會不會執行了,剩下就是你判斷的問題
$("#request_list").html('');

更正剛測試了一下會執行 但只有一次 第二次以後就不會了 用console.log看了一下似乎是變true後就停止運行了

剛把var flag = false;拖到function裡雖然true後會繼續更新了可是又變成一直send request了 可以改成在true時才send request嗎

剛說了只會更新一次,因為你要控制更新,就是用類似方式。
另外要比較新的資料和舊資料一不一樣,不send request怎麼知道要不要更新?總要有依據吧~/images/emoticon/emoticon06.gif

問題是我不需要send這麼多次阿/images/emoticon/emoticon10.gif

把var flag = false;拖到function裡是能多次更新 但是跟沒改前一樣會狂send request

那你需要幾次? 還是要降低更新頻率?

就變動時send就好

那請問你要怎麼知道有沒有變動? 要先知道你變動的條件是什麼,不然就只能這樣做了吧
/images/emoticon/emoticon10.gif

變動的條件嗎.....就有人點播時json裡的資料會變動阿 因為上限已到所以之後的我都回覆在這了:@kksugsay 這部分由於不知道使用者是從哪點播的 可能是左側清單 可能是歌曲清單等 建議直接看這個比較快http://ac1011.hopto.org:4095/js/requester.js

那json 的資料不就是request_html,有人點播的動作是寫在你js裡嗎? 把那段js放上來看看

自己看吧,總之在user點播的時候把flag改成false,就可以繼續更新了,就這樣~
這樣還不會改的話,不管你了~/images/emoticon/emoticon05.gif

1
浩瀚星空
iT邦新手 2 級 ‧ 2018-06-11 17:25:55

一般來說,如果可以從後端解決的話。我會從後端解決這個問題。
不過先依照你目前的方式來做說明。

這邊可以發現,你並無絕對性的key值。一般來說,我為何要說能從後端解決是最好的。
是因為可以由後端另外給與一個key值或是唯一性比對值。如資料串的md5碼。

這邊看起來你的json資料因該是由外部來的,可能是無法自行修正處理。
但最好的方式,還是希望能用一個後端來接收資料後,並將你想要的字串重新處理過。

這邊是有發現你的程式碼中有幾個需要注意的地方,這也是我上面說的,你並無絕對性的key(index)值存在。
除非你可以確定你所獲取的資料順序是都一樣的。

所以你採用index的判斷取值的方式,並非是最好的方法。這也容易發生index的對應順序錯誤資料的問題。

所以首先:由於不太清楚你的資料來源情況。要不然可以的話,可以先找個資料是有唯一性特性的最好。如歌曲代碼之類的。

這邊先教一下改良你的程式。從程式碼來看,你因該是用jquery。
那最好還是善用一下jquery的ecah。不要直接用for。
好處是你不需要用index的方式來做指定。

將你的

for(q=0;q<request_length-1;q++){

}

改成

$.each(request_json,function(index,v){

});

其中v就是request_json[q]原先的值。你會比較好處理。
而index就是對應的key值。如果所屬的json無對應的key值。那就是0、1、2....??跟陣列一樣的index值。
如果有對應key。你就太好了。這也代表著說,其key值有其唯一性。

再來就是運用jquery的select的特性。給與時。其實你可以給他一個代碼如

$("tr[setkey='???']")的方式來做一些處理。

其實還有更多的做法。你目前使用的做法的確是非常耗效能,因該還會讓會員感覺有頁面更換的感覺。

如果可以的話,看是否能給一份json相關資料。有空我再幫你改良這一段程式。
因為要說的東西太多了。

看更多先前的回應...收起先前的回應...

光改那個沒啥意義,會這樣寫,表示其他程式處理方式都是一樣,除非程式整個重構

我想這json光有你也看不懂 必須要搭配特定程式才會有作用

而那個程式是:foobar2000

@kksugsay
他如果不改程式的話。只光用index的dom方式來跑。
只是更容易發生效能問題的。不能每次都用html來做替換掉吧。
光看瀏覽器的ram用量就會覺得很可怕。
pc可能還不用太擔心這個問題。不過手機的話,可是很可怕的用法。

當然我也是會擔心他是否會應用,只是想改一邊讓他看看是否懂的如何使用jquery。其它是否要全面性來改當然還是得看他了。這只能提個頭而已

@jason311101
這說真的,我還頭一次聽到json要用特定的程式才會有作用的說法。
除非它不是正統的json格式。

不過看你的程式碼,你也不過是直接取用requestlist.json的檔案來處理。也無做任何轉換規格的做法。
怎麼會有此「特定程式」才有作用的說法這一說??
難不成??javascript就是你所謂的特定程式?

@浩瀚星空
你試試直接開啟json跟到http://ac1011.hopto.org:4095/data/requestlist.json
這網頁看出來的結果一不一樣

他會改的話,就不會問這種問題了,起這種頭沒啥意義,真要教的話,就直接把作法寫出來~ 很愛打字,我好懶得打~

嗯,我看完了,一個是規格套用樣版。
看樣子你那段運行因該是有配合其它程式沒錯。

但反正你取到的就是已經正規取值的東西出來了。無需去管他的套版是什麼。反正要的就是產生後的值。

不過我要的依然也是ok的。因為我要查看的就是是否有唯一性的id。
這邊我就有注意到song_id是屬於唯一性的id。

你可以用那段值來做唯一性的值。重新思考一下

我要發表回答

立即登入回答