addEventListener syntax with variable function name - javascript

In my Firefox extension, I create a popup menu dynamically. Originally, I used this line on each menu item:
menuFunc.setAttribute("oncommand","MainExtension.MyPlugin." + functionName + "();");
where functionName is a string with the name of the function to be called for that menu item. This worked fine. When I uploaded my extension to the Mozilla Addons page, the automated code validation program flagged this line and said that using setAttribute to set oncommand in this way was not secure and that addEventListener should be used instead. I switched to this syntax:
menuFunc.addEventListener("oncommand",function() {MainExtension.MyPlugin[functionName]},false);
but now nothing happens when I click on a menu item.
Is my syntax off or is there something else wrong? I don't think the problem is the common 'this' reference error. I tried removing all uses of 'this' from one of the functions and it still did not work. It seems like the functions are not being called at all. No errors are being generated either.

Update:
The command action is attached using just command, not oncommand:
menuFunc.addEventListener("command", MainExtension.MyPlugin[functionName], false);
You should be able to just do:
menuFunc.oncommand = MainExtension.MyPlugin[functionName];

Just a guess: Does it help to use true instead of false as the third parameter in order to capture the event?

Related

Best Practice : Call a function from chrome dev console [duplicate]

In Chrome's JavaScript console, how do I call a function that belongs to a .js file included in the webpage I am viewing?
If it's inside a closure, i'm pretty sure you can't.
Otherwise you just do functionName(); and hit return.
An example of where the console will return ReferenceError is putting a function inside a JQuery document ready function
//this will fail
$(document).ready(function () {
myFunction(alert('doing something!'));
//other stuff
})
To succeed move the function outside the document ready function
//this will work
myFunction(alert('doing something!'));
$(document).ready(function () {
//other stuff
})
Then in the console window, type the function name with the '()' to execute the function
myFunction()
Also of use is being able to print out the function body to remind yourself what the function does. Do this by leaving off the '()' from the function name
function myFunction(alert('doing something!'))
Of course if you need the function to be registered after the document is loaded then you couldn't do this. But you might be able to work around that.
This is an older thread, but I just searched and found it. I am new to using Web Developer Tools: primarily Firefox Developer Tools (Firefox v.51), but also Chrome DevTools (Chrome v.56)].
I wasn't able to run functions from the Developer Tools console, but I then found this
https://developer.mozilla.org/en-US/docs/Tools/Scratchpad
and I was able to add code to the Scratchpad, highlight and run a function, outputted to console per the attched screenshot.
I also added the Chrome "Scratch JS" extension: it looks like it provides the same functionality as the Scratchpad in Firefox Developer Tools (screenshot below).
https://chrome.google.com/webstore/detail/scratch-js/alploljligeomonipppgaahpkenfnfkn
Image 1 (Firefox):
http://imgur.com/a/ofkOp
Image 2 (Chrome): http://imgur.com/a/dLnRX
You can invoke it using
window.function_name()
or directly without window like
function_name()
Basically, there are two cases here:
Your function is in global scope. In that case, simply open a console and call it yourFunction()
Your function is scoped inside some other function(s) and is not accessed globally. In that case, you can open a Sources tab, locate your .js file, place a breakpoint anywhere at the bottom of the outer function (you might need to refresh a page after that if the code have already been run) and call yourFunction() in console. Also, while at breakpoint you may do something like window.yourFuncRef = yourFunction in console, to be able to access it later at any time.
I just discovered this issue. I was able to get around it by using indirection. In each module define a function, lets call it indirect:
function indirect(js) { return eval(js); }
With that function in each module, you can then execute any code in the context of it.
E.g. if you had this import in your module:
import { imported_fn } from "./import.js";
You could then get the results of calling imported_fn from the console by doing this:
indirect("imported_fn()");
Using eval was my first thought, but it doesn't work. My hypothesis is that calling eval from the console remains in the context of console, and we need to execute in the context of the module.

Video.js: Adding a menu to the control bar via plugin

