Javascript 使用jQuery和Node在DOM上填充数据的最佳方法
我正在使用节点的Javascript 使用jQuery和Node在DOM上填充数据的最佳方法,javascript,jquery,node.js,dom,socket.io,Javascript,Jquery,Node.js,Dom,Socket.io,我正在使用节点的Socket.io将数据从服务器推送到客户端浏览器。 在客户机上,我使用jQuery填充DOM中返回的行 下面是我用来填充Socket.io返回的数据的代码段 var OverSpeedAlerts = []; var TripCancellation = []; var GeofenceInOutAlerts = []; var ScheduleOverstay = []; var UnSchduledOverstay = []; var SkippedBusStop = []
Socket.io
将数据从服务器推送到客户端浏览器。
在客户机上,我使用jQuery填充DOM中返回的行
下面是我用来填充Socket.io返回的数据的代码段
var OverSpeedAlerts = [];
var TripCancellation = [];
var GeofenceInOutAlerts = [];
var ScheduleOverstay = [];
var UnSchduledOverstay = [];
var SkippedBusStop = [];
var TripDelayAlert = [];
var SkippedUnplannedAlert = [];
var DelayStartEndAlert = [];
var RouteDeviatedAlert = [];
var MultipleBusEntry = [];
声明原型:
Array.prototype.inArray = function (comparer) {
for (var i = 0; i < this.length; i++) {
if (comparer(this[i])) return true;
}
return false;
};
// adds an element to the array if it does not already exist using a comparer
// function
Array.prototype.pushIfNotExist = function (element, comparer) {
if (!this.inArray(comparer)) {
this.unshift(element);
}
};
if (typeof io !== 'undefined') {
var pushServer = io.connect('http://SomeIP:3000');
pushServer.on('entrance', function (data) {
var rows = data.message;
var NumberOfRows = rows.length;
$('#notifications').html(NumberOfRows);
// console.log(rows);
OverSpeedAlerts = [];
TripCancellation = [];
GeofenceInOutAlerts = [];
ScheduleOverstay = [];
UnSchduledOverstay = [];
SkippedBusStop = [];
TripDelayAlert = [];
SkippedUnplannedAlert = [];
DelayStartEndAlert = [];
RouteDeviatedAlert = [];
var MultipleBusEntry = [];
for (var i = 0; i < rows.length; i++) {
if (rows[i].alert_type == 'overspeed') {
OverSpeedAlerts.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'trip_cancellation') {
TripCancellation.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Geofence-In' || rows[i].alert_type === 'Geofence-Out') {
GeofenceInOutAlerts.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Scheduled-Overstay') {
ScheduleOverstay.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Unscheduled-Overstay') {
UnSchduledOverstay.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Skipped Unplanned' || rows[i].alert_type == 'Skipped-Busstop') {
SkippedBusStop.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Delay Start' || rows[i].alert_type == 'Delay End') {
TripDelayAlert.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Route Deviated') {
RouteDeviatedAlert.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Multiple Bus Entry') {
MultipleBusEntry.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
}
CreateOverSpeedGrid();
CreateTripCancellation();
CreateGeofenceGrid();
CreateScheduleOverstayGrid();
CreateUnSchduledOverstayGrid();
CreateTripDelayGrid();
CreateSkippedBusStop();
CreateRouteDeviationAlert();
CreateMultipleBusEntry();
});
pushServer.on('end', function (socket) {
});
}
Array.prototype.inArray=函数(比较器){
for(var i=0;i
处理从套接字接收的数据:
Array.prototype.inArray = function (comparer) {
for (var i = 0; i < this.length; i++) {
if (comparer(this[i])) return true;
}
return false;
};
// adds an element to the array if it does not already exist using a comparer
// function
Array.prototype.pushIfNotExist = function (element, comparer) {
if (!this.inArray(comparer)) {
this.unshift(element);
}
};
if (typeof io !== 'undefined') {
var pushServer = io.connect('http://SomeIP:3000');
pushServer.on('entrance', function (data) {
var rows = data.message;
var NumberOfRows = rows.length;
$('#notifications').html(NumberOfRows);
// console.log(rows);
OverSpeedAlerts = [];
TripCancellation = [];
GeofenceInOutAlerts = [];
ScheduleOverstay = [];
UnSchduledOverstay = [];
SkippedBusStop = [];
TripDelayAlert = [];
SkippedUnplannedAlert = [];
DelayStartEndAlert = [];
RouteDeviatedAlert = [];
var MultipleBusEntry = [];
for (var i = 0; i < rows.length; i++) {
if (rows[i].alert_type == 'overspeed') {
OverSpeedAlerts.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'trip_cancellation') {
TripCancellation.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Geofence-In' || rows[i].alert_type === 'Geofence-Out') {
GeofenceInOutAlerts.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Scheduled-Overstay') {
ScheduleOverstay.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Unscheduled-Overstay') {
UnSchduledOverstay.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Skipped Unplanned' || rows[i].alert_type == 'Skipped-Busstop') {
SkippedBusStop.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Delay Start' || rows[i].alert_type == 'Delay End') {
TripDelayAlert.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Route Deviated') {
RouteDeviatedAlert.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
else if (rows[i].alert_type == 'Multiple Bus Entry') {
MultipleBusEntry.pushIfNotExist(rows[i], function (e) {
return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
});
}
}
CreateOverSpeedGrid();
CreateTripCancellation();
CreateGeofenceGrid();
CreateScheduleOverstayGrid();
CreateUnSchduledOverstayGrid();
CreateTripDelayGrid();
CreateSkippedBusStop();
CreateRouteDeviationAlert();
CreateMultipleBusEntry();
});
pushServer.on('end', function (socket) {
});
}
if(io的类型!=“未定义”){
var pushServer=io.connect('http://SomeIP:3000');
pushServer.on('entry',函数(数据){
var rows=data.message;
var NumberOfRows=rows.length;
$('#notifications').html(NumberOfRows);
//console.log(行);
超速率=[];
TripCancellation=[];
GeofenceInOutAlerts=[];
计划逾期逗留=[];
UnSchduledOverstay=[];
SkippedBusStop=[];
TripDelayAlert=[];
SkippedUnplandalert=[];
DelayStartEndAlert=[];
RoutedViatedAlert=[];
var MultipleBusEntry=[];
对于(变量i=0;i
上述功能之一如下所示。Rest是在DOM的其他部分填充数据的类似函数
function CreateOverSpeedGrid() {
$('#tabs ul').find('a:contains("Overspeed Alerts")').html('OverSpeed Alerts(' + OverSpeedAlerts.length + ')');
if (OverSpeedAlerts.length != 0) {
$('#notifyOverspeed table').html('');
$('#notifyOverspeed table').append('<tr class="ui-widget-header"> <th> Depot </th> <th> Route </th> <th> Schedule </th> <th> Trip Number </th><th>Trip Direction</th> <th> Alert Summary</th> <th> Alert Details </th> <th> Generated On </th> </tr>'); //new Date([UNIX Timestamp] * 1000);
for (var i = 0; i < OverSpeedAlerts.length; i++) {
$('#notifyOverspeed table').append('<tr> <td>' + OverSpeedAlerts[i].depot_name + '</td> <td>' + OverSpeedAlerts[i].route_name + '</td> <td>' + OverSpeedAlerts[i].schedule_no + '</td> <td>' + OverSpeedAlerts[i].trip_number + ' </td> <td>' + OverSpeedAlerts[i].trip_direction + '</td><td> ' + OverSpeedAlerts[i].alert_sub + ' </td> <td title="' + ConvertToValidTooltip(OverSpeedAlerts[i].alert_msg) + '" style="text-decoration:underline;cursor:pointer;"> ' + "Place mouse pointer to view message" + ' </td> <td>' + new Date(OverSpeedAlerts[i].alert_gen_date_time * 1000) + ' </td> </tr>');
}
}
}
函数CreateOverSpeedGrid(){
$('#tabs ul').find('a:contains(“OverSpeedAlerts”)).html('OverSpeedAlerts('+OverSpeedAlerts.length+'));
如果(过速极限长度!=0){
$('#表').html('');
$(“#notifyOverspeed table”).append(“‘车辆段路线计划行程编号’);//生成的行程方向警报摘要警报详细信息’;//新日期([UNIX时间戳]*1000);
对于(变量i=0;i
上面的代码工作正常。但问题是,由于每10秒从套接字接收到如此多的推送消息,浏览器无法处理如此多的数据并挂断
有没有更好的方法呢???不知道你的应用程序的详细信息,我将假设你需要所有这些数据
var io /*some lib*/, pushServer, alertTypes, alterTypesMapping, $notifications, lookupCache;
//i use the -Length fields to store the "previous" length, so i know if the dom needs updating at all
// and what part is new, no need to re-render perfectly valid html
alertTypes = {
OverSpeedAlerts: [],
OverSpeedAlertsLength: 0,
TripCancellation: [],
TripCancellationLength: 0,
GeofenceInOutAlerts: [],
GeofenceInOutAlertsLength: 0,
ScheduleOverstay: [],
ScheduleOverstayLength: 0,
UnSchduledOverstay: [], //scheduled? sorry ide with spelling check
UnSchduledOverstayLength: 0,
SkippedBusStop: [],
SkippedBusStopLength: 0,
TripDelayAlert: [],
TripDelayAlertLength: 0,
SkippedUnplannedAlert: [],
SkippedUnplannedAlertLength: 0,
DelayStartEndAlert: [],
DelayStartEndAlertLength: 0,
RouteDeviatedAlert: [],
RouteDeviatedAlertLength: 0
};
//mapping from types to their lists (some types map to the same list)
alterTypesMapping = {
'overspeed': 'OverSpeedAlerts',
'trip_cancellation': 'TripCancellation',
'Geofence-In': 'GeofenceInOutAlerts',
'Geofence-Out': 'GeofenceInOutAlerts',
'Scheduled-Overstay': 'ScheduleOverstay',
'Unscheduled-Overstay': 'UnSchduledOverstay',
'Skipped Unplanned': 'SkippedBusStop',
'Delay Start': 'TripDelayAlert',
'Delay End': 'TripDelayAlert',
'Route Deviated': 'RouteDeviatedAlert',
'Multiple Bus Entry': 'MultipleBusEntry'
};
//cache dom lookup
$notifications = $('#notifications');
//we serialize the relevant message parts into an unique id, used for de-duping
//<id> => <alert_type>|<device_id>|<alert_gen_date_time>
lookupCache = {};
function process_data (data) {
var i, l, rows, id;
rows = data.message;
l = rows.length;
//update dom row count
$notification.html(l);
for (i=0; i<l; ++i) { //caching length in l, ++i is faster than i++
id = rows[i].alert_type + '|' + rows[i].device_id + '|' + rows[i].alert_gen_date_time;
if (!lookupCache[id]) {
lookupCache[id] = 1; //set it to truthy so next time around its there
//not in cache push it to the relevant list
//you used unshift here, that's essentially moving all other elements in the list one spot and
//adding the new one at index 0 (speed O(n) eg increases with more elements in the list)
//instead you can push the new element to the end, (speed O(1) constant speed)
// and when iterating the list doing that in reverse
alertTypes[alterTypesMapping[rows[i].alert_type]].push(rows[i]);
}
}
updateDom();
}
function updateDom () {
var keys, i, l, html;
//here we check all length fields in the alertTypes and see if the actual list length
//is greater than their -Length
//if so we update the relevant dom
keys = Object.keys(alertTypes);
for (i=0, l=keys.length; i<l; ++i) {
//skip the -Length keys
if (keys[i].match('Length')) {
continue;
}
//please add a data-type="<type>" to the a's, so much better to lookup by attribute instead of text matching content
$('#tabs ul a[data-type="' + keys[i] + '"]').html(keys[i] + '(' + alertTypes[keys[i] + 'Length'] + ')');
//since well only update the dom, i presume at this point there is a dom with the table with headers
//(use thead and th for this please)
//(and use tbody for a table's body)
//now we iterate the new elements (from list.length back to key-Length)
//j starts at the length of the list, and ends at m, the previous length
//counting backwards
html = [];
for (j=alertTypes[keys[i]].length, m=alertTypes[keys[i] + 'Length']; j>m; --j) {
//array join is almost always faster than string concatenation
//since strings are not mutable in js (eg. you create a new string every +)
html.push([
'<tr>',
'<td>',
alertTypes[keys[i]].depot_name,
'</td>',
'<td>',
alertTypes[keys[i]].route_name,
'</td>',
'<td>',
alertTypes[keys[i]].schedule_no,
'</td>',
'<td>',
alertTypes[keys[i]].trip_number,
'</td>',
'<td>',
alertTypes[keys[i]].trip_direction,
'</td>',
'<td>',
alertTypes[keys[i]].alert_sub,
'</td>',
'<td ',
'title="',
ConvertToValidTooltip(alertTypes[keys[i]].alert_msg),
'" style="text-decoration:underline;cursor:pointer;">Place mouse pointer to view message',
'</td>',
'<td>',
new Date(OverSpeedAlerts[i].alert_gen_date_time * 1000),
'</td>',
'</tr>'
].join(''));
}
//and finally we update the key-Length so next time well only add what is newer than what we are about to add
alertTypes[kesy[i] + 'Length'] = alertTypes[keys[i]].length;
//get the dom element we have to update
$('#' + keys[i] + ' tbody').prepend(html.join(''));
}
}
if (io !== undefined) { //no need for typeof when checking undefined, check undefined directly with equality (eg. undefined === undefined)
pushServer = io.connect('http://SomeIP:3000');
pushServer.on('entrance', process_data);
}