展开目录
判断一个object是否HTMLDom
htmljavascript技巧
X
陈尼玛的博客
记录开发生涯的踩坑经历,用时间来验证成长
加载中

需要写一个函数,要求是传入参数为object,判断如果是HTMLDom则执行后续流程,否则抛异常。

如果不考虑过时的ie6,7等浏览器,可以直接用 xx instanceof HTMLElement 来判断。不过我还是想考虑更通用的做法,在低版本ie上也能跑。实际上完全可以做到,办法是使用id这个特殊属性,通过 document.getElementById 获取后判断是否是同一个对象,是则证明为HTMLDom。

<meta charset='utf-8'>
<body>
<script>
function isHtmlDom(anything){
    // 判断是否为空
    // 因为老版本ie的Dom instanceof Object会取出false,所以这里不能用instanceof运算
    if(!anything)throw 'not an object';
    // 是否页面上有这个对象
    var hasId=function(id){
      return document.getElementById(id);
    };
    // 是否本身具备id属性
    var has=Object.prototype.hasOwnProperty.call(anything,'id'); // 老版本的ie没有hasOwnProperty
    try{
      has=has || anything.hasOwnProperty(id);// 现代浏览器使用hasOwnProperty来检查
    }catch(e){}
    // 保留旧id,之后还要变回来的
    var oldid=[
      has,
      anything.id //旧id
    ];
    // 若没有则随机产生一个
    if(!anything.id){
      var id;
      for(var i=0;;i++){
        id=[i,'_',Math.random()*999999|0];
        if(!hasId(id))break;
      }
      anything.id=id;
    }
    // 是否能用id获取到这个对象
    // 情况1,已在dom树中,可以直接取到
    var exists=hasId(anything.id)===anything;
    // 情况2,没有在dom树中,所以需要添加一次后才可以获取
    if(!exists){
      try{
        document.body.appendChild(anything);
        exists=hasId(anything.id)===anything;
        document.body.removeChild(anything);
      }catch(e){
        exists=false;
      }
    }
    // 还原
    if(oldid[0])anything.id=oldid[1];
    else delete anything[id];

    return exists;
}

// 为了演示低版本上的效果,所以这段代码用for的语法来写
var list=[document,document.body,{id:'xx'},null];
for(var i=0;i<list.length;i++){
  try{
    isHtmlDom(list[i]);
    list[i]=[i,true];
  }catch(e){
    list[i]=[i,false,e];
  }
}
alert(list.join('\n'));
</script>
</body>

相关文档

暂无

随便看看

  1. 记一次nodejs内存泄漏的排查经历

  2. cnpm 立即同步

  3. mac ssh透过代理连接

  4. react项目webpack打包时拆分异步加载的文件

  5. 安卓文字偏上,文字顶部被遮罩

  6. npm远程服务器某些配置不兼容代理的解决办法

  7. nodejs本地双向代理 端口转发

  8. 判断变量是否 0 或者 '0'

  9. 树莓派 3B/3B+ usb启动

  10. dd备份/还原

  11. linux自启动/禁止自启动服务

  12. cdn资源列表

  13. webpack使用外部资源

  14. 把树莓派的存储空间拓展到整张TF卡中

  15. python下载文件,带进度条控制

  16. centos查看最近一次的开机时间

  17. ie8上Image.onload不触发问题

  18. bootstrap modal弹框导致ie无法获取焦点

  19. 数据库清理优化

畅言模块加载中