Javascript 所有事件的HTML5事件源侦听器?
我在JavaScript客户端应用程序中使用EventSource提供推送通知。 我可以像这样附加事件侦听器:Javascript 所有事件的HTML5事件源侦听器?,javascript,html,server-sent-events,Javascript,Html,Server Sent Events,我在JavaScript客户端应用程序中使用EventSource提供推送通知。 我可以像这样附加事件侦听器: source.addEventListener('my_custom_event_type', function(e) { console.log(e.data); }, false); source.addEventListener('*', function(e) { console.debug('Event with no listener attached: ', e
source.addEventListener('my_custom_event_type', function(e) {
console.log(e.data);
}, false);
source.addEventListener('*', function(e) {
console.debug('Event with no listener attached: ', e);
}, false);
但是我想监视从服务器推送的所有事件(基本上是为了调试),因此如果发送了某个事件,但它没有事件侦听器,我可以很容易地找到它。我的意思是,我不想“忽略”所有没有绑定eventListeners的事件
我希望这样做:
source.addEventListener('my_custom_event_type', function(e) {
console.log(e.data);
}, false);
source.addEventListener('*', function(e) {
console.debug('Event with no listener attached: ', e);
}, false);
但是,像上一篇那样的规范和教程没有具体说明这是否可行
另一方面,它可能是一些firefox/chrome扩展,允许监视所有服务器事件或其他内容。这些东西确实有助于开发推送通知
谢谢 我自己找到了一个解决方案,它也极大地改进了EventSource接口 服务器端:不发送事件类型,只包含一个额外的数据字段(我总是使用json)。所以不是
event: eventName
data: {mykey: 'myvalue'}
我改为从服务器发送:
data: {mykey: 'myvalue', eventName: 'eventName'}
客户端:现在我可以使用EventSource onmessage回调,它会对每个没有事件类型的消息触发
对于绑定事件侦听器,我创建了一个具有主干.event功能的包装器类。结果是:
// Server Sent Events (Event Source wrapper class)
var MyEventSource = (function() {
function MyEventSource(url) {
var self = this;
_.extend(this, Backbone.Events);
this.source = new EventSource(url);
this.source.onmessage = function(event) {
var data, eventName;
var data = JSON.parse(event.data);
var eventName = data.eventName; delete data.eventName;
// Now we can monitor all server sent events
console.log('app.server.on ', eventName, '. Data: ', data);
self.trigger(eventName, data);
};
}
return MyEventSource;
})();
现在有了这个包装类,我可以很容易地扩展功能,所有服务器发送的事件都可以很容易地监控,这要归功于扩展主干事件。这个类中的事件处理功能要强大得多
用法示例:
var source = new MyEventSource('url/of/source');
// Add event listener
source.on('eventName', function(data) {
console.log(data);
});
// Fire a event (also very useful for testing and debugging!!)
source.trigger('eventName', { mykey: 'myvalue' });
// Unbind event listener (very important for complex applications)
source.off('eventName');
现在我有了一个易于处理、扩展、调试和测试的组件。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script>
var content = '';
if(typeof(EventSource)!=="undefined")
{
var source = new EventSource("demo_sse.php");
source.onmessage = function(event)
{
content+=event.data + "<br>";
$("#result").html(content);
};
}
else
{
$("#result").html("Sorry, your browser does not support server-sent events...");
}
</script>
var内容=“”;
if(typeof(EventSource)!=“未定义”)
{
var source=neweventsource(“demo_sse.php”);
source.onmessage=函数(事件)
{
content+=event.data+“
”;
$(“#结果”).html(内容);
};
}
其他的
{
$(“#结果”).html(“对不起,您的浏览器不支持服务器发送的事件…”);
}
我知道这不是一个事件源,但我也在寻找同样的东西(一种在不知道事件类型的情况下捕获所有传入事件的方法)。由于没有对发送这些事件的服务器进行任何控制,我最终只是用一个XHR编写了它,以防其他人遇到以下情况:
function eventStream(path, callback){
//Create XHR object
var xhr = new XMLHttpRequest();
//initialize storage for previously fetched information
var fetched='';
//Set readystatechange handler
xhr.onreadystatechange=function(){
//If the connection has been made and we have 200, process the data
if(xhr.readyState>2 && xhr.status==200){
//save the current response text
var newFetched=xhr.responseText;
//this is a stream, so responseText always contains everything
//from the start of the stream, we only want the latest
var lastFetch=xhr.responseText.replace(fetched, '');
//Set the complete response text to be removed next time
var fetched=newFetched;
//callback to allow parsing of the fetched data
callback(lastFetch);
}
};
//open and send to begin the stream;
xhr.open('GET', path, true);
xhr.send();
}
parseEvents=function(response){
var events=[];
//split out by line break
var lines=response.split("\n");
//loop through the lines
for(var i=0;i<lines.length;i++){
//each event consists of 2 lines, one begins with
//"name:", the other with "data"
//if we hit data, process it and the previous line
if(lines[i].substr(0, lines[i].indexOf(':'))=='data'){
//add this event to our list for return
events.push({
//get the event name
name: lines[i-1].split(':')[1].trim(),
//parse the event data
data: $.parseJSON(lines[i].substr(lines[i].indexOf(':')+1).trim())
});
}
}
//return the parsed events
return events;
};
evenStream('http://example.com/myEventPath', function(response){
var events=parseEvents(response);
});
函数事件流(路径,回调){
//创建XHR对象
var xhr=new XMLHttpRequest();
//为以前获取的信息初始化存储
获取的var=“”;
//设置readystatechange处理程序
xhr.onreadystatechange=函数(){
//如果已经建立了连接,我们有200个,请处理数据
如果(xhr.readyState>2&&xhr.status==200){
//保存当前响应文本
var newFetched=xhr.responseText;
//这是一个流,所以responseText总是包含所有内容
//从流的开始,我们只想要最新的
var lastFetch=xhr.responseText.replace(已获取“”);
//设置下次删除的完整响应文本
var fetched=newFetched;
//回调以允许对提取的数据进行分析
回调(lastFetch);
}
};
//打开并发送以开始流;
xhr.open('GET',path,true);
xhr.send();
}
parseEvents=函数(响应){
var事件=[];
//断线分开
变量行=响应。拆分(“\n”);
//环线
对于(var i=0;i以上的用户tothemario
,我需要找出这个问题的线索
似乎可以使用自定义类型将事件发送回浏览器,但为了触发消息事件,必须将侦听器分配给新类型,而不是消息
类型
如果您看一下下面的客户端代码,它将很有希望说明这一点
对于上下文,我的服务器发送一个自定义类型为CustomType
的事件。因此,我向该类型订阅了一个事件侦听器,并为message
添加另一个侦听器,作为其他所有内容的总括
在此工作流中,将触发一个事件,该事件通过另一个侦听器CustomType
进入浏览器
<script type="text/javascript">
var CustomTypeList = [];
function EventSystemOpen(e) {
console.log("EventSystemOpen", e);
}
function EventSystemError(e) {
console.log("EventSystemOpen", e);
if (e.readyState == EventSource.CLOSED) {
//
}
}
function GotServerEventMessage(e) {
console.log("GotServerEventMessage", e);
}
function GotCustomType(e) {
CustomTypeList.push(JSON.parse(e.data));
console.log("Added CustomType", e, JSON.parse(e.data), CustomTypeList);
}
if (!!window.EventSource) {
var source = new EventSource('api/listen');
source.addEventListener('open', EventSystemOpen, false);
source.addEventListener('error', EventSystemError, false);
source.addEventListener('message', GotServerEventMessage, false);
source.addEventListener('CustomType', GotCustomType, false);
}
</script>
var CustomTypeList=[];
函数EventSystemOpen(e){
console.log(“EventSystemOpen”,e);
}
函数EventSystemError(e){
console.log(“EventSystemOpen”,e);
if(e.readyState==EventSource.CLOSED){
//
}
}
函数GotServerEventMessage(e){
log(“GotServerEventMessage”,e);
}
函数类型(e){
push(JSON.parse(e.data));
log(“添加了CustomType”,e,JSON.parse(e.data),CustomTypeList);
}
如果(!!window.EventSource){
var source=neweventsource('api/listen');
source.addEventListener('open',EventSystemOpen,false);
source.addEventListener('error',EventSystemError,false);
source.addEventListener('message',GotServerEventMessage,false);
source.addEventListener('CustomType',GotCustomType,false);
}
“对没有事件类型的每条消息都会触发Onmessage回调”。这对我来说是非常有用的信息。谢谢。仅供参考:调用Onmessage=some_函数;
与调用addEventListener(“message”,some_函数)完全相同
。很明显,没有事件类型的消息与事件类型为“message”的消息是相同的。您好,Themario。由于某些原因,JSON.parse(event.data)对我不起作用。请您提供服务器端生成数据的方法:{mykey:'myvalue',eventName:'eventName}?提前感谢。tothemario
!感谢您的回答,基于您的指导,我尝试了源代码。addEventListener('eventName',MyHander,false);
这在没有包装器的情况下可以工作。(请参阅下面的答案以获取完整示例)这将不起作用,因为onmessa