Manually creating a javascript event object - javascript

Say I have the following code:
$('#someid').click(function(event) { myFunction(event); });
function myFunction(event)
{
// do something with event
}
And I would like to test myFunction() with an eval statement, without doing something like using eval('$("#someid").click()');
Is there a way to manually create an event object in javascript that would work with an eval statement?
Also if myFunction is only used as an event handler, can it always assume event is not null?

Well, assuming that's JQuery at the top, the event object shouldn't ever be null.
The event object is a completely different critter between IE and everybody else so unless JQ 100% normalizes the object (I think it builds its own event object from the looks of it), it may still vary in properties that JQuery doesn't use between browsers. To manufacture your own event object I guess I would just use a for x in loop to see what's inside and build an object hash that simulates that.
So on this page something like:
$('#adzerk1').click( function(event){
console.log('fakeEvent = {');
for(x in event){ console.log( x + ':' + event[x] + ',\n')}
console.log('}');
} );
$('#adzerk1').click();
will return all properties and their values for that event in the console box of firebug. You'd have to make it recursive and test to get all the innards of properties of event that are objects themselves, however. Otherwise I've set it up so that all you would have to do is cut and paste the results into your JS and then delete the last comma before the closing curly bracket.

Related

How to determine if a property exists on a javascript object

I have created a ton of Image objects in javascript and put them all in an array. However, some of these objects have a mouseover() and mouseout() property, and some do not.
Is there a way to determine if the object I'm referencing has those functions defined or not?
I've tried
if (typeof obj.mouseover !== 'undefined')
but if I never even declared
mouseover = function() { ... }
on that object, then the code just breaks right there.
So I'm looking for a way to determine if I even added 'var mouseover = function() { ... }' on each object.
Of course, I could go through and make sure EVERY object gets mouseover and mouseout created, even if not set as anything, but that feels like an unnecessary pain if there's another way to just detect if that was set in the first place.
Thanks.
You can check that the method exists on the object via Object.hasOwnProperty('someMethodName')
Mozilla dev link
Use reflection. Eg.:
Javascript Reflection
It is then easy to write a function like:
DoesMethodExist = function (object_, methodName){...}
that iterates through all the method names of object_ and matches them with methodoName.

VBA IE call a javascript containing 'this' keyword

I am attempting to call a javascript function on a webpage that contains the 'this' keyword which is referring to the <input> textbox on the webpage. The function looks like this:
functiondostuff('hdnAttribute',this,'Key')
Using
js = "functiondostuff('hdnAttribute',this,'Key')"
Call IE.Document.parentWindow.execScript(js)
doesn't throw an error but does not produce the results of the function since this cannot be identified.
Stepping through the website this = [object DispHTMLInputElement] instead of the element name while the function is running. Anyone have any ideas?
Good Morning,
Adding more to this issue. There seems to be two problems, 1st is setting the window.event, functiondostuff begins with: if (window.event && window.event.keyCode == 13), when the function is called it exits out immediately due to the event being null. Is there a way to pass the event as 13 to the website? The second issue is submitting the "this" HTMLInputObject.
Does anyone know a method to fire the 'onkeypress' event? I am at the point of trying sendkeys to avoid calling the function but have not been able to get them to work with IE. Thanks for any suggestions!
Key point is context. If you have this HTML
<input onclick="functiondostuff('hdnAttribute',this,'Key')">
then the browser can infer context from the user interaction and set this for you correctly.
From within VBA that's a slightly different matter and you have to define context manually.
How about this:
Dim js As Variant
js = Array( _
"var input = document.getElementById('yourElementsId');", _
"functiondostuff('hdnAttribute',input,'Key');" _
)
Call IE.Document.parentWindow.execScript(Join(js, vbNewLine))
This way you get to define context yourself.
document.getElementById was just for the sake of the example. If your element has no ID, use any other method (like DOM traversal, document.querySelectorAll, document.getElementsByTagName + a loop, ...) to get a reference to the desired element.

Save and restore "onclick" action on jQuery objects

