I'm upgrading a script to make it crosss browser. The current code I have is as follows.
function testFocus(){
var testSelection = document.getElementById('chattext').contentWindow.
window.document.selection.createRange().parentElement();
while (testSelection)
{
if (testSelection.id == "chatContent") {
return true;
}
testSelection = testSelection.parentElement;
}
return false;
}
However the following code no longer works in modern browsers. Presently the code above has to have text selected. Where it just needs to check that the textbox has focus. The function is used as a check before text is added by a button / javascript.
Strikes me that you could use an event listener to set a variable. The only problem being that IE uses attachEvent(event, callback) instead of addEventListner so you've actually got to add the code
<script type="text/javascript">
var ChatHasFocus = false;
var ts = document.getElementById('chattext');
function setFocus() {ChatHasFocus = true;}
function setNoFocus(){ChatHasFocus = false;}
if (ts.addEventListener != undefined) {
ts.addEventListener('focus', setFocus, false);
ts.addEventListener('blur', setNoFocus, false);
} else if (ts.attachEvent != undefined) {
ts.attachEvent('onfocus', setFocus);
ts.attachEvent('onblur', setNoFocus);
} else {
ts.onmouseover = setFocus;
ts.onmouseout = setNoFocus;
}
</script>
edit - I've added script tags to show you how it adds to your document. I've tested in firefox and chrome and it seems to work, but getting an IE sandbox together might be a little more difficult for me. I'm sure there's something little that I'm missing there - i'll take a look.
edit2 i made a mistake with the IE code. tuns out you don't put quotes around 'undefined' I've fixed the code above to reflect an answer that is tested and wotkign in firefox, chrome and IE6. I don't have any other IEs to test in.
Related
Have anybody out there found a simple way of detecting whether the browser supports the transitionend event or not in vanillaJs, especially in a way that actually works in all major browsers? :(
I have found this unanswered thread in here: Test for transitionend event support in Firefox, and quite a lot of almost working hacks.
Right now I am bulk adding eventlisteners to all the vendor prefixes, and it kind of works out (even though I think it is a hideous approach that hurts my eyes every time I look at it). But IE8 and IE9 does not support it at all, so I need to detect those two, and treat them separately.
I would prefer to do this without browser sniffing, and definitely without huge libraries/frameworks like jQuery
I have made a jsfiddler snippet that illustrates my problem. There is a button that spawns a dialog. When the dialog is removed by clicking close, it is transitioned in top and opacity, and after ended transition it is supposed to display=none. But if the transitionend is never fired (like in IE8 and IE9), the dialog is never removed, making it cover the show dialog button, destroying the UX. If I could detect when transitionend is not working, I could just set the display=none when closing for those browsers.
http://jsfiddle.net/QJwzF/22/
window.listenersSet = false;
window.dialogShouldBeVisible = false;
window.showMyDialog = function () {
var myDialog = document.getElementById('dialog'),
myClose = document.getElementById('close');
if (!listenersSet) {
if (!window.addEventListener) { // IE8 has no addEventListener
myclose.attachEvent('onclick', function () {
hideMyDialog();
});
} else {
myClose.addEventListener('click', function () {
hideMyDialog()
});
['webkitTransitionEnd','oTransitionEnd', 'otransitionend', 'transitionend'].forEach(function (eventName) {
myDialog.addEventListener(eventName, function (e) {
if (e.target === myDialog && e.propertyName === 'top') { // only do trigger if it is the top transition of the modalDialog that has ended
if (!dialogShouldBeVisible) {
myDialog.style.display = 'none';
e.stopPropagation();
}
}
});
});
}
listenersSet = true;
}
myDialog.style.display = 'block';
myDialog.style.top = '15px';
myDialog.style.opacity = '1';
dialogShouldBeVisible = true;
}
window.hideMyDialog = function () {
var myDialog = document.getElementById('dialog'),
myClose = document.getElementById('close');
myDialog.style.top = '-5%';
myDialog.style.opacity = '0.1';
dialogShouldBeVisible = false;
}
It is working in Opera, Firefox, Chrome and IE10, but not in IE8 and IE9 (afaik)
If I did a bad job explaining my problem, please let me know, and I will try do a better job! :)
Copied from bootstrap transition, it not only returns true if browser supports transition but also returns proper name of event
function transitionEnd() {
var el = document.createElement('div')//what the hack is bootstrap
var transEndEventNames = {
WebkitTransition : 'webkitTransitionEnd',
MozTransition : 'transitionend',
OTransition : 'oTransitionEnd otransitionend',
transition : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return transEndEventNames[name];
}
}
return false // explicit for ie8 ( ._.)
}
Hope this helps.
EIDT:
I modified a little bit default bootstrap function so it doesn't return object but string.
I would definitely use this small script available on Github.
It's listed among Modernizr "Cross-browser polyfills" page so it can be trusted but Modernizr itself is not required.
The examples in the Github page of the script are written using jQuery (and I can't understand why) but jQuery is also not required as it's written in vanilla js.
Like so you'll have a useful whichTransitionEnd method available. I can't test it right now being on my laptop without IE8/IE9 available but I guess that this method will return false (or anything falsy) in those browsers.
var transition = transitionEnd(box).whichTransitionEnd();
// return for example "webkitTransitionEnd"
It will then be quite easy to target those browsers where transitions (and thus transitionend events) are not supported. Hope this will be a nudge in the right direction.
EDIT
After tweaking with the above code the OP came up with a much shorter version of the original script. It saves a good deal of bytes and only detects support for this event, and, in case it's supported returns the name of the event itself.
You can find it here as a gist and read more about it in the comments to this answer.
I have this bit of javascript code I am trying to get to work in IE10. Been trying to use jquery to reference the styleSheet and the rule and initialize them. Hasn't helped. Here's the code:
function SetBold(Item, bold)
{
var aitemstyle = document.all.item(Item).style;
if (aitemstyle)
{
if (bold)
{
aitemstyle.fontWeight = "bold";
aitemstyle.color = "black";
aitemstyle.textDecoration = "none";
}
//this else block of code causes function-expected error IE10 windows 8, oRule var initialization
else
{
var oRule=document.styleSheets("panoramaCSS").rules("12pxHoverColorChange");
//IE10 expected function from previous line. So, for loop below for finding 12pxHovercolorChange rule
//inside panoramaCSS styleSheet
//TODO make the selections off Panel Performance go unbold. Not working yet.
}
}
}
I'm not sure why it might be working in other browsers, but accessing a style-sheet and a rule requires square brackets:
var oRule=document.styleSheets("panoramaCSS").rules("12pxHoverColorChange");
shoud be
var oRule=document.styleSheets["panoramaCSS"].rules["12pxHoverColorChange"];
The reason for the error is that IE is interpreting the parentheses as a call to a function that doesn't exist.
This quirksmode page should be useful.
I've looked through quite a few answers and other places online, but I haven't found anyone that is experiencing the error in the same way that I am.
My browser just updated to IE10 and that brought this to our attention. If I run in compatibility mode, the function seems to work just fine. If I'm not in compatibility mode, I get an IE debugger error SCRIPT5002 - Function Expected error.
I've marked the place where I get the error with ==>. If I take that variable out and replace the variable with the document.frames... it then references that line as the problem. Any help would be appreciated.
I inherited this code from a previous employee and have only been working with javascript for about 3 months. Here is the code:
function FncSaveClient(){
//Submit Primary Client form
//Verify Data
==> var CntSumFrm = document.frames('IFrameSummary').document.all.item('DefaultFrm');
if (CntSumFrm.fireEvent('onsubmit') == true){
CntSumFrm.submit();
}
//If Edit Mode Submit Subforms
var IntAcctNum = CntSumFrm.TxtAcctNum.value
if (IntAcctNum != 0){
//Locations Subform
var CntLocFrm = document.frames('IFrameLocations').document.all.item('DefaultFrm');
if (CntLocFrm.fireEvent('onsubmit') == true){
CntLocFrm.submit();
}
//Contacts Subform
var CntContactTbl = document.frames('IFrameContacts').document.all.item('TblContactSummary')
if (CntContactTbl.rows.length-3 == 0){
alert('You must have at least one contact per client.');
document.all.item('BtnSubTblClientContacts').style.color='red';
}
//Classification Subform
var CntClassFrm = document.frames('IFrameMarketing').document.frames('IFrameClassification').document.all.item('DefaultFrm');
if (CntClassFrm.fireEvent('onsubmit') == true){
CntClassFrm.submit();
}
//Save Client Admin
var CntAdminFrm = document.frames('IFrameAdmin').document.all.item('DefaultFrm');
if (CntAdminFrm.fireEvent('onsubmit') == true){
CntAdminFrm.submit();
}
else
{
document.all.item('BtnSubTblSalesRel').style.color='red';
}
}
if(CntSumFrm.TxtDeleted.value == 1)
{
window.parent.location.href = '/Accounts/';
}
}
That code is full of ancient IE-specific code, that is probably not allowed anymore even by IE, unless in compatibility mode. You should look into replacing stuff like:
document.frames
document.all
.items()
I believe the error happens because frames or item (maybe both) is not a function when IE follows the JS standards.
I had a similar issue with a Java Script I wrote back in 2005 today. An external user using IE10, which we are still back in IE8, couldn't get things to work properly. It appears that document.all has been deprecated and is only accessibly in compatibility mode. I removed the check I had for IE and so it now uses document.getElementById which I already had for other browsers, and it appears to work even with compatibility mode turned off.
Yesterday I asked a question about running a script once a YouTube video is playing and after a lot of wrestling I figured this out.
Now the solution works in Firefox, Chrome, Safari, IE9 and IE8 but for some reason it's not working in Opera and IE7. I have very little Javascript experience so any help would be really appreciated.
I link the JS like this
<script type='text/javascript' src='http://www.example.ca/wp-includes/js/jquery/jquery.js?ver=1.7.1'></script>
<script type='text/javascript' src='http://www.example.ca/wp-content/plugins/slidedeck-lite-for-wordpress/lib/youtubeapi.js?ver=2011-04-28'></script>
<script type='text/javascript' src='http://www.example.ca/wp-content/plugins/slidedeck-lite-for-wordpress/lib/slidedeck.jquery.lite.js?ver=1.4.5'></script>
And within youtubeapi.js I run this
window.YTplayerState;
function onPlayerStateChange(evt) {
YTplayerState = evt.data;
}
window.YTplayerState; is an attempt to help fix the Opera/IE7 issue. Then within a pre-existing file for the SlideDeck plugin I run this
var YTplayerState;
var autoPlay = function() {
gotoNext = function() {
if (self.pauseAutoPlay === false) {
if (self.options.cycle === false && self.current == self.slides.length || YTplayerState == 1) {
self.pauseAutoPlay = true;
} else {
self.next();
}
if (YTplayerState == 1) {
self.pauseAutoPlay = true;
}
}
};
setInterval(gotoNext, self.options.autoPlayInterval);
};
Which most browser seem to be okay with, although that may just be luck, but it works. I know the issue in Opera is that YTplayerState never gets the value because if I manually change the value to one with a keypress function then it all behaves as expected.
If it's not anything with the code directly provided, are there any common quirks with Opera that I should look out for?
To my knowledge, this is a bug in Youtube video player. Sorry.
If you google for "onPlayerStateChange opera", you'll find more similar error reports.
So loading up our new web application in Firefox and Chrome I had an alert subtly tell me that a tabStrip couldn't be found. Following through the code I found this function:
function initializeTabStrip() {
var tblList = document.getElementsByTagName("table");
var tabStrip = null;
for (var i = 0; i < tblList.length; ++i) {
if (typeof (tblList[i].tabStripRoot) != "undefined") {
tabStrip = tblList[i];
break;
}
}
if (tabStrip) {
window.tabStrip = new TabStrip(tabStrip);
}
else {
alert("couldn't find tabstrip");
}
}
In both Firefox and Chrome, typeof (tblList[i].tabStripRoot) comes up to be undefined, whereas in Internet Explorer the same section of code will find an item, and follow through correctly.
I've tried using Firebug and IE's developer toolbar script debugging tool to follow through and attempt to discover what 'tabStripRoot' is, but I haven't had any luck.
Would any of you JavaScript guru's be able to give me some direction into why one out of three browsers works?
Thanks for your help.
You're relying on IE's non-standard ability to access arbitrary attributes as properties of DOM elements.
In standards-compliant browsers, you cannot write someElement.tabStripRoot to access the tabStripRoot attribute.
Change it to tblList[i].getAttribute('tabStripRoot').