zoukankan      html  css  js  c++  java
  • 批量处理标签属性中document.getElementsByName()的替代方案

    背景

    今天在逛知乎时候,看到一个JavaScript方面的问题:

    最近在学习JavaScript DOM,就好奇地查阅资料,以及请教学长,得到下面解答:
    http://www.w3help.org/zh-cn/causes/SD9012
    http://www.w3help.org/zh-cn/causes/SD9001

    document.getElementsByName(elementName) 方法是 HTMLDocument 接口提供的方法,该方法传入的参数应该是目标元素的 name 属性的值:
    目标元素的 name 是一个大小写敏感的字符串,仅 BUTTON, TEXTAREA, APPLET, SELECT, FORM, FRAME, IFRAME, IMG, A, INPUT, OBJECT, MAP, PARAM, META 元素允许有 name 属性1,并且 name 属性可以不是唯一的。
    在IE 中,只有这些标签有 'name' 属性时,可以使用 document.getElementsByName(elementName) 方法获取他们创建的 DOM 元素,但在其他浏览器中,有 'name' 属性的其他标签也可以用这种方法获取。即

    可以在其他浏览器中通过使用 document.getElementsByName('test')[0] 来获取,但在 IE 中却不行,得到的将是 undefined。
    使用 document.getElementsByName 方法获取页面内的元素时,在 IE6 IE7 IE8 中的 name 是大小写不敏感的。

    源代码

    
    var reliableGetByName = true;
    
    // IE6/7/8(Q)有id和name混淆的问题, IE6/7/8有不能获取非form和不区分大小写的问题
    (function () {
     var div = document.createElement('div');
     var expando = 'selector-' + new Date().getTime();
     document.body.appendChild(div).name = expando;
     reliableGetByName = !document.getElementsByName(expando.toUpperCase()).length;
     document.body.removeChild(div);
     div = null;
    })();
    
    function getElemensByName(name, context) {
    
    context = context || document;
    
    var seeds;
    
    // 只有document有这个方法
    if (reliableGetByName && context.getElementsByName) {
     seeds = context.getElementsByName(name);
     }
     else {
     seeds = context.getElementsByTagName('*');
     }
    
    var results = [];
     var elem;
    
    for (var i = 0, len = seeds.length; i !== len && (elem = seeds[i]) != null; i++) {
     if (elem && elem.nodeType === 1 && elem.getAttribute('name') === name) {
     results.push(elem);
     }
     }
    
    return results;
    }
    
    

    具体思路

    1.判断浏览器是否支持getElementsByName函数

    先生成一个div,给div加一个name = 随机串,如果可以找到,就说明是IE9+;找不到就是IE8-,还有一种方法是利用IE6/7/8不区分大小写判断的。

    
     var reliableGetByName = true;
    
    // IE6/7/8(Q)有id和name混淆的问题, IE6/7/8有不能获取非form和不区分大小写的问题
    (function () {
     var div = document.createElement('div');
     var expando = 'selector-' + new Date().getTime();
     document.body.appendChild(div).name = expando;
     reliableGetByName = !document.getElementsByName(expando.toUpperCase()).length;
     document.body.removeChild(div);
     div = null;
    })();
    
    

    2.在context中找name为name的所有元素,返回一个数组

    
    function getElemensByName(name, context) {
    
    context = context || document;
    
    var seeds;
    if (reliableGetByName && context.getElementsByName) {
     seeds = context.getElementsByName(name);
     }
     else {
     seeds = context.getElementsByTagName('*');
     }
    

    3.判断elem存在,elem.nodeType=== 1 是元素,然后elem.name 是给的name

    var results = [];
     var elem;
    
    for (var i = 0, len = seeds.length; i !== len && (elem = seeds[i]) != null; i++) {
     if (elem && elem.nodeType === 1 && elem.getAttribute('name') === name) {
     results.push(elem);
     }
     }
    
    return results;
    }
    

    分析

    以上代码可以解决四个问题:
    1、IE67混淆id和name
    2、IE678不能获取非表单元素
    3、IE678忽略大小写
    4、只有document.getElementByName而没有elem.getElementByName的问题

  • 相关阅读:
    Hibernate 事务和并发控制
    InfoSYS-20170114
    STM32学习笔记:读写内部Flash(介绍+附代码)
    STM32串口通信配置(USART1+USART2+USART3+UART4)
    Keil-MDK编译完成后代码大小
    STM32窗口看门狗和独立看门狗的区别,看门狗介绍及代码演示
    关于单片机编程里面调用sprintf死机的解决方法及原因分析
    ESP8266 wifi 模块配置,Wechat+APP控制实现
    STM32常见问题
    深入浅出 TCP/IP 协议
  • 原文地址:https://www.cnblogs.com/QingFlye/p/4398793.html
Copyright © 2011-2022 走看看