I need to pass data between two autonomic user scripts - ideally without touching the unsafeWindow object - and I thought using custom events would be the way to go. I thought of something like this (let us disregard the MSIE model for the purpose of the example):
addEventListener("customEvent", function(e) {
alert(e.data);
});
var custom = document.createEvent("HTMLEvents");
custom.initEvent("customEvent", true, true);
custom.data = "Some data...";
dispatchEvent(custom);
This works nicely in the standard Javascript environment and within one user script, but when the event is fired by the user script and caught outside of it or inside another user script, the data property is undefined in Chromium. I suppose I could just save the passed data in the sessionStorage, but it is far from seamless. Any other elegant solutions? Perfection need and can be achieved, I can feel it.
Yes, you can use a MessageEvent or a CustomEvent.
Example usage:
//Listen for the event
window.addEventListener("MyEventType", function(evt) {
alert(evt.detail);
}, false);
//Dispatch an event
var evt = new CustomEvent("MyEventType", {detail: "Any Object Here"});
window.dispatchEvent(evt);
pass object with more details as attributes:
var event = new CustomEvent('build', { detail: { 'detail1': "something", detail2: "something else" }});
function eventHandler(e) {
log('detail1: ' + e.detail.detail1);
log('detail2: ' + e.detail.detail2);
}
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
new CustomEvent is not supported in IE https://caniuse.com/#search=CustomEvent
Here is a version which also works on IE9+:
//Listen for the event
window.addEventListener("MyEventType", function(evt) {
alert(evt.detail.test); //alerts "Any Object Here"
}, false);
//Dispatch an event
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('MyEventType', false, false, { test: "Any Object Here" });
window.dispatchEvent(evt);
Related
I need to pass data between two autonomic user scripts - ideally without touching the unsafeWindow object - and I thought using custom events would be the way to go. I thought of something like this (let us disregard the MSIE model for the purpose of the example):
addEventListener("customEvent", function(e) {
alert(e.data);
});
var custom = document.createEvent("HTMLEvents");
custom.initEvent("customEvent", true, true);
custom.data = "Some data...";
dispatchEvent(custom);
This works nicely in the standard Javascript environment and within one user script, but when the event is fired by the user script and caught outside of it or inside another user script, the data property is undefined in Chromium. I suppose I could just save the passed data in the sessionStorage, but it is far from seamless. Any other elegant solutions? Perfection need and can be achieved, I can feel it.
Yes, you can use a MessageEvent or a CustomEvent.
Example usage:
//Listen for the event
window.addEventListener("MyEventType", function(evt) {
alert(evt.detail);
}, false);
//Dispatch an event
var evt = new CustomEvent("MyEventType", {detail: "Any Object Here"});
window.dispatchEvent(evt);
pass object with more details as attributes:
var event = new CustomEvent('build', { detail: { 'detail1': "something", detail2: "something else" }});
function eventHandler(e) {
log('detail1: ' + e.detail.detail1);
log('detail2: ' + e.detail.detail2);
}
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
new CustomEvent is not supported in IE https://caniuse.com/#search=CustomEvent
Here is a version which also works on IE9+:
//Listen for the event
window.addEventListener("MyEventType", function(evt) {
alert(evt.detail.test); //alerts "Any Object Here"
}, false);
//Dispatch an event
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('MyEventType', false, false, { test: "Any Object Here" });
window.dispatchEvent(evt);
I looked through many threads at SO, but could not find an answer that solves my problem. So, I define a CKEditor instance like so:
var editor = $('#test-editor');
editor.ckeditor(function() {}, {
customConfig: '../../assets/js/custom/ckeditor_config.js',
allowedContent: true
});
However I do not know how can I catch change event. This is what I tried:
var t = editor.ckeditor(function() {
this.on('change', function () {
console.log("test 1");
});
}, {
customConfig: '../../assets/js/custom/ckeditor_config.js',
allowedContent: true
});
editor.on('change', function() {
console.log("test 2");
});
t.on('change', function() {
console.log("test 3");
});
All these three attempts ended in failure. I should add, that I do not want to loop through all editors on a page, I just want to address one particular editor rendered at component with #test-editor. How can I do that?
The jQuery ckeditor() method returns a jQuery object, which exposes only 5 events of CKEditor in its event handling. In order to use other events, you need to use the CKEditor.editor object by accessing the editor property of the jQuery object.
So, you need to use something like this:
var myeditor = $('#test-editor').ckeditor({
customConfig: '../../assets/js/custom/ckeditor_config.js',
allowedContent: true
});
myeditor.editor.on('change', function(evt) {
console.log('change detected');
});
I don't unterstand this:
I try to create a custom event which should be fired when a list is fully loaded in a table body. Like this (executes after list is loaded):
var event = new Event('mklistloaded', {
name: 'listname'
});
document.dispatchEvent(event);
And this is the "receiving" end:
document.addEventListener('mklistloaded', function(e) {
console.log('mklistloaded event: ' + JSON.stringify(e));
});
But console log prints out:
mklistloaded event: {"isTrusted":false}
That's quite the same as described in the mozilla example:
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
What am I doing wrong here?
You missed the section in the docs "Adding custom data – CustomEvent()"
document.addEventListener('mklistloaded', function(e) {
console.log('mklistloaded detail: ', e.detail);
});
// use CustomEvent() instead of Event()
var event = new CustomEvent('mklistloaded', {
'detail': 'listname'
});
document.dispatchEvent(event);
Note that it seems to require using the property name detail
I have an event listener setup using jQuery like this:
$(document).on('my-custom-event', function(e, custom_id) {
console.log('the ID is: ' + custom_id);
});
It is easy to trigger this with jQuery.trigger, like this:
$(document).trigger('my-custom-event', '12345');
But I am trying to figure out how to trigger it with vanilla javascript, and also ensure that custom_id gets passed properly.
For example, this does not work. It triggers the event, but does not pass the custom_id argument:
var e = new CustomEvent('my-custom-event', 'asdf')
document.dispatchEvent(e)
How can I use plain javascript to trigger the event and also pass the custom_id argument?
According to MDN, detail can be used to pass data when initializing the event.
Here is an example:
// add listener
// let's be cool and add it to the document for this example
document.addEventListener('EVENT-NAME', function (e) {
// do something
// use e.detail for the data
});
// create event
var event = new CustomEvent('EVENT-NAME', {
detail: 'legit data'
});
// dispatch event
document.dispatchEvent(event);
I have also created a demo: http://jsfiddle.net/dirtyd77/02p2o7ut/1/
Hopefully this helps and let me know if you have any other questions!
EDIT:
Unfortunately, there is no way (that I know of) to do what you are asking, however, there is a workaround.
jQuery events have a property called originalEvent. You could check to see if that value exists in the event that custom_id does not. Here is how you could do this:
DEMO: http://jsfiddle.net/dirtyd77/02p2o7ut/2/
$(document).on('my-custom-event', function (e, custom_id) {
// if custom_id not defined, will check e.originalEvent.detail
custom_id = custom_id || e.originalEvent.detail;
console.log('the ID is: ' + custom_id);
});
// trigger jQuery event
$(document).trigger('my-custom-event', '12345');
$('#customEvent').click(function () {
// create event
var event = new CustomEvent('my-custom-event', { detail: '12345' });
// dispatch event
document.dispatchEvent(event);
});
Getting a weird error for .stopPropagation() in IE
My code is as follows:
$(document).ready(function(){
var options = {
$this: "",
$menuItems: $(".mainMenu > li"),
$blueBar: $(".blueBar"),
$submenuBg: $("#submenuBg"),
$sortOptions: $(".sortOptions"),
$submenu: $(".submenu"),
submenuClass: ".submenu",
blueBarClass: ".blueBar",
selectedClass: "selected",
sortOptionsClass: ".sortOptions",
subSubmenu: "ul",
subSubmenuClass: "sub-submenu"
};
$sortBy.toggle(function(){
options.$this = $(this);
ddlShow(event, options);
},
function(){
options.$this = $(this);
ddlHide(options);
}
);
});
var ddlShow = function(event, options){
event.stopPropagation();
options.$this.children(options.sortOptionsClass).show();
}
var ddlHide = function(options){
options.$this.children(options.sortOptionsClass).hide();
}
Getting the following error:
object doesn't support property or method 'stoppropagation'
Code works fine in Chrome and Firefox.
How do I solve this?
Note: The same code works fine without the object options.
in IE we do not have stopPropogation method available in javascript on event object. If you will search in google you will find different implementation of event object in ie and webkit based browsers. So in order to correct that jQuery has given a single interface for handling it so you should use jQuery way of doing events to stop getting this errors.
You can read this article to get more clarification http://www.quirksmode.org/js/introevents.html
replace
e.stopPropagation(); with
if (e.stopPropagation) e.stopPropagation(); else e.cancelBubble = true; worked for me
Thanks
Have your toggle handlers accept the event parameter from jQuery:
$sortBy.toggle(function(event){ // ADDED PARAMETER
options.$this = $(this);
ddlShow(event, options);
},
If you do not do this, then when calling ddlShow the argument event resolves to window.event, which is an object that has not been "normalized" by jQuery for cross-browser consistency.
Here:
$sortBy.toggle(function(){ <-- you must get the event object from jquery.
options.$this = $(this);
ddlShow(event, options);
},
function(){
options.$this = $(this);
ddlHide(options);
}
);
Then:
$sortBy.toggle(function(event){ ... ddlShow(event, options); }...
JQuery by default passes the event object, you just have to declare it in the function arguments to use it within the function.
$sortBy.toggle(function(event){
// Do your stuff here
})
Also, It's not advisable to use event as argument name.
event refers to the global event object. Define something like e
function(e, options){
e.stopPropagation();
//do stuff here
}