【问题标题】:IE9 error: Object doesn't support property or method 'setAttribute'IE9 错误:对象不支持属性或方法“setAttribute”
【发布时间】:2013-01-30 22:23:29
【问题描述】:

功能:

function disable_hidden_flip_questions(option, value){
    var first_q = document.getElementById('hidden_auto_questions');
    var second_q = document.getElementById('hidden_include_auto');
    var inputs_list = [];
    if(option == 'all'){
        inputs_list.push(first_q.getElementsByTagName("input"));
        inputs_list.push(second_q.getElementsByTagName("input"));
    }else if (option == 'first'){
        inputs_list.push(first_q.getElementsByTagName("input"));
    }else if(option == 'second'){
        inputs_list.push(second_q.getElementsByTagName("input"));
    }

    for (var inputs in inputs_list){
        for(var input in inputs_list[inputs]){
            if(inputs_list[inputs].hasOwnProperty(input) && input != 'length'){
                if(!value){
                    inputs_list[inputs][input].removeAttribute('disabled');
                }else{
                    inputs_list[inputs][input].setAttribute("disabled", "disabled");
                }
            }
        }
    }
}

在 Chrome 和 Firefox 中运行良好,但在 IE9 中,控制台在这一行给我一个错误:

inputs_list[inputs][input].setAttribute("disabled", "disabled")

如果我 console.log(inputs_list[inputs][input]) 我在 Chrome 中得到这个:

(输入是由 RoR 生成的,这就是为什么它的 nameid 这么长)

<input class="radio_buttons optional" id="custom_attributes_trailer_insurance_endorsement_false" name="custom_attributes[trailer_insurance_endorsement]" type="radio" value="false" disabled="disabled"> 

是的,这就是我想要的(和期望的)...但是在 IE9 的控制台中我得到了这个:

[object HTMLCollection]

这完全没用……

所以问题:在 IE 的崇高观点中我哪里出错了?我知道 IE9 支持 setAttribute,所以我假设它与我的 for...in 循环有关。

编辑:因此,由于 cmets,问题可能出在对象类型上(HTMLCollection 存储在 Array 中)。如果确实如此,我该如何让所有数据类型都兼容?

【问题讨论】:

  • 有什么理由不使用 jQuery 来避免这种类型的跨浏览器垃圾?
  • 是的 - jQuery 中有很多不错的东西和库,但是 this 是使用它的真正原因(或类似的跨浏览器解决方案)。
  • @StephenP 你有 jquery 解决方案吗?
  • @ryan - 正如@vaporbook 在他的回答中指出的那样,您从getElementsByTagName 中得到一个HTMLCollection - 浏览器实现为您提供的“本机”对象,因此可以因浏览器而异(虽然它不应该)——使用像 jQuery 这样的库的主要原因是 it 处理像这样的跨浏览器差异。 jQuery 还为您提供了更一致的处理方式。在 jQuery 中,您可能会按照 $("#hidden_auto_questions input").each(call_my_function); 的方式做一些事情(注意 CSS 样式选择器)

标签: javascript internet-explorer-9


【解决方案1】:

HTMLCollections 并不是真正的数组,因此以这种方式处理它们可能会得到不一致的结果。虽然所有浏览器都会从 getElementsByTagName 返回一个 HTMLCollection,但它们允许您处理它们的方式可能存在重大差异。最好的方法是使用 DOM 方法从 HTMLCollection 访问内容 - 因此您将使用 .item(0) 来确保您引用的是 dom 节点而不是集合本身(请参阅https://developer.mozilla.org/en-US/docs/DOM/HTMLCollection)。此外,您不会尝试操作集合列表,因此如果您确实使用数组将数据推送到其中,请确保它们是单独的数据而不是 HTMLCollection。

【讨论】:

  • 它在您链接到的文档中说我可以使用方括号语法来访问 htmlCollection 的项目,因为此时它给我的错误 [input] 只是一个索引项目,所以它与说.item(0) 相同
  • 是的,没错。当您执行“inputs_list.push(first_q.getElementsByTagName("input"));”时您实际上是在将 HTMLCollection 推送到 javascript 数组对象上。但你对他们一视同仁。很抱歉,我无法提供您应该进行的一项更改来修复它,只是说这是我认为问题根源的这两种非等效数据结构的混合处理。
【解决方案2】:

jquery 中的解决方案:

  $("input[name=trailer_use]").click(function(event){
        if(event.target.id == "trailer_use_yes"){
            $("#hidden_auto_questions").removeClass('hide_auto').addClass('show_auto');
            $("input[name=trailer_insured]").removeAttr("disabled");
            show_trailer_warning(null, "remove");
        }else {
            $("#hidden_auto_questions").removeClass('show_auto').addClass('hide_auto');
            $("input[name=trailer_insured]").attr("disabled", "disabled");
            if($("#hidden_include_auto").hasClass("show_auto")){
                $("#hidden_include_auto").removeClass('show_auto').addClass('hide_auto');
                $('input[name="custom_attributes[trailer_insurance_endorsement]"]').attr("disabled", "disabled");
            }
            show_trailer_warning(null, "disclaimer");
        }
  });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多