您会收到有关 SO 中新答案和内容的通知。(顶部 StackExchange 旁边的红色标记)
即使用户不与浏览器交互(不重新加载),通知标记也会出现。
我怎样才能实现这样的功能?
您会收到有关 SO 中新答案和内容的通知。(顶部 StackExchange 旁边的红色标记)
即使用户不与浏览器交互(不重新加载),通知标记也会出现。
我怎样才能实现这样的功能?
我会研究 WebSockets、长轮询、SignalR、NodeJS 等主题,以获取类似功能的实现示例。
我认为 WebSockets 是这里真正的解决方案。但是,如果您不想走得太远,您可以使用客户端的计时器来检查是否存在新通知。
$(document).ready(function() {
startTimer = function() {
window.setTimeout(checkNotifications, 15000);
},
checkNotifications = function() {
$.ajax({
url: "/notifications/check",
success: function(result) {
//show red mark if notifications exist
startTimer(); //start timer to check again
}
});
}
startTimer();
});
由于您询问的是 Javascript,我会使用某种数据库或 XML 文档来存储通知,然后只检查新通知。
您可以使用 PHP 从这样的自定义脚本中使用 Jquery (AJAX) 调用 XML 数据:(我尚未对此进行测试,但我希望有人觉得它有用)
示例 XML:
<?xml version="1.0" encoding="utf-8"?>
<notifications>
<user>
<id>673154978</id>
<notes>
<note>
<id>98465321865</id>
<date>1374112224</date>
<userID>168948521</userID>
<url>/question?q=894251&a=1364567891</url>
<type>answer-question</type>
<topic>Can you tell me some Lorem Ipsum?</topic>
<content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tempus nisi ac arcu congue, a scelerisque tellus facilisis.</content>
</note>
<note>
<date>1374112570</date>
<userID>168982417</userID>
<url>/question?q=894251&a=1364567987</url>
<type>answer-question</type>
<topic>Can you tell me some Lorem Ipsum?</topic>
<content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tempus nisi ac arcu congue, a scelerisque tellus facilisis.</content>
</note>
</notes>
</user>
</notifications>
PHP:
<?php
function getUserInfoByID($userID) { # For converting the ID to the username
$foundUser = false; # Default false
$users = simplexml_load_file('data/usersAndIDs.xml'); # Load this XML as SimpleXML object
foreach($users as $userTag) { # Cycle through users
if($userTag->userID = $userID) { # Does this match?
$foundUsername = $userTag; # Ah, here's the username and the other info like last time active, list of seen notifications, etc.
break; # Stop loop as we're now done
}
}
return $foundUser; # Return the info. May be bool(false) or the username
}
if(isset($_POST['type']) && $_POST['type'] != '') { # Is this set?
if($_POST['type'] == 'notifications') { # Is it "nofitioncations?"
$notifications = simplexml_load_file('data/notifications.xml'); # Load this XML as SimpleXML object
foreach($notifications as $users) { # Go through XML per "user" tag
if($users->id == $_POST['userID']) { # Find whose notifications to return
#Either just go straight to encoding for the Javascript to form, as seen below
# echo json_encode($users->notes); # JSON encoding for the Javascript to read. Remove the pound symbol at the beginning of this line to use it and comment out or remove the rest of the script that creates this in the PHP
# Or get it all into order now.
$theUserInfo = getUserInfoByID($_POST['userID']); # Get all of the users info by the sent ID
$userSeenNotes = json_decode($theUserInfo->seenNotes); # seenNotes tag in the user XML may contain an array in JSON format for easy storage like <seenNotes>["6816818618","61861681861","436881613","681898213","46848153"]</seenNotes>
foreach($users->notes as $note) { # Cycle through notes
if(!in_array($note->id, $userSeeNotes)) { # Already been seen? If not, then continue. You may wish to also check if it was recent enough and then make it show up slightly darker to show that it's been seen already. Seen in this case means they followed the link. You'd want to write that to data/usersAndIDs.xml as I've used earlier in this script
$type = explode($note->type, '-'); # From "answer-question" to array('answer','question')
$answerersInfo = getUserByID($note->userID); # Get all of the answerer's info by the ID in data/notifications.xml
echo
'<div class="notification $type[0]">' . # This is the notification -- Lines do not need the "' . (line break) '" stuff. I added that to add comments so that they're not part of the HTML
'<a class="note" href="http://yoursite.com' . $note->url . '">' . # Link all text to specific answer
'<span class="note-$type[1]">' . $note->topic . '</span>' . # Question topic. I would suggest cutting this off using a set width and height with "overflow: hidden;" in CSS
'<span class="note-$type[0]">' . $note->content . '"</span>' . # The reply answer. I also suggest cutting this off
'<span class="note-user">by ' . $answerersInfo->username . '</span>' . # Probably would appear very small just as a preview
'<span class="note-date">' . gmdate("r", $note->date) . '</span>' . # Date in GMT in this format: "Thu, 21 Dec 2000 16:01:07 +0200". Could also use date()
'</a>
</div>';
}
}
}
}
}
}
?>
Javascript:(为我的 PHP 改编 Leantraxxx 上面的答案)
$(document).ready(function() {
startTimer = function() {
window.setTimeout(checkNotifications, 15000); // 1000 * (seconds to wait)
},
checkNotifications = function() {
$.post('notifications.php', { 'userID': '673154978', 'type': 'notifications' },
function(data){
$('div#notifications').append(data);
}); // Use '}, "json");' if you're going to format the info from JSON here. As is, the PHP will format it the way I wanted to, but you can remove that and uncomment the part about JSON encoding (Line 23-ish)
startTimer(); //start timer to check again
}
startTimer();
});