1

我需要跨兼容性 IE7 向上对于事件侦听器。由于我使用的系统,我只能使用外部 js 文件来创建侦听器。我希望为所有 textarea 框创建一个规则,使它们在包装文本时增加高度,这意味着您永远不必滚动(它们需要打印所有显示的文本)。使用 addEventListener 可以正常工作,但是因为我不能使用 THIS,所以我无法使用 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 字段。我假设这是因为它只有最后一个对象的值。不知道下一步该做什么

4

5 回答 5

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;
    }
}
于 2012-09-24T20:44:25.493 回答
2

对于使用旧 IE 事件模型(包括 IE 8 的 quirks 模式)的浏览器,您可以使用跨浏览器addEvent函数设置侦听器中的元素。this例如

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;

  ...

}
于 2012-09-24T23:42:31.180 回答
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

于 2012-09-24T22:38:51.433 回答
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);
    }

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

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

于 2012-09-24T20:48:30.277 回答
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);
    };
};
于 2014-02-20T10:26:10.713 回答