I want to disable a whole bunch of objects on the page, and then re-enable them later. Since some of them are tags rather than buttons, I disable them by removing their onclick attr. I've tried to store the old handler in a .data(), but unfortunately when I attempt to restore them with $(obj).attr('onclick',$(obj).data('onclick')), it calls the function rather than restoring it to the attribute. And if I try to store it in a different attribute instead of a data, it doesn't store the function, it stores the return value for the function.
Is there any way to accomplish this without re-writing every tag and every onclick handler on my page?
if( doEnable) {
$(obj).attr('href', $(obj).data('href'));
$(obj).attr('onclick', $(obj).data('onclick'));
$(obj).removeClass(EIS.config.classes.disabled);
$(obj).show();
}
else {
// Save the things you're going to remove
$(obj).data('onclick', $(obj).attr('onclick'));
$(obj).data('href', $(obj).attr('href'));
$(obj).prop("href", null);
$(obj).prop("onclick", null);
$(obj).addClass(EIS.config.classes.disabled);
$(obj).show();
}
By the way, this code seems to work fine in Chrome and Firefox, but only sometimes in IE8 and never in IE6. Unfortunately the client tests first in IE6.
$(obj).attr('onclick', ...
is ambiguous, has results that differ in different versions of jQuery and different browsers. It probably doesn't do what you want. You should avoid using attr on event handlers.
The problem is the disconnect between the onclick attribute and the onclick property. jQuery has tried to brush the difference between an attribute and a property under the carpet in the past, using attr to access both, but they're quite different. This was changed in jQuery 1.6, and partially reverted in 1.6.1, to widespread controversy, confusion and incompatibility.
For many properties, the values of an attribute and the corresponding DOM property are the same; for others, including all properties that aren't strings, they aren't. Event handlers certainly aren't: the property is a Function object, whereas the string attribute might be (a) the original string of the onclick="..." attribute in the HTML, (b) nothing (if the onclick was assigned from script to be a Function object) or (c) unavailable (in older IE).
To access the event handler Function property, use prop() in jQuery 1.6:
$(obj).data('onclick', $(obj).prop('onclick'));
...
$(obj).prop('onclick', $(obj).data('onclick'));
or just use plain old JavaScript which is actually simpler and more readable; jQuery wins you nothing here.
obj._onclick= obj.onclick;
...
obj.onclick= obj._onclick;
Either way this is not going to reliably ‘disable’ elements since they can (and very likely will, if you're using jQuery) have other event listeners registered on them, using addEventListener/attachEvent rather than the old-school event handler interfaces.
It looks like saving a function via .data() works just fine:
var f1 = function() { console.log('invoked'); };
$('a').data('func', f1)
var f2 = $('a').data('func'); // 'invoked' is not printed
f1 === f2 // true
so how are you storing the function via .data? if you're doing something like
a = $('a');
a.data('onclick', a.click()); // click handler is invoked here
then you're actually invoking the click handler(s) prematurely, and storing the return value with .data().
--edit--
it appears that .attr(function) invokes the passed function. This is a feature of jQuery. I'd suggest using jQuery's .click() method to attach the function as a click handler.
a = $('a');
a.each(function() {
this.data('onclick', handler_fn);
this.bind('click', handler_fn);
});
// later
a.each(function() {
this.unbind('click');
});
// even later
a.each(function() {
this.bind('click', this.data('onclick'));
});
What about binding the event in jQuery instead of setting the onclick attribute?
$(obj).click($(obj).data('onclick'));
Can we see the code that you use to set the data attribute?

onclick setAttribute workaround for IE7

I can't seem to get this:
top.document.getElementById("clickThis").setAttribute("onclick", "tinyMCE.execCommand('mceInsertContent',false,'<div style=\"width: 600px; margin: 0 auto .5em;\" class=\"wp-caption alignnone\"><img class=\"alignnone\" src=\"<?php echo $full_width; ?>\" alt=\"<?php echo $value; ?>\" /><p class=\"wp-caption-text\"><?php echo $get_image->caption; ?></p></div>');");
To work in IE7, I have tried all of the workarounds I could find online and wondering if anyone could help?
Don't do that.
Instead, add an event handler by calling attachEvent / addEventListener.
I know I'm a bit late, but this was bugging the hell out of me too, and I finally got it.
To get IE to execute dynamically built code during the onclick event, do this:
Write the code for all other browsers: element.setAttribute( "onclick", object.varName + "method( " + var + " )" );
Use a custom attribute to hold your dynamic statement: element.setAttribute( "exec", object.varName + "method( " + var + " )" );
Create an anonymous function to execute the statement stored in our custom attribute when the element is clicked: element.onclick = function(){ eval( this.exec ); };
This approach is working for me in IE9 running in IE7 browser mode, as well as the current versions of Chrome and Firefox.
A couple of things to note:
First, in my case, I needed to execute an objects method. To do that, I need to know the var name for the object, which I set as a property when initiating the class. So the object.varName property is one I created and set in my runtime code.
Second, "exec" is not a standard attribute, which is why it works to hold the string I want to execute. But you can call it what ever you want as long as you use a non-standard attribute.
Third, here's why this works: IE, or at least IE7, will only let you set the onclick event to contain an anonymous function. If you assign an object's method or a variable containing
a function, the function is executed when the onclick attribute is set instead of when the element is actually clicked. In my case, I couldn't build an anonymous function because the variables change at runtime. So instead, I dynamically build a statement that is then stored in an attribute of the element. The onclick event then executes whatever statement is stored in that attribute.
Cheers.
worked like a dream when I did this:
if(navigator.userAgent.indexOf("MSIE 7.0") != -1){
document.getElementById("pb").onclick = function(){ eval( this.onClick ); };
}
that way only ie7 looks at it.

How do I pass an HTML element as an argument to a Javascript function?

i have a chat window which has a close button(input type='image') and onclick i want to remove the chat window from the parent node and i use this code
closeBtn.setAttribute("onclick", "return closeContainer(cc" + friendId + ");");
please note that this button is created through javascipt and the cc223423432 (say) will be the id of the chat window
here is my code to remove it
function closeContainer(ccId) {
var x = ccId;
x.parentNode.removeChild(x);
//..........
}
now in IE8 and Chrome it finds the passed argument as HTMLDIV and works fine but in firefox it give an error cc223423432 is undefined
any idea why???
i know i can always do a document.getElementByID and then remove it but please if there is anything i am missing please tell
closeBtn.setAttribute("onclick", "return closeContainer(cc" + friendId + ");");
Don't use setAttribute to set event handlers... actually don't use setAttribute on an HTML document at all. There are bugs in IE6-7 affecting many attributes, including event handlers. Always use the ‘DOM Level 2 HTML’ direct attribute properties instead; they're reliable and make your code easier to read.
Lose the attempt to create a function from a string (this is almost always the wrong thing), and just write:
closeBtn.onclick= function() {
return closeContainer(document.getElementById('cc'+friendId));
};
or even just put the closeContainer functionality inline:
closeBtn.onclick= function() {
var el= document.getElementById('cc'+friendId);
el.parentNode.removeChild(el);
return false;
};
in firefox it give an error cc223423432 is undefined any idea why???
Because IE makes every element with an id (or in some cases name) a global variable (a property of window). So in IE you can get away with just saying cc223423432 and getting a reference to your object.
This is a really bad thing to rely on, though. As well as not existing in other browsers, it clutters up the global namespace with crap and will go wrong as soon as you do actually have a variable with the same name as an id on your page.
Use getElementById to get a reference to an id'd node instead, as above. This works everywhere and is unambiguous.
Since the parameter is not enclosed in quotes Firefox considers this as a variable with name
cc223423432 which is not defined. Thats why it generates the error.
Better to pass this as a string and then use
document.getElementById ( parameter );
to get the object.
You need to pass that id as a string:
closeBtn.setAttribute("onclick", "return closeContainer('cc" + friendId + "');");
Then:
function closeContainer(ccId) {
var x = document.getElementById(ccId);
x.parentNode.removeChild(x);
//..........
}
jquery will work in all of those browsers. I would do the following:
closeBtn.click(function(){
('#cc' + friendId ).remove();
});
However, if you don't want the ramp-up time of learning the jquery api, it looks like you need to pass your id parameter as a string, otherwise firefox considers this a variable name (notice the additional single quotes inside the closeContainer call:
closeBtn.setAttribute("onclick", "return closeContainer('cc" + friendId + "');");
Or you could do the following
function handler(elementRef) {
console.log(elementRef);
}
<button onclick="handler(this)">Click Me!</button>

Categories