attachEvent无法使用此JavaScript

时间:2012-09-24 20:27:50

标签: javascript this getelementsbytagname attachevent

我需要交叉兼容性IE7向上用于事件监听器。由于我使用的系统,我只能使用外部js文件来创建监听器。 我希望为所有textarea框创建一个规则,使它们在包装文本时增加高度,这意味着您永远不必滚动(它们需要打印所有文本显示)。这可以使用addEventListener工作正常,但因为我不能使用这个我无法使用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>

这仅适用于IE 8中的最后一个textarea字段。我假设这是因为它只有最后一个对象的值。 不知道下一步该做什么

5 个答案:

答案 0 :(得分:3)

http://jsfiddle.net/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;
    }
}

答案 1 :(得分:2)

对于使用旧IE事件模型(在quirks模式下包含IE 8)的浏览器,您可以使用跨浏览器addEvent函数将this设置为侦听器中的元素。 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);});
  }
}

现在,您可以在代码中执行以下操作:

function gettext() {
  var x = document.getElementsByTagName("textarea");
  var ent; 

声明一个额外的变量来存储对当前元素的引用。

  var el;

  for (var i = 0; i < x.length; i++) {

请注意,应声明i,否则在执行上述操作时它将成为全局变量,并可能与其他代码混淆。

    el = x[i];

由于getElementsByTagName返回NodeList,您可以按索引访问成员,而不是键入。存储引用(不知不觉)更快,而不是稍后输入。

    addEvent(el, 'keyup', ChangeDepth);
    addEvent(el, 'mouseup', ChangeDepth);
    addEvent(el, 'change', ChangeDepth);
 } 

您不再需要传递对元素的引用,因为在侦听器中它将是this。请注意,在addEventListener用于附加侦听器的位置,传递的第一个参数将是事件对象。但是在使用attachEvent的情况下,它将不会被传递,因此请使用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;

  ...

}

答案 2 :(得分:1)

这似乎有效 - 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>

以下是工作代码的链接:

http://www.quirkscode.com/flat/forumPosts/legacyEventIE/legacyEventIE.html

答案 3 :(得分:0)

您应该避免在循环内创建函数。这会导致问题,因为使用的变量是封装范围到封装函数,因此对所有“新”函数都是通用的。

换句话说:

var i, fns = [];
for(i = 0; i < 10; i++) {
    fns.push(function () { return i; });
}

将创建10个函数,这些函数全部返回10(或最终为i}:

fn[0](); //is 10
fn[5](); //is 10
i = 5;
fn[5](); //is 5

有几种方法可以解决这个问题。第一种是使用函数包装器并将动态变量作为参数传递。像这样:

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));

另一个可以说是更好的解决方案(至少一个不会导致JSLint对你大喊大叫的解决方案)是创建一个生成器函数:

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);
    }

这样做更好,因为它不那么“重”,更容易确定哪些数据与事件处理程序的创建相关(例如,它更容易维护)。

但它确实需要更多改变。所以这取决于你。

答案 4 :(得分:0)

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);
    };
};