I am trying to make a div, that when you click it turns into an input box, and focuses it. I am using prototype to achieve this. This works in both Chrome and Firefox, but not in IE. IE refuses to focus the newly added input field, even if I set a 1 second timeout.
Basically the code works like this:
var viewElement = new Element("div").update("text");
var editElement = new Element("input", {"type":"text"});
root.update(viewElement);
// pseudo shortcut for the sake of information:
viewElementOnClick = function(event) {
root.update(editElement);
editElement.focus();
}
The above example is a shortened version of the actual code, the actual code works fine except the focus bit in IE.
Are there limitations on the focus function in IE? Do I need to place the input in a form?
My guess is that IE hasn't updated the DOM yet when you make the call to focus(). Sometimes browsers will wait until a script has finished executing before updating the DOM.
I would try doing the update, then doing
setTimeout("setFocus", 0);
function setFocus()
{
editElement.focus();
}
Your other option would be to have both items present in the DOM at all times and just swap the style.display on them depending on what you need hidden/shown at a given time.
What version IE? What's your DocType set to? is it strict, standards or quirks mode? Any javascript errors appearing (check the status bar bottom left for a little yellow warning sign) ? Enable error announcing for all errors via Tools > Options > Advanced.
Oisin
The question is already answered by 17 of 26. I just want to point out, that Prototype has native mechanism for this: Function.defer()
Related
I am trying to use an HTML button to call a JavaScript function.
Here's the code:
<input type="button" value="Capacity Chart" onclick="CapacityChart();">
It doesn't seem to work correctly though. Is there a better way to do this?
Here is the link:http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html click on the capacity tab in the bottom left section. The button should generate an alert if the values are not changed and should produce a chart if you enter values.
There are a few ways to handle events with HTML/DOM. There's no real right or wrong way but different ways are useful in different situations.
1: There's defining it in the HTML:
<input id="clickMe" type="button" value="clickme" onclick="doFunction();" />
2: There's adding it to the DOM property for the event in Javascript:
//- Using a function pointer:
document.getElementById("clickMe").onclick = doFunction;
//- Using an anonymous function:
document.getElementById("clickMe").onclick = function () { alert('hello!'); };
3: And there's attaching a function to the event handler using Javascript:
var el = document.getElementById("clickMe");
if (el.addEventListener)
el.addEventListener("click", doFunction, false);
else if (el.attachEvent)
el.attachEvent('onclick', doFunction);
Both the second and third methods allow for inline/anonymous functions and both must be declared after the element has been parsed from the document. The first method isn't valid XHTML because the onclick attribute isn't in the XHTML specification.
The 1st and 2nd methods are mutually exclusive, meaning using one (the 2nd) will override the other (the 1st). The 3rd method will allow you to attach as many functions as you like to the same event handler, even if the 1st or 2nd method has been used too.
Most likely, the problem lies somewhere in your CapacityChart() function. After visiting your link and running your script, the CapacityChart() function runs and the two popups are opened (one is closed as per the script). Where you have the following line:
CapacityWindow.document.write(s);
Try the following instead:
CapacityWindow.document.open("text/html");
CapacityWindow.document.write(s);
CapacityWindow.document.close();
EDIT
When I saw your code I thought you were writing it specifically for IE. As others have mentioned you will need to replace references to document.all with document.getElementById. However, you will still have the task of fixing the script after this so I would recommend getting it working in at least IE first as any mistakes you make changing the code to work cross browser could cause even more confusion. Once it's working in IE it will be easier to tell if it's working in other browsers whilst you're updating the code.
I would say it would be better to add the javascript in an un-obtrusive manner...
if using jQuery you could do something like:
<script>
$(document).ready(function(){
$('#MyButton').click(function(){
CapacityChart();
});
});
</script>
<input type="button" value="Capacity Chart" id="MyButton" >
Your HTML and the way you call the function from the button look correct.
The problem appears to be in the CapacityCount function. I'm getting this error in my console on Firefox 3.5: "document.all is undefined" on line 759 of bendelcorp.js.
Edit:
Looks like document.all is an IE-only thing and is a nonstandard way of accessing the DOM. If you use document.getElementById(), it should probably work. Example: document.getElementById("RUnits").value instead of document.all.Capacity.RUnits.value
This looks correct. I guess you defined your function either with a different name or in a context which isn't visible to the button. Please add some code
Just so you know, the semicolon(;) is not supposed to be there in the button when you call the function.
So it should just look like this: onclick="CapacityChart()"
then it all should work :)
One major problem you have is that you're using browser sniffing for no good reason:
if(navigator.appName == 'Netscape')
{
vesdiameter = document.forms['Volume'].elements['VesDiameter'].value;
// more stuff snipped
}
else
{
vesdiameter = eval(document.all.Volume.VesDiameter.value);
// more stuff snipped
}
I'm on Chrome, so navigator.appName won't be Netscape. Does Chrome support document.all? Maybe, but then again maybe not. And what about other browsers?
The version of the code on the Netscape branch should work on any browser right the way back to Netscape Navigator 2 from 1996, so you should probably just stick with that... except that it won't work (or isn't guaranteed to work) because you haven't specified a name attribute on the input elements, so they won't be added to the form's elements array as named elements:
<input type="text" id="VesDiameter" value="0" size="10" onKeyUp="CalcVolume();">
Either give them a name and use the elements array, or (better) use
var vesdiameter = document.getElementById("VesDiameter").value;
which will work on all modern browsers - no branching necessary. Just to be on the safe side, replace that sniffing for a browser version greater than or equal to 4 with a check for getElementById support:
if (document.getElementById) { // NB: no brackets; we're testing for existence of the method, not executing it
// do stuff...
}
You probably want to validate your input as well; something like
var vesdiameter = parseFloat(document.getElementById("VesDiameter").value);
if (isNaN(vesdiameter)) {
alert("Diameter should be numeric");
return;
}
would help.
Your code is failing on this line:
var RUnits = Math.abs(document.all.Capacity.RUnits.value);
i tried stepping though it with firebug and it fails there. that should help you figure out the problem.
you have jquery referenced. you might as well use it in all these functions. it'll clean up your code significantly.
I have an intelligent function-call-backing button code:
<br>
<p id="demo"></p><h2>Intelligent Button:</h2><i>Note: Try pressing a key after clicking.</i><br>
<button id="button" shiftKey="getElementById('button').innerHTML=('You're pressing shift, aren't you?')" onscroll="getElementById('button').innerHTML=('Don't Leave me!')" onkeydown="getElementById('button').innerHTML=('Why are you pressing keys?')" onmouseout="getElementById('button').innerHTML=('Whatever, it is gone.. maybe')" onmouseover="getElementById('button').innerHTML=('Something Is Hovering Over Me.. again')" onclick="getElementById('button').innerHTML=('I was clicked, I think')">Ahhhh</button>
I have simple css statement I want to apply to some HTML that basically only shows an element when its previous sibling is not empty. The use case is to only show a "Clear" button when a list has items in it.
<ul></ul>
<button>Clear</button>
ul:empty + button
{
display: none;
}
The problem is that whenever my javascript inserts a new list item into the list, Chrome appears to work correctly and automatically make the button visible. IE11 however fails to show the Clear button. This JS fiddle illustrates the problem: http://jsfiddle.net/xw4nbnz3/
What is the easiest workaround for this problem to make ie11 work? Preferably staying in CSS only.
Pretty sure I'd seen this before, but I can't find the previous question anymore so I'll take a stab at it.
This looks like a typical repaint bug: IE will understand your CSS just fine... if the list starts out with items, and if you write a function to empty the list instead, it will not update the button either. Unfortunately, repaint bugs aren't known for having pure CSS workarounds.
Fortunately, they don't usually need them. Since this only happens when you change the DOM, you can easily work around this within the JS, and it doesn't take very many lines. It looks like removing the list itself first, before inserting the new item, then putting the list back in resolves this issue whilst not creating any problems in other browsers:
function AddListItem()
{
var mylist = document.getElementById("mylist");
if (!mylist)
return;
var parent = mylist.parentElement;
var button = mylist.nextElementSibling;
parent.removeChild(mylist);
var li = document.createElement("li");
li.appendChild(document.createTextNode("Hello, world!"));
mylist.appendChild(li);
parent.insertBefore(mylist, button);
}
Tested on IE11 on Windows 7, Windows 8.1, and Windows 10 RTM (build 10240), and Microsoft Edge on Windows 10 RTM. Note that removing the list after inserting the item (right before putting it back in) does not work; you will need to remove it first.
The issue is related to cascaded selectors like the button in the selector ul:empty + button.
It's safe to use the :empty pseudo-class in IE11 when it applies to DOM element itself https://codepen.io/egeneralov/pen/geRQXz.
I am dynamically creating a text area, based on the number of each user, comment for each user.
i am using the below code to do the same, it works fine in all the browser except IE8.
$(template1).find('textarea').attr({"id":'selfasgn'+aud.ASGN_ID,"onchange":'captureSelfComments('+aud.ASGN_ID+')'})
note that $(template1) is clone of one of the element in node.
template1 = reviewTemplate.clone(true);
function captureSelfComments(p_asgnid){
alert('caling captureSelfComments');
}
I tried below code, but its getting called when this element gets constructed or appened to the DOM. so i removed it.
$(template1).find('textarea').live('change',captureSelfComments(aud.ASGN_ID))
am I doing anything wrong here ?
For IE, try propertychange() as described here since IE may not always support the change event.
var lowIE = /msie (6|7|8)/gi.test(window.navigator.userAgent);
$(template1).find('textarea').live(lowIE ? 'propertychange' : 'change',captureSelfComments(aud.ASGN_ID));
Generally, it is not a good idea to do user agent sniffing but we are talking about IE... which is basically also not a good idea, generally :)
When I select any option in list then it should print its value in textbox(all html).
I tried
stafflist.setAttribute("onchange", "javacript:document.getElementById('id_17_enrolpassword').value = this.value;");
Its working in IE8+ and all modern browsers but not in IE7.
Also tried
stafflist.addEventListener('onchange',"javacript:document.getElementById('id_17_enrolpassword').value = this.value;",false);
So what changes I should do here?
IE only fires the onchange event when the element loses focus - if you were to click outside the element or tab to a different element it should fire then.
You can get around this by using a different even, for example onkeypress
1) the javascript: label is only needed if the first script on the page is vbscript.
2) does this work better?
document.getElementById('stafflist').onchange=function(){
document.getElementById('id_17_enrolpassword').value = this.value;
}
?
do it this way -
stafflist.onchange = function(){
document.getElementById('id_17_enrolpassword').value= this.value;
}
I know this doesn't truly answer the question at hand, but, can't you use something like jQuery to code these sort of even handlings?
The code is a bit more readable (IMHO), and you don't have to deal this these cross-browser scripting issues yourself.
There's this question, but the solution posted is browser sniffing, which I'm trying to avoid.
I need to make my website compatible with the iPad and perhaps newer Androids. I've been using an old version of the FCKEditor (now CK Editor) for my WYSIWYG editors, but that doesn't work on mobile, so I want to swap it out for a simple textarea with something like markdown, if it's not supported.
Supposedly it won't work because mobile devices tend not to support this contentEditable property, which means the on-screen keyboard won't pop up when you click on it.
How can I detect if the browser supports contentEditable? It's been suggested that I just check the div in question with something like mydiv.contentElement === undefined or something like that, but the div (if it's using one) is all built into the FCK Editor and buried somewhere in an iframe.
Isn't there another way to detect if a browser supports contentEditable in general?
Just tried this:
var contentEditableSupport = typeof $('<div contenteditable="true">')[0].contentEditable !== 'undefined';
Says "true" on my iPad...... I don't think it should.
Edit: It's returning "string" because all attributes are strings.... it's just reading the attribute. How else am I supposed to do this?
You could create an anonymous editable div, check it for contentEditable, then remove the div.
Here is the test I use and is also used in Modernizr. It will give false positives in iOS 4 (and possibly earlier) but unfortunately it's impossible to detect in those environments.
var contentEditableSupport = "contentEditable" in document.documentElement;
I was able to accomplish this by checking the default value of the contentEditable property rather than the presence or type. The W3 spec indicates that the missing value default for contentEditable is "inherit", but in older browsers (e.g. Android/Gingerbread) the default value is "false". Thanks to fudgey for the comment on the OP that pointed me in the right direction!
This test works for me:
var contentEditableSupport = $('<div/>')[0].contentEditable == 'inherit';
Check for execCommand
if (document.execCommand) {
... browser supports contentEditable
} else {
... browser doesn't support contentEditable
}
To check if any propery exits for a element. You can do this
var element = document.createElement('__ELEMENT__');
if ('__PROPERTY__' in element ) {
// property supported in the browser
}
or
if ('__PROPERTY__' in document.createElement('__ELEMENT__') ) {
// property supported in the browser
}
The below link contains it all.
https://github.com/Modernizr/Modernizr/issues/570
http://diveintohtml5.info/everything.html#contenteditable