I'm trying to a menu to the control bar of a video.js player via a plugin. Here's a demo of my end goal. The problem is that the demo is adding a menu to the control bar in video.js itself whereas I want a plugin that adds a menu.
So far I have been able to create a plugin that adds a MenuButton to the control bar, but I'm unable to populate the menu with any menu items.
Here's a demo of where I'm at now.
The problem is when I try to create a new PlaybackRateMenuItem object with new videojs.PlaybackRateMenuItem(this, {rate: rates[i] + 'x'}). The JS console throws the following error on line 805 of video.dev.js:
Uncaught TypeError: Cannot read property 'guid' of undefined
This corresponds to the following function in the unminified version:
vjs.bind = function(context, fn, uid) {
// Make sure the function has a unique ID
if (!fn.guid) {
fn.guid = vjs.guid++;
}
... omitted ...
};
Or more specifically, this line: if (!fn.guid) {.
From stepping through in a debugger, I see that fn is being passed in as undefined and the caller of the function is:
vjs.bind(this.player(), this.player().reportUserActivity);
When this function is being called, this.player() returns a defined value, but once vjs.bind is called, both arguments become undefined and I have no idea why. Any ideas or a point in the right direction? Thanks!
Turns out I had two major problems here.
Overriding the createMenu method instead of the createItems method for my class that extended the videojs.MenuButton class.
The this argument to the constructor of the videojs.MenuItem class must be the videojs player object, not just this. Problem is that the name of this object is mangled in the minified version of video.js. For this situation, I found that using this.c was the player object, but overall, I found it easier to just use the unminified version, video.dev.js, and not have to deal with the name mangling. In that case, using this.player_ was correct.

JavaScript Invalid Argument

I have a complex function that loops through the elements during the onSuccess: of my js and I'm getting the following error that I haven't seen before.
exception encountered : {"message": "Invalid argument.", "description": "Invalid argument.", "number": -2147024809, "name": "Error"}
The js function looks like this:
if(Object.isArray(list)){
list.each(function(listItem, index){
if(!Object.isUndefined(listItem.disabled)){
listItem.disabled = disableFlag;
}
});
}
that is called from the onSuccess: portion of an Update. My html is a button that is calling the noted function from an onclick. When I run it the onException: always happens and I'm getting the error by:
Object.toJSON(exception)
Has anyone seen this before? I have tried playing around with the functionality and it seems that when I use the button to do what it's supposed to do after a specific sequence of events is the only time this happens. So, I placed an arbitrary link on the page and wanted to see if I clicked that, what would happen and it updated the JSON object on the page and allowed for me to use the button for it's set action without the error. Any help would be appreciated.
Most of the time this kind of error happens in IE when you set an attribute of a DOM element.
If listItem is DOM element then maybe it's not yet added to the document or disableFlag is an invalid value. Or the error happens outside the provided code.

Undefined variable error that shouldn't be a variable

I've made a piece of code in jquery that assigns a href attribute to a variable. Here's that code:
$('#reactions' + i).attr('href', 'javascript:comments ('+entry.url+','+i+');');
This should assign a call to the javascript function comments. Now I want to use that call on a jquery mobile button, like this:
document.write('Reactions');
But doing this gives me a in FF and Chrome. This is the error from FF±
Uncaught exception: ReferenceError: Undefined variable: i_heart_chaos_ihc_after_dark_independence_day_through_a_bullhornthis_is_what
Error thrown at line 1, column 0 in javascript:comments (i_heart_chaos_ihc_after_dark_independence_day_through_a_bullhornthis_is_what,1);:
comments (i_heart_chaos_ihc_after_dark_independence_day_through_a_bullhornthis_is_what,1);
In this, i_heart_chaos_ihc_after_dark_independence_day_through_a_bullhornthis_is_what is the value of entry.url.
I'm just not getting why this error appears, as far as I know, everything should work.
I know that there are questions looking similar to mine, but I couldn't figure out the answer. If you want to see the whole source, it's here.
Surround entry.url with quotes:
$('#reactions' + i).attr('href', 'javascript:comments ("'+entry.url+'",'+i+');');
The best way to fix the issue is to do it the "jQuery way". Instead of adding a href attribute that executes JavaScript, add a click event:
$('#reactions' + i).click( function() {
comments( entry.url, i );
});
Similarly don't use document.write() but add elements to the document using jQuery functions.

variable assignments using jQuery failing in Safari?

I'm using jQuery 1.3.2 and it's breaking under Safari 4 for mysterious reasons.
All of my javascript references are made right before the tag, yet with the following code:
var status = $('#status');
status.change( function(){ /* ... */ } );
The following error is displayed in the Web Inspector:
TypeError: Result of expression 'status.change' [undefined] is not a function.
However the error is not encountered if I eliminate the variable assignment attach the change method directly like so:
$('#status').change( function(){ /* ... */ } );
Why? I need to use variables for this and several other findById references because they're used many times in the script and crawling the DOM for each element every time is regarded as bad practice. It shouldn't be failing to find the element, as the javascript is loaded after everything except and .
Try changing the variable to something other than "status."
It's confusing your variable with window.status (the status bar text). When I typed var status = $('#status') into the debugging console, the statusbar changed to [Object object]. Must be a bug in Safari.
If you put the code inside a function, so that status becomes a function-local variable, it should work.
It's standard practice in jQuery to wrap things in a
$.onready(function() {
});
This makes sure the DOM is loaded before you try to manipulate it.

Categories

Resources