Let me just first point out to any IE users right now (this is not a problem in Chrome, Safari or Firefox) hint hint ;)
So... I have a issue with my tooltips in IE, I have a onmouseover listener for all the elements which are to be hoverable and then in my mouseover function I have a very basic cross browser declaration as such...
var event = e || window.event,
el = event.target || event.srcElement;
I've been having issues with the window object not existing in IE or something, this has been a issue after I added a flag to ignore mouseover's from one element mouseover on the way to the tooltip itself (during the time cycle allowed, 300ms). In other words the flag is to ignore mouseovers on route to the tooltip from the original mouseover.
So that logic looks like this...
loadtip.refMouseOver = function (e) {
var event = e || window.event, el = event.target || event.srcElement;
//console.log(window); // <-- throws error in IE (Member not found)
// Reset the lastHoveredRef data.
tipManager.lastHoveredRef = null;
tipManager.lastHoveredRef = [el, event];
// true means there is a tip open still, so if no tip is open.
if (tipManager.tipState !== true) {
tipManager.processTip(el, event);
} else {
return; // do nothing
}
}
The "Member not found" error will occur when I hover from one element quickly to the next in IE with the tooltip still open.
I read about window.open and close stuff with a try catch but I didn't see how that was relevant. Any help is greatly appreciated.
Ok I have found the problem.
To sum it up, basically IE will not pass a event to another function if that function call is within a setTimeout.
So you can trick IE by creating a copy of the event and passing that, here is a example of that...
var eventCopy = {};
for (var i in event) {
eventCopy[i] = event[i];
}
Then just send your function the eventCopy, even though this is a 'total' hack.
setTimeout(function () { yourFunction(eventCopy), yourDelayTime);
And voila it will work.
I should add, that Internet Explorer will merely create a reference to the global window event which is why we need the copy of event. This is because by the time setTimeout calls the function, windows.event has already passed,
Bottom line... don't try to send a event inside a setTimeout because IE won't accept it. This is true for IE 6, 7 & 8 from my testing.
I realize this question/answer is pretty old and seems to be resolved. That being said, I have another alternative I've used to handle a similar -- yet slightly different -- issue with 'Member Not Found' in IE versions prior to MSIE 9. I hope this helps someone out! ...this can also be used to work around issues with Firefox not having window.event.
First I extended jQuery and added a function to get the MSIE version or -1 if the browser is non MSIE. You can do the same or just create a pure JS function to accomplish this. Then create an event override function (it might be necessary to add a global 'event' variable in some cases), that's more of a per individual situation basis. Then override the event in your event handler(s) as needed.
Extending jQuery
// So this will give you the version of IE (or for non IE browser -1)
$.fn.msieVersion = function()
{
if ( navigator.userAgent.toLowerCase().indexOf( 'msie' ) !== -1 ) {
return document.documentMode;
}
return -1;
};
Override the global event
var setEvent = function( evt ) {
// Set the event if MSIE version is >= 9 or is -1 which means it's not IE
if ( $.fn.msieVersion() >= 9 || $.fn.msieVersion === -1 ) {
// NOTE: I have a global 'event' variable I'm using that comes from another previously loaded JS file
// Why? I didn't do it. I'm updating some SUPER old code the best I can. (old enough it has references to Netscape....)
event = evt || window.event;
}
return true;
};
Usage Example
$( 'img.myImageID' ).bind('mouseover mouseout', function ( evt ) {
setEvent( evt ); // Override the event
// DO WORK! ...continue all other awesomeness here!
// Maybe setTimeout(...)
};
Related
Here is the thing.
I'm need to open a new tab and draw something on the new opened tab.
I add event listener like that:
div3.addEventListerner("onmousedown",MouseDown(NewWindow.event),false);
But the firefox throw errors about the code in the MouseDown() function when the page is loading. The error is not throwed when I move the mouse.
function MouseDown(event)
{
if(!event)
{
var event = window.event;
}
X = event.pageX;//Throw error here.
Y = event.pageY;
So, there is anyone who knows how to fix this Problem?????
Remove the var from var event = window.event. The variable is already declared (as an argument), so re-declaring it with var can only lead to problems.
To be specific, due to hoisting, here is what your code boils down to:
function MouseDown(event) {
var event; // = undefined
if( !event) { // always true
event = window.event; // undefined in modern browsers
}
X = event.pageX; // ERROR!
}
Without the var, all is well!
When you're using addEventListener(), Event object is passed automatically in all browsers supporting the said method. However, you're calling your eventhandler immediately in argument. Instead you should pass a reference:
div3.addEventListener("mousedown", MouseDown, false);
Notice also "mousedown" without on. In the handlerfunction, event always exists, no need to check it for older IEs, since they don't support addEventListener.
I have some old code that I'm updating to work in firefox, and I've run across a problem.
In the code, there's a function that looks like this:
function tableEnter() {
myLocation = event.srcElement;
}
This doesn't work in firefox. I've researched this quite a bit, but most of the solutions I've found require an event to be passed to this function, and then act on the e parameter that was passed. ...Unfortunately in the code that I'm updating, I'm not getting any parameters passed.
What's the solution to making the event.srcElemet work in firefox, without any parameters being passed to my function?
Edit:
Okay, the question is becoming: How do i pass the event object to my tableEnter() function?
Here's what the code is currently doing:
$(document).ready(function () {
//make table rows
//for every new table row...
myRow.onmouseover = tableEnter; (this is probably a bad name. it should be like..rowEnter. But this is the way I found the code)
});
the question is now, how do i pass the event object into tableEnter() so that I can do the things suggested on the internet, and the answers below.
Thanks.
I honestly can't see why you would want to have access to the event object, without it being an argument of your handler. But, hey, that's just me. Although no parameters are specified, FF and chrome just do as they please and pass the event object to the handler anyway. So:
function tableEnter()
{
var evt = window.event || arguments[0];
var src = evt.target || evt.srcElement;
}
And that's it. Personally, I would advise you to do what the whole wide web is doing:
function handler(e)
{
e = e || window.event;
var target = e.target || e.srcElement;
}
Since you're using FF, you shouldn't try to diverge from any of the coding conventions or standards too much, however vague they might be. At least it's better than no standards or conventions at all.
In view of your update, just change your function definition to:
function tableEnter(e)
{
//though in jQuery, I suspect e is allready X-browser-proof
e = e || window.event;
//just leave ^^this^^ line out, and check in IE: alert(typeof e);
//if it alerts object, jQuery passed the event object for you
var theRow = this;//<-- this points to the row that triggered the mouseover
var jQRow = $(this);//gives you access to jQuery methods
var target = e.target || e.srcElement;//<-- mainly of importance in delegation
}
I'm fairly new to web development and I'd like to think I am getting the hang of it, the only major problems I keep running into are cross-browser compatibility issues.
I have a textarea on a webpage that will call a function after the user is done typing. In order to do this, I am using jQuery and setTimeout to wait a bit before calling the function. This ensures that the function isn't called after every single keypress. I don't want it called after every keypress because the function sends a request to a servlet which does some processing and returns.
The code works fine on Chrome (I use Chrome for debugging it), but it doesn't work with IE7. Here it is:
var timer = null;
$("#scriptInput").keypress(function() {
clearTimeout(timer);
var thisEvent = window.event;
timer = setTimeout(function() {validateScript(thisEvent);}, 500);
});
function validateScript(evt) {
var code = (evt.keyCode) ? evt.keyCode : evt.which;
//check which key was pressed...
//don't need to send a request on key presses of CAPSLOCK, SHIFT, and ARROW keys
if(code != 20 && code != 16 && code != 37 && code != 38 && code != 39 && code !=40){
sendRequest(2);
}
}
As you can see, I've already made numerous attempts at implementing compatibility with IE7, but to no avail :\
It must be compatible with at least IE7 because it will be used by a number of machines which use IE7 and don't have the privileges to upgrade.
Let me know if you need anymore info!
Thanks!
P.S. "scriptInput" is the id of the textarea this is affecting.
var thisEvent = window.event; is not cross-browser compatible - not all browsers use the global event object but a function argument instead.
jQuery always provides you with an event object as a function argument, so simply remove the above assignment and change your code like this:
$("#scriptInput").keypress(function(thisEvent) {
...
});
jQuery also normalizes the various properties for the pressed keys into e.which so you can get rid of var code = (evt.keyCode) ? evt.keyCode : evt.which; and simply use evt.which all the time.
You can also improve/shorten the whole thing a bit more. If adding another library is fine I'd use _.debounce from Underscore.js to do the timing:
$("#scriptInput").keypress(_.debounce(validateScript, 500));
Instead of Underscore.js you could also use a jQuery plugin providing that functionality.
If adding additional third-party code is not an option I'd store the timer on the element instead of a (possibly global) variable:
$("#scriptInput").keypress(function(e) {
var $this = $(this);
window.clearTimeout($this.data('timer'));
$this.data('timer', window.setTimeout(function() {
validateScript(e)
}, 500));
});
there is an if statement on my company's website that makes one web page imcompatible with firefox
if(event.srcElement.getAttribute("onclick") == null){
...code..
document.mainForm.submit();
}
I've commented out the if statement conditions and now its working with forefox. My question is, what is event.srcElement.getAttribute("onclick"), is it important, would it cause problems in the future. also, is there something similar i can replace the condition with so that it works on firefox?
Edit:
function gotoRDManagerPT(PTId, bDDetailId) {
if(!proceed()) return false;
var target = event.target || event.srcElement;
if(event.target.getAttribute("onclick") == null) {
document.mainForm.displayRDManagerPT.value = "true";
document.mainForm.PTId.value = PTId;
document.mainForm.bDDetailId.value = bDDetailId;
document.mainForm.submit();
}
}
srcElement is proprietary property originally coming from IE. The standardized property is target:
var target = event.target || event.srcElement;
if(target.onclick == null) { // shorter than getAttribute('onclick')
//...
document.mainForm.submit();
}
Also have a look at quirksmode.org - Event properties for more cross browser information.
Regarding the question what it is doing:
event.target / event.srcElement contains a reference to the element the event was raised on. getAttribute('onclick') == null checks whether a click event handler is assigned to element via inline event handling.
Is it important? We cannot say because we don't know what the ...code.. is doing.
In IE the event object is available in the window object already; in Firefox, it's passed as a parameter in the event handler.
Example
JavaScript:
function toDoOnKeyDown(evt)
{
//if window.event is equivalent as if thie browser is IE then the event object is in window
//object and if the browser is FireFox then use the Argument evt
var myEvent = ((window.event)?(event):(evt));
//get the Element which this event is all about
var Element = ((window.event)?(event.srcElement):(evt.currentTarget));
//To Do -->
}
HTML:
<input type="text" id="txt_Name" onkeydown="toDoOnKeyDown(event);"/>
As you notice when we called the function inside the html we have added a parameter event just in case the browser is Firefox.
I have read in an article that the event object in IE is called window.event and in Firefox we have to put it as a parameter.
In case you need it to be attached in the code:
document.getElementById('txt_Name').onkeydown = function(evt) {
var myEvent = ((window.event)?(window.event):(evt));
// get the Element which this event is all about
var Element = ((window.event)?(event.srcElement):(evt.currentTarget));
// To Do -->
};
Try quick fix as follows:
Include in code:
let target = event.target || event.srcElement;
and change
event.srcElement.XXXXX to target.XXXXX
this solves the issue with Firefox.
I am trying to simulate keypresses in a web application, it is for an embedded system but it uses a Webkit derived browser. I have tested the code in Chrome and get the same error.
I tried to use code snippets from this example from Yahoo, but I keep getting the same error when firing the event using dispatchEvent. "target" is an HTML element in the DOM tree.
function fireEvent(target) {
var evt = document.createEvent("UIEvent");
evt.initEvent("keypress", true, true);
target.dispatchEvent(evt);
}
It always throws:
"Error: UNSPECIFIED_EVENT_TYPE_ERR: DOM Events Exception 0"
I have tried createEvent("Events") as well and it always boils down to the same exception, both on the embedded system and in Chrome.
Ok, when doing further testing, it seemed that when all key event parameters was properly initialised, then dispatchEvent worked without fireing an exception.
The following code works.
function fireEvent(target) {
var evt = document.createEvent("Events");
evt.initEvent("keypress", true, true);
evt.view = window;
evt.altKey = false;
evt.ctrlKey = false;
evt.shiftKey = false;
evt.metaKey = false;
evt.keyCode = 0;
evt.charCode = 'a';
target.dispatchEvent(evt);
}
Keypress is an UIEvent. You should use initUIEvent( 'type', bubbles, cancelable, windowObject, detail ) rather than initEvent(). But for firefox, which implements a keyEvents, you should create a KeyEvents and initKeyEvents().
This one is old thread, just to update it I am adding another answer so that it makes more sense to any one.
initEvent() is deprecated It is still supported in some browsers but avoid using it.
There is better concise way to create events like this
function fireEvent(target) {
var event = new Event('build');
// Listen for the event.
target.addEventListener('build', function (e) { ... }, false);
// Dispatch the event.
target.dispatchEvent(event);
}
To add more data to the event object, the CustomEvent interface exists and the detail property can be used to pass custom data.
For example, the event could be created as follows:
var event = new CustomEvent('build', { 'detail': target.dataset.time });
Reference: Creating and Triggering Events