V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
lisisi
V2EX  ›  JavaScript

document.querySelector("#id") 和 document.getElementById("id") 有什么区别吗?

  •  
  •   lisisi · 2019-12-27 18:59:34 +08:00 · 6761 次点击
    这是一个创建于 1794 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1、看到一些 document.querySelector("#id") 的用法,这个新方法比 document.getElementById("id") 有什么优势吗?
    2、遇到 id 是变量,document.querySelector("#id") 怎么传 id 进来呢?

    const foo = 'id_Name';
    document.querySelector("#" + foo)
    

    试了下,上面这样写没效的

    32 条回复    2019-12-28 17:21:36 +08:00
    Danswerme
        1
    Danswerme  
       2019-12-27 19:18:06 +08:00 via Android
    1. querySelector 接收一个 css 选择器字符串,比如 "#root > .nav:nth-child(1)",后者只能接收 id 名称。
    2. 请检查你的代码
    ysc3839
        2
    ysc3839  
       2019-12-27 19:20:07 +08:00 via Android
    我觉得没有优势,因为要解析 css 选择器。
    Cbdy
        3
    Cbdy  
       2019-12-27 19:22:56 +08:00
    没有区别
    stillsilly
        4
    stillsilly  
       2019-12-27 19:31:20 +08:00 via iPhone
    有区别,不过我现在在外面没时间也没电脑,晚上回家没人回答的话我来解释一下
    lisisi
        5
    lisisi  
    OP
       2019-12-27 19:52:59 +08:00
    @Danswerme document.getElementById("id") 中的 id 可以直接把变量传进来,document.querySelector("#id") 中的 id 并没有看到可用的传值方式。不知道你有没有明白我说的问题?
    littlepanzh
        6
    littlepanzh  
       2019-12-27 20:10:27 +08:00 via iPhone
    现在的前端真幸福,不用考虑 IE6 7
    noreplay
        7
    noreplay  
       2019-12-27 21:36:23 +08:00
    MDN 上有解释
    https://developer.mozilla.org/zh-CN/docs/Web/API/Document/getElementById

    然而你的那个代码是有效的。
    你可以打开控制台,试下下面的代码
    const id="Wrapper";
    document.querySelector('#'+id)
    lxk11153
        8
    lxk11153  
       2019-12-27 21:36:56 +08:00
    @Danswerme #1 对于问题 1,求深入点,内部实现呢?仅比较 getElementById("id")和 querySelector("#id"),内部会不会掉用到同一处实现呢?你这回答的太表象了,肉眼都能识别啊
    @lisisi #5 对于问题 2,字符串拼接传咯?有什么问题?
    429463267
        9
    429463267  
       2019-12-27 21:40:10 +08:00 via Android
    你说的是 jsoup api ?
    VDimos
        10
    VDimos  
       2019-12-27 21:50:17 +08:00 via Android
    这还新方法,这 api 不都好久了吗
    netChen
        11
    netChen  
       2019-12-27 21:53:40 +08:00
    还是楼上那句话,现在前端真幸福,不用考虑 IE6
    autoxbc
        12
    autoxbc  
       2019-12-27 22:05:28 +08:00
    从一致性上说,应该只使用 querySelector,其他元素选择方法一律弃用

    不要考虑性能问题,这是引擎设计者应该考虑的,可维护性才是重点
    lxk11153
        13
    lxk11153  
       2019-12-27 22:09:21 +08:00
    @noreplay #7 之前还没注意,querySelector 有 2 个
    - Document.getElementById()
    - Document.querySelector() https://developer.mozilla.org/zh-CN/docs/Web/API/Document
    - Element.querySelector() https://developer.mozilla.org/zh-CN/docs/Web/API/Element

    So: document.querySelector("#id")和 document.getElementById("id")内部会不会调用到同一处实现呢?
    vanishcode
        14
    vanishcode  
       2019-12-27 22:17:14 +08:00
    一个是静态一个是动态
    前者是后者的引用所以要慢一些
    不知道是不是记错了。。。欢迎老哥指正。。。
    Mutoo
        15
    Mutoo  
       2019-12-27 22:33:46 +08:00
    @lxk11153 当然是同一个,因为 Document 和 Element 的 querySelector() 都是继承自 ParentNode.querySelector()
    lxk11153
        16
    lxk11153  
       2019-12-27 23:09:07 +08:00
    @Mutoo #15 感谢,文档还是没有源码细。。
    Talk is cheap show me the code.
    Code never lies, comments sometimes do.
    zhlssg
        17
    zhlssg  
       2019-12-27 23:47:12 +08:00
    querySelector 和 querySelector 可以代替 className, tagName, id 这些旧的 api,好记也是优点吧
    zhlssg
        18
    zhlssg  
       2019-12-27 23:48:10 +08:00
    @zhlssg querySelectorAll
    secondwtq
        19
    secondwtq  
       2019-12-27 23:51:22 +08:00
    #8 难道是楼主的小号 ...

    用 querySelector + 字符串拼接意味着可以 query 的不只 id ... 在输入的字符串后面可以加其他选择器

    @ysc3839 选择器只用解析一遍,有缓存
    但是用来做同样的工作,前者是要稍微慢一点(因为确实包了一层)
    geelaw
        20
    geelaw  
       2019-12-28 00:05:52 +08:00 via iPhone   ❤️ 1
    lihongming
        21
    lihongming  
       2019-12-28 01:28:39 +08:00 via iPhone
    @littlepanzh 现在前端的发展趋势是根本不写最终执行的代码,而是全都用最新语法(现在是 ES6 ),并用 webpack 之类的工具“编译”成可执行的代码,所以根本不用考虑兼容性。
    yimity
        22
    yimity  
       2019-12-28 08:47:11 +08:00   ❤️ 1
    你的传 id 变量的代码没问题,不过传变量是最基础的知识了。
    getElementBy 获取到的是动态的,即 你增加了 dom,再获取还是可以获取到你最新增加的的,你删掉了 dom,再获取的时候,之前获取到的就不在了,就是每次都是实时从 dom 树里面获取。
    而 querySelector 是引用,即获取一次后面增加的 dom,不会获取到了,删掉了 dom, 在代码中还是能够用(但是会报错)。
    old9
        23
    old9  
       2019-12-28 10:19:35 +08:00 via Android
    本帖这都是些什么乱七八糟的
    c6h6benzene
        24
    c6h6benzene  
       2019-12-28 10:36:42 +08:00 via iPhone
    昨天刚看到,现学现用:

    理论上 id 不应该重名,但现实总有各种可能。querySelector 会拿到同一个 id 的多个元素,getElementbyID 只有一个。
    jinliming2
        25
    jinliming2  
       2019-12-28 10:37:48 +08:00 via iPhone
    @lihongming emmmmm,我这里不考虑兼容性的做法是直接写最终执行的代码,也就是 ES6 (目前是 ES2019,稍微超前一点的部分 ES2020 也用,比如 BigInt 啥的),而不经过 Webpack babel 之类“编译”,直接用就好……
    因为,我这里目标用户基本都是 Chrome Firefox 这些了……所以不需要考虑向下兼容……

    直接写最终代码,在调试断点的时候,是真的爽……毕竟代码没有被转换为 ES3 ES5 这些的等效代码,而是浏览器解释器直接内部实现,速度更快,调试的时候非常爽!
    babel 转码过之后大部分都是 ES3 ES5 的代码,载入 Source Map 又卡又慢,断点还时不时打不到正确的位置上……
    miniwade514
        26
    miniwade514  
       2019-12-28 10:48:07 +08:00 via iPhone
    不用兼容 8- 也算是幸福的事了?当年需要兼容的时候也不见得都是手撸兼容啊,那几位在秀什么。
    querySelector 的性能不需要纠结,你的 DOM 树八成还没有复杂到需要纠结这种基础 API 性能的地步。
    grewer
        27
    grewer  
       2019-12-28 11:03:26 +08:00
    GitHub 都在全面用 querySelector 这种方法了
    lisisi
        28
    lisisi  
    OP
       2019-12-28 11:28:27 +08:00
    @yimity 可能是你说的这个原因,id 是写死的没问题,id 是中间生成的,querySelector 就选不到了,只能用 getElementBy 来取。
    secondwtq
        29
    secondwtq  
       2019-12-28 12:09:59 +08:00
    @grewer 不能拿 GitHub 做例子,据我观察 GitHub 是最激进的站点之一,我 Mac 上的老版 Chrome,GitHub 不能加载最新 commit,branch 的菜单点不开。另外 YouTube 不能看。

    其他网站没出过问题,说明 GitHub 和 Google 可能确实对浏览器要求比较高。
    secondwtq
        30
    secondwtq  
       2019-12-28 13:21:54 +08:00
    @yimity
    “getElementBy 获取到的是动态的,即 你增加了 dom,再获取还是可以获取到你最新增加的的,你删掉了 dom,再获取的时候,之前获取到的就不在了,就是每次都是实时从 dom 树里面获取。
    而 querySelector 是引用,即获取一次后面增加的 dom,不会获取到了,删掉了 dom, 在代码中还是能够用(但是会报错)。”

    求依据:标准,源码,或示例
    你说的可能是 getElementByClassName/TagName 和 querySelectorAll
    楼主这个好像没这个区别
    uqf0663
        31
    uqf0663  
       2019-12-28 14:25:41 +08:00
    在本页按 F12 在控制台输入
    const q = 'q';
    document.querySelector("#" + q).value="可以啊";

    能够正常往最上面的搜索 input 写字啊,没问题啊,哪里不行了?
    jsq2627
        32
    jsq2627  
       2019-12-28 17:21:36 +08:00
    除了用法上,功能上没区别

    用法上,很多人会忽视掉 css selector 的 escaping 问题,例如对于:
    <div id="123" />
    用 document.getElementById("123") 是没问题的,但是 document.querySelector("#123") 就是不对的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   904 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 22:04 · PVG 06:04 · LAX 14:04 · JFK 17:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.