I require Cross patability IE7 upwards For an event listener. Due to the system I am using I can only use an external js file to create the listeners. I wish to create a rule for all textarea boxes, making they increase in height when they wrap the text meaning that you never have to scroll (They need to be printed with all the text showing). This works fine using addEventListener, but because I can't uses THIS I can not get this to work generically using attachEvent.
<html>
<style>
input[type="text"], textarea{ width:10%;}
</style>
<script>
function gettext(){
var x=document.getElementsByTagName("textarea");
var ent;
for(i = 0; i < x.length; i++){
if (x.item(i).addEventListener) {
x.item(i).addEventListener("keyup", function () {ChangeDepth(this)}, false)
x.item(i).addEventListener("mouseup", function () {ChangeDepth(this)}, false)
x.item(i).addEventListener("change", function () {ChangeDepth(this)}, false)
}
else {
ent = document.getElementById(x.item(i).id)
x.item(i).attachEvent ("onkeyup", function () {ChangeDepth(ent)});
x.item(i).attachEvent ("onmouseup", function () {ChangeDepth(ent)});
x.item(i).attachEvent ("onchange", function () {ChangeDepth(ent)});
}
}
}
function ChangeDepth(e){
var t = e.scrollHeight +'px';
if ((e.clientHeight < e.scrollHeight)||(e.clientHeight > e.scrollHeight)){e.style.height = t ;}
}
</script>
<body onload="gettext()">
<p>(Type in the textarea box when the text wraps it will increase the height of the box)<br />
<textarea name="c" cols="" rows="1" id="c" ></textarea>
<br />
<textarea name="f" cols="" rows="1" id="f" ></textarea></p>
</body>
</html>
This only works for the last textarea field in IE 8. I am assuming this because It only has the value of the last object. No idea what to do next
I require Cross patability IE7 upwards For an event listener. Due to the system I am using I can only use an external js file to create the listeners. I wish to create a rule for all textarea boxes, making they increase in height when they wrap the text meaning that you never have to scroll (They need to be printed with all the text showing). This works fine using addEventListener, but because I can't uses THIS I can not get this to work generically using attachEvent.
<html>
<style>
input[type="text"], textarea{ width:10%;}
</style>
<script>
function gettext(){
var x=document.getElementsByTagName("textarea");
var ent;
for(i = 0; i < x.length; i++){
if (x.item(i).addEventListener) {
x.item(i).addEventListener("keyup", function () {ChangeDepth(this)}, false)
x.item(i).addEventListener("mouseup", function () {ChangeDepth(this)}, false)
x.item(i).addEventListener("change", function () {ChangeDepth(this)}, false)
}
else {
ent = document.getElementById(x.item(i).id)
x.item(i).attachEvent ("onkeyup", function () {ChangeDepth(ent)});
x.item(i).attachEvent ("onmouseup", function () {ChangeDepth(ent)});
x.item(i).attachEvent ("onchange", function () {ChangeDepth(ent)});
}
}
}
function ChangeDepth(e){
var t = e.scrollHeight +'px';
if ((e.clientHeight < e.scrollHeight)||(e.clientHeight > e.scrollHeight)){e.style.height = t ;}
}
</script>
<body onload="gettext()">
<p>(Type in the textarea box when the text wraps it will increase the height of the box)<br />
<textarea name="c" cols="" rows="1" id="c" ></textarea>
<br />
<textarea name="f" cols="" rows="1" id="f" ></textarea></p>
</body>
</html>
This only works for the last textarea field in IE 8. I am assuming this because It only has the value of the last object. No idea what to do next
x.item(i).addEventListener("keyup", ChangeDepth, false)
Then you'll only need to change the ChangeDepth
function.
– Shmiddty
Commented
Sep 24, 2012 at 20:42
http://jsfiddle/KAy9a/
function wireUp() {
console.log('wiring');
var x = document.getElementsByTagName("textarea");
var ent;
for (i = 0; i < x.length; i++) {
if (x.item(i).addEventListener) {
x.item(i).addEventListener("keyup", ChangeDepth, false)
x.item(i).addEventListener("mouseup", ChangeDepth, false)
x.item(i).addEventListener("change", ChangeDepth, false)
}
else {
x.item(i).attachEvent("onkeyup", ChangeDepth);
x.item(i).attachEvent("onmouseup", ChangeDepth);
x.item(i).attachEvent("onchange", ChangeDepth);
}
}
}
function ChangeDepth(e) {
// instead of passing in the element, we get the Event object
// we can then get the event target (or srcElement) to know where the event came from
e = e || event;
e = e.target || e.srcElement;
// the code below is the same you had before:
var t = e.scrollHeight + 'px';
if ((e.clientHeight < e.scrollHeight) || (e.clientHeight > e.scrollHeight)) {
e.style.height = t;
}
}
You can use a cross–browser addEvent
function that sets this
to the element within the listener for browsers that use the old IE event model (which includes IE 8 in quirks mode). e.g.
function addEvent(el, evt, fn) {
if (el.addEventListener) {
el.addEventListener(evt, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + evt, function() {fn.call(el);});
}
}
Now in your code you can do:
function gettext() {
var x = document.getElementsByTagName("textarea");
var ent;
Declare an extra variable to store a reference to the current element.
var el;
for (var i = 0; i < x.length; i++) {
Note that i
should be declared, otherwise it will bee a global variable when the above is executed and possibly mess with other code.
el = x[i];
Since getElementsByTagName
returns a NodeList, you can access members by index, which is less to type. Storing a reference is (imperceptibly) faster and less to type later.
addEvent(el, 'keyup', ChangeDepth);
addEvent(el, 'mouseup', ChangeDepth);
addEvent(el, 'change', ChangeDepth);
}
You no longer need to pass a reference to the element since in the listener it will be this
. Note that where addEventListener
was used to attach the listener, the first argument passed will be the event object. But where attachEvent
was used, it won't be passed so get it using window.event
.
function ChangeDepth(e) {
// Get a reference to the related event object
var e = e || window.event;
// Get a reference to the element that called the listener
var elementThatCalledListener = this;
...
}
This seems to work - JavaScript:
function load() {
'use strict';
function changeHeight(){
var elem = document.activeElement;
var heightStr = elem.scrollHeight +'px';
if ((elem.clientHeight < elem.scrollHeight) || (elem.clientHeight > elem.scrollHeight))
{elem.style.height = heightStr ;}
}
var x = document.getElementsByTagName("textarea");
var i;
for (i = 0; i < x.length; i++) {
if (x[i].addEventListener) {
x[i].addEventListener("keyup", changeHeight)
x[i].addEventListener("mouseup", changeHeight)
x[i].addEventListener("change", changeHeight)
}
else {
x[i].attachEvent("onkeyup", changeHeight);
x[i].attachEvent("onmouseup", changeHeight);
x[i].attachEvent("onchange", changeHeight);
}
}
}
if (window.addEventListener) {
window.addEventListener('load', load);
} else if (window.attachEvent) {
window.attachEvent('onload', load);
}
HTML:
<!DOCTYPE html>
<style>
input[type="text"], textarea {
width: 10%;
}
</style>
<p>(Type in the textarea box when the text wraps it will increase the height of the box)<br/>
<textarea rows='1'></textarea>
<br/>
<textarea rows='1'></textarea>
</p>
<script type="text/javascript" src="legacyEventIE.js"></script>
</body>
</html>
Here is a link to the working code:
http://www.quirkscode./flat/forumPosts/legacyEventIE/legacyEventIE.html
You should avoid creating functions inside loops. This causes problems because the variables used are closure-scoped to the encapsulating function and therefore are mon to all the "new" functions.
In other words:
var i, fns = [];
for(i = 0; i < 10; i++) {
fns.push(function () { return i; });
}
Will create 10 functions that all return 10
(or whatever i
ends up being):
fn[0](); //is 10
fn[5](); //is 10
i = 5;
fn[5](); //is 5
There are a few ways to fix this. The first is to use a function wrapper and pass in the dynamic variable as an argument. Like so:
ent = document.getElementById(x.item(i).id)
(function (my_ent, my_i) {
x.item(my_i).attachEvent ("onkeyup", function () {ChangeDepth(my_ent)});
x.item(my_i).attachEvent ("onmouseup", function () {ChangeDepth(my_ent)});
x.item(my_i).attachEvent ("onchange", function () {ChangeDepth(my_ent)});
}(ent, i));
Another, arguably better, solution (at least one that won't cause JSLint to yell at you) is to create a generator function:
var attachEvents = function (item, ent) {
item.attachEvent ("onkeyup", function () {ChangeDepth(ent)});
item.attachEvent ("onmouseup", function () {ChangeDepth(ent)});
item.attachEvent ("onchange", function () {ChangeDepth(ent)});
};
//... Inside the for loop:
else {
ent = document.getElementById(x.item(i).id)
attachEvents(x.item(i), ent);
}
This is better because its not as "heavy" and it is easier to determine what data are relevant to the creation of the event handlers (e.g. it's easier to maintain).
But it does require more of a change. So it's up to you.
var add_event_column_rubrics = function(){
var id_current_event;
var secect_class_column_rubrics = document.querySelector('.rubric_click');
if(secect_class_column_rubrics.addEventListener)//other
secect_class_column_rubrics.addEventListener('click',function(e){f_secect_class_column_rubrics(e)},false);
else{if(secect_class_column_rubrics.attachEvent)//IE
secect_class_column_rubrics.addEventListener('onclick',f_secect_class_column_rubrics);
}
var f_secect_class_column_rubrics = function(e){
e=e||window.event;
e=e.target||e.srcElement;`enter code here`
// console.log(e);//debug
id_current_event = e.id;
alert(id_current_event);
};
};