精华内容
下载资源
问答
  • 在前端开发过程中,我们通过浏览器的页面来查看我们代码编写的成果。然而浏览器的功能非常强大,它不只是能展示我们编写的页面,还能够帮助我们定位开发过程中遇到的问题,提升我们的开发效率。有些时候我们甚至还...

    在前端开发过程中,我们通过浏览器的页面来查看我们代码编写的成果。然而浏览器的功能非常强大,它不只是能展示我们编写的页面,还能够帮助我们定位开发过程中遇到的问题,提升我们的开发效率。有些时候我们甚至还可以通过浏览器的调试工具来查看一些网站酷炫效果的实现方式。下面我们以Chrome浏览器为例,来介绍一些常用的调试技巧。

    c3b344471dc45d61c53efdf8ee91fc7f.png

    1. Chrome开发者工具

    首先我们打开Chrome的开发者工具(又称控制台),打开方式有以下几种:

    1. 点击浏览器右上角竖排的“三个点”,选择“更多工具”,再选择“开发者工具”打开
    2. 单机鼠标右键,点击“查看”选项打开
    3. 通过按快捷键 Ctrl + shift + I 快速打开

    通过以上任意一种方式打开开发者工具后,我们能够看到这样的界面(一般F12可以查看)。

    7ecb57f5782f42014ea93b1b73a1434c.png

    开发者工具界面的信息量比较大,不过不用担心,我们一点点来看。工具栏上前几个tab是我们最常用的调试模块。

    Element: 用于查看和编辑DOM节点和节点相对应的CSS样式

    Console:用于打印运行时抛出的信息,我们可以通过它查看异常信息或主动抛出信息进行调试。

    Sources: 用于查看资源信息,我们编写和运行的代码都可以在这里找到。我们可以通过在这里设置断点来达到调试的目的。

    Network: 用于查看请求信息,这里可以看到所有的页面资源请求,包括网络请求、图片资源、HTML、CSS、JS等。可以根据需求筛选请求项,一般多用于网络请求的查看和分析。

    Performance: 用于查看页面加载的性能情况,包括页面渲染时间、JS执行时间等。

    Application:用于查看 cookie、localStorage 等信息。

    以上是Chrome开发者工具的主要功能模块,虽然内容略多,但是正因为有了这些信息,浏览器的调试功能才会如此强大。现在记不住这些模块也没关系,接下来我们将通过使用这些调试工具,来加深对它们的理解,并看看它们能为我们的开发带来怎样的帮助。

    2. DOM调试

    2.1 查看 DOM

    在浏览器中,如果我们想要了解一个页面的 DOM 结构,我们可以通过开发者工具中的 Element 模块进行查看。我们首先编写一段 HTML

    186fe601591abcf134e04fcfb398490b.png

    保存这段 HTML 后在浏览器打开,并开启控制台。我们将工具栏选中到 Element ,会看到这样的信息

    af925daf08ad7f3e41df602795c560ba.png

    你会发现这里展示的 DOM 结构就是我们写的 HTML ,浏览器不仅将我们的 HTML 渲染成页面,还将它的 DOM 显示在控制台中方便我们调试。

    用鼠标在控制台里选中不同的 DOM 节点,会发现页面中有蓝色区块会随着鼠标选中 DOM 节点的变化而调整,实际上 蓝色区块就是当前 DOM 节点对应渲染的页面部分

    2.2 定位 DOM

    当一个页面结构比较复杂,层级较深的时候,我们通过移动鼠标在 DOM 节点中寻找需要查看的节点就会变得比较麻烦。要点开它的外层节点并一级一级找下去,这样的查找方式费时费力,因此浏览器控制台提供了一个方便定位 DOM 的功能。

    依然是上面那个例子,如果我们需要去找到 table 中的第一行第二列的那个单元格,怎样操作比较迅速?这里我们通过点击控制台左上角的一个定位按钮来进行快速选中。打开控制台,点击定位按钮,点击后该按钮会变成蓝色,标志我们当前正处于定位模式(定位模式下鼠标无法触发页面交互,如按钮事件等)。

    b70489bb3a3c15488edd5d0ff5397b9c.png

    接下来我们在页面上点击我们想要查看的元素,点击页面上table 中第一行第二列的单元格(显示 2 的那个)。点击后我们发现控制台的 Element 直接将那个

    节点高亮定位了。
    b3f05bd8b41df611025d3c6095d0be0e.png

    这样我们就迅速的定位了我们想要查看的 DOM 节点,此时定位按钮从蓝色变为灰色,标志着定位完成,退出定位模式。快速定位的功能在复杂结构的页面中尤为实用,我们可以在开发过程中充分利用起来。

    2.3 操作 DOM

    完成了 DOM 的定位,接下来我们可以对 DOM 元素做一些操作。对当前选中的 DOM 元素点击右键可以看到一系列的操作选项。

    ff61640d049ae1e2859162e1c37f0cd8.png

    点击 Edit as HTML 来对当前的 DOM 节点做改写和添加,例如这里我们对

    标签做编辑,在后面添加另一个

    标签。

    0d57b8272ac1759c174923d12d75473c.png

    完成后点击旁边未被选中到元素即可保存编辑,并在浏览器页面上同步生效。此时可以发现页面上已经出现了我们刚刚添加的节点了。

    7bccabf3903f3c4c4da297aeebfbf162.png

    如果你想撤销上一次 DOM 变更,按 ctrl + Z 即可,重做则按 ctrl + shift + Z。

    其他的一些 DOM 操作也都很直观,比如可以点击 Add attribute 给选中节点添加属性;Delete element会删除选中节点等等。操作很简单,这里就不一一演示,读者可以自己尝试一下。

    3. CSS调试

    除了对 DOM 的操作,我们还能够方便得对CSS进行调试。不知大家在查看 DOM 的时候有没有关注到界面上还有这么一块区域?

    00c3aec96927a8210ca8aa3a2425c93a.png

    这里就是 CSS 的地盘。我们可以在这里看到选中的 DOM 节点上已添加的样式,可以对里面对值进行修改,或是添加其他 CSS 样式。这里我们给

    标签添加一个 color 样式。

    415d9d760b709f38850ccb43674d48e3.png

    先用 DOM 调试的技巧选中这段文字,再对它添加完 color:red ,这时我们发现页面上的文字变成了红色,与此同时控制台对 DOM 节点树中也对这个节点动态得添加了一个 style 属性,于是我们完成了样式添加。这就是浏览器调试 CSS 样式的便捷之处 —— 简单且直观。甚至于接下来如果我想改变一下文字的颜色,只需要在样式栏里点击一下 color 属性,就可以进行变更了,所见即所得。

    e9c67f7c5c5f29dc7800cbd63e94aa14.png

    我们再注意到样式栏的顶部,有一些 :hover 的图标,点开来看,发现这里可以设置 DOM 的交互状态。假设勾选一个 :focus 复选框,当前选中的 DOM 节点便被模拟了获取焦点的样式特性。

    aab133086a8189e85f853420c323bc01.png

    最后我们再看一下右侧部分,上面有个矩形,它就是我们在 CSS 部分中学习过的“盒子模型”。通过将鼠标在盒子模型上移动,页面上会显示出相对应的 DOM 节点,通过它我们能够更好得了解页面上的布局结构。选中 Computed ,下方显示出一系列的样式,这些样式就是节点经过浏览器计算后渲染在页面上的最终样式,如果某一个节点受到多个地方的样式影响,我们就可以在这里看到它最终的样式属性(与页面上的渲染效果相对应)。

    0bdd23e63e92299e6c15d8ee32dadf4d.png

    4. JS调试

    本节内容将简单介绍如何使用浏览器对 JS 进行调试,由于很多时候我们所说的浏览器调试都是指 JS 调试,因此这部分有很多调试的方法和技巧。具体的调试技巧将在下一章节详细介绍,本节只做一个熟悉的过程。

    JS 的调试主要关注的区域是 Console 和 Sources 模块,前文说过 Console 模块是用于打印运行时抛出的信息,我们可以通过它查看异常信息或主动抛出信息进行调试。 Sources 用于查看资源信息,我们编写和运行的代码都可以在这里找到。我们可以通过在这里设置断点来达到调试的目的。那么接下来我们分别对这两个模块加以认识。

    首先点击进入 Console 模块,会看到一个可输入的控制台界面。在这里我们可以输入一些简单的 JS 指令,按回车键执行。

    bd64027c23c554ee9bb9715f206bf40e.png

    通过简单的尝试可以看到,在这里我们可以能够执行 JS 脚本,并且直观得看到输出结果。这意味着当我们希望看到 JS 代码运行时的数据状态时,我们可以利用这个工具来给我们展现。那么如何在 JS 中使用 Console 控制台呢?其实很简单,只要在你希望查看的数据处加上一行代码

    console.log(希望查看的数据);

    即可在 Console 控制台中查看数据。有了它我们不需要等到 JS 代码执行完毕才能看是否符合预期,在执行过程中我们就可以很方便得查看动态数据并打印记录在控制台中,这对我们的编程有很大的帮助。

    接下来我们来看 Sources 模块。我们可以任意访问一个在线网站,然后打开控制台,点击 Sources 会看到一些代码。这些代码就是当前这个页面所引用的资源,包括 JS 文件,样式文件等等,由于线上运行的代码通常是经过混淆和压缩的,可能难以定位和阅读。我们在文件底部可以看到一个花括号 {} ,点击这个花括号我们能将压缩了的文件格式化成正常的语法缩进。

    450d5038eaee08367b4dfebbb292020d.png

    我们注意到代码的左侧是一列数字,标记着当前的代码处于第几行。这列数字是可以点击的,当点击某个数后,数字被标记成蓝色,此时标记着我们在这一行代码处设置了断点,当程序运行到这段代码处时会停止运行并保留运行现场。我们可以查看当下运行时的数据和方法的执行情况,实际上这就是我们所谓的“断点调试”,下一章节会详细演示。

    这里我们关注到当程序运行到断点处时,页面上会出现一个条形的操作栏显示 paused in debugger ,右边紧跟着两个按钮。第一个三角形的按钮表示 “跳过断点” ,点击它之后脚本会继续往下执行,直到完成运行或是进入到下一个设置的断点。另一个弧形的按钮表示 “单步调试” ,代码会进入到断点的下一行,我们可以查看下一行代码的运行情况。由于此时仍然是断点状态我们可以重复点击 “单步调试” 的按钮达到逐步运行的调试效果。

    a2cc65bfd865d50aa2f7aa83224f63aa.png

    最后再介绍一些 Sources 模块下实用的快捷键,选中控制台的 Sources 之后按下 ctrl + P ,能够搜索当前页面引用的资源。通过它我们可以迅速找到希望调试的 JS 文件。当我们选中某个文件之后,可以使用快捷键 ctrl + F 进行文件内容检索,方便快速定位代码片段和查看变量使用。

    c5ed6159ff9819310dff0b5696afcfa3.png

    5. 网络请求调试

    接下来我们再来看看网络请求的调试。在网页开发中网络请求是的数据的来源渠道,加载一个页面所需的 HTML 、 CSS 、JS 以及图片等资源都是通过网络请求获取的。数据的获取直接影响着页面内容的展示,如此重要的环节浏览器自然也对其做了监控。我们可以通过 Network 模块来对网络请求进行分析和调试。

    任意打开一个在线网址如 https://github.com ,进入控制台并点击 Network ,我们能够看到很多资源请求。

    f06bb00d81df7fb3d5e69d4d572aeaab.png

    工具栏上有很多分类:XHR、JS、CSS、Img、Media、Font、Doc、WS、Manifest等,这些是请求资源的分类。默认是展示全部 All ,点击到其中某一项则能够将请求列表过滤为只有该类型。如点击 JS 则下面的请求列表全部为 JS 资源,点击 XHR 则过滤为向后端发送的异步请求。

    大部分时候我们用到最多的分类是 XHR ,它能够帮助我们调试异步请求。从我们发送请求到我们接收响应数据的过程中,大量细节都记录在控制台中。我们可以点击一个具体的异步请求进行查看

    84ad16847747e57824a4f7e6acb4e1b7.png

    首先看到 Header 这一栏,里面包含了很多信息,这些信息分成4个模块: General 、 Response Headers 、 Request Headers 和 Query String Parameters。

    • General里面记录的是请求的基本信息,包括请求地址(Request URL)、请求类型(Request Method)、请求发送状态(Status Code)等
    • Response Headers是响应头,里面记录了返回数据的类型(Content-Type),浏览器数据的压缩格式(Content-Encoding),服务器的类型(Server),当前时间(Date)等
    • Request Headers是请求头,里面记录了本次请求的客户机支持的数据类型(Accept),缓存控制(Cache-Control),Cookie,访问的主机名(Host),处理完这次请求后的连接方式(Connection)等
    • Query String Parameters是异步请求的参数,如果是 get 请求,则参数为加在url后面的一串查询参数,如果是post请求,则参数为 body 体里的 json 对象。

    然后我们切到 Preview 这里我们看到的内容是异步请求返回的数据,数据格式是 JSON 对象。很多时候我们就是通过查看这里的数据来进行异步请求的数据查看和问题排查。当我们调用了一个后端提供的接口,我们第一时间就该来到这里查看后端返回了怎样的数据,我们才能继续利用这些数据进行后续的操作。

    4547b85010871694672b478c76f9d294.png

    接下来我们再看 Response ,里面的内容是也是异步请求返回数据,不过它跟 preview 的区别在于 preview 中的数据是以 JSON 对象的形式返回的,而在 Response 中是以 JSON 字符串的形式返回。

    cbbd1b11266821c62c51fed05f1b0b8c.png

    最后的 Timing 一栏中,展示了本次异步请求的时间开销。在哪个环节消耗了多少时间在这一栏里都能很明确得展示出来,因此当一个异步请求的等待时间较长时,我们不妨可以到这里来看看是在哪个环节能够进行优化。

    b09034ba686ef9aad448f541bf212c8b.png

    怎么样?一个异步请求的发送过程是不是在浏览器中记录得非常详细了?正是因为有了这样强大的功能,Chrome浏览器才会成为众多前端开发人员钟爱的调试利器。

    总结

    介绍了 Chrome 浏览器的基本调试场景和调试方法,并分别对 DOM 调试,CSS调试,JS调试和网络请求的调试做了展示。当然, Chrome 浏览器的调试功能并不仅限于此,还有很多模块值得大家去探索。浏览器是前端开发用于展示的平台,更是我们提升效率的利器,大家一定要多多尝试,将它充分利用起来。


    欢迎关注
    展开全文
  • 代码如下: # 视图代码 # coding=utf-8 from flask import Flask,request,url_for,render_template,flash from models import User ...求问怎么在打开网页时,修改get请求到post,正确打开post编写的网页。
  • 跨站脚本攻击(Cross Site Scriptings)有两种情况,...XSS攻击在浏览器端触发,大家对其危害认识往往停留在可以窃取cookie、修改页面钓鱼,等等。用一句话来说明该漏洞的危害就是:前端页面能做的事它都能做。挖掘...

    跨站脚本攻击(Cross Site Scriptings)有两种情况,一种是通过外部输入然后直接在浏览器端触发,即反射型XSS;还有一种则是先把利用代码保存在数据库或文件中,当Web程序读取利用代码并输出在页面上时触发漏洞,也就是存储型XSS。XSS攻击在浏览器端触发,大家对其危害认识往往停留在可以窃取cookie、修改页面钓鱼,等等。用一句话来说明该漏洞的危害就是:前端页面能做的事它都能做。

    挖掘XSS漏洞的关键在于寻找没有被过滤的参数,且这些参数传入到输出函数,常用的输出函数列表如下:print、print_r、echo、printf、sprintf、die、var_dump、var_export,所以我们只要寻找带有变量的这些函数即可。另外在代码审计中,XSS漏洞在浏览器环境对利用的影响非常大,所以最重要的还要掌握各种浏览器容错、编码等特性和数据协议。关于XSS漏洞的东西可以再写一本厚厚的书,由于篇幅问题,这些东西就不在这里详细介绍了,推荐阅读邱永华的《XSS跨站脚本攻击剖析与防御》和余弦的《Web前端黑客技术揭秘》。

    XSS漏洞比SQL注入更多,而且在满足业务需求的情况下更加难防御。XSS漏洞经常出现在文章发表、评论回复、留言以及资料设置等地方,特别是在发文章的时候,因为这里大多都是富文本,有各种图片引用、文字格式设置等,所以经常出现对标签事件过滤不严格导致的XSS,同样,评论回复以及留言也是。其次在资料设置的地方,比如用户昵称、签名等,有的应用可能不只一处设置资料的地方,像在注册的地方可以设置、修改资料的地方可以设置,这时候要多留意,不一定所有设置这个资料的地方都过滤严格了。我们在通读代码挖掘的时候可以重点关注这几个地方,这几个地方的XSS也通常都是存储型的。


    反射型XSS

    反射型XSS也就是我们在描述里面说直接通过外部输入然后在浏览器端输出触发的类型,这种类型的漏洞比较容易通过扫描器黑盒直接发现,只需要将尖括号、单双引号等提交到Web服务器,检查返回的HTML页面里面有没有保留原来的特殊字符即可判断。但是白盒审计中,我们只需要寻找带有参数的输出函数,然后根据输出函数对输出内容回溯输入参数,观察有没有经过过滤。

    举例一个反射型XSS漏洞的大致形式,代码如下:

    //以下是QQ私密接口
    

    代码中echo"sig:".$_GET["oauth_signature"]."n";直接将$_GET["oauth_signature"]的值输出到浏览器中,则可以直接用GET方式注入代码。

    存储型XSS

    存储型XSS,顾名思义也就是需要先把利用代码保存在比如数据库或文件中,当Web程序读取利用代码并输出在页面上时执行利用代码,它的原理图流程图如图所示

    b058765a3d9e9b1b9fb890051a704c33.png

    存储型XSS比反射型要容易利用得多,不用考虑绕过浏览器的过滤,另外在隐蔽性上面也要好得多,特别是在社交网络中的存储型XSS蠕虫能造成大面积的传播,影响非常大,曾经在新浪微博和百度贴吧都爆发过大规模的XSS蠕虫。

    同样,要挖掘存储型XSS也是要寻找未过滤的输入点和未过滤的输出函数,这个最终的输出点可能跟输入点完全不在一个业务流上,对于这类可以根据当前代码功能去猜,或者老老实实去追哪里有操作过这个数据,使用表名、字段名去代码里面搜索。


    骑士cms存储型XSS分析

    这里笔者临时找了一个叫骑士cms的程序看了下,在后台申请友情链接的地方存在XSS漏洞,常规的特殊字符(如尖括号)和标签的事件(如onerror等)大多被过滤,漏洞挖掘过程如下。

    安装好骑士cms后,在后台看到一个友情链接管理如图所示

    aad25182c3f54135b5f3ffb2e8352b44.png

    前台有一个申请友情链接,根据经验这个申请友情链接的地方应该是一个payload输入的地方,我们先看看/admin/admin_link.php的代码:

    $act 

    这里是判断访问admin_link.php这个文件的时候有没有act参数,没有就给$act变量赋值为list,即进入到输出友情链接列表的代码:

    $offset

    get_links()函数代码如下:

    function 

    很清楚地看到,这是一个从数据库读取友情链接列表的功能:

    $link 

    后面的代码则是将读取的内容以link/admin_link.htm为模板显示出来。跟进模板页看看,有一个关键的代码片段如下:

    5bb95b8ec4353412a4f55be06fae8dec.png

    其中:

    <

    这段代码是有问题的,这里直接把显示logo的img标签放在span标签的title里面,当鼠标滑过的时候会调用事件执行显示title即执行img标签,这里的利用点是{#$list.link_logo#}可以是HTML实体编码,从而绕过骑士cms的安全检查。目前我们已经找到一个输出点了,输入点也根据当前代码功能猜到是在前台申请链接的地方,利用过程如下,在前台申请友情链接页面http://localhost/74cms/link/add_link.php的logo字段输入

    1 oner&#114;or=ale&#114;t(1) //&#114;=> r    &#12288=>空格

    来构造代码如下:

    <

    执行结果如图所示。

    d49aa556436a4f72e3ebcd76af29e41c.png

    当管理员在后台查看链接时触发漏洞执行代码,如图所示

    977e4136a8db2d76470ff11d5d2d3c19.png

    漏洞防范

    由于XSS漏洞在不同浏览器下有不同的利用方式,而且特别是业务上有需求使用富文本编辑器的时候,防御起来就更加复杂,所以在XSS防御这块应该从多个方面入手,尽量减少XSS漏洞。

    • 特殊字符HTML实体转码

    一般的XSS漏洞都是因为没过滤特殊字符,导致可以通过注入单双引号以及尖括号等字符利用漏洞,比如一个图片标签如下<img src="$_GET['a']"/>,则可以通过输入双引号来闭合第一个单引号利用漏洞,防御这类的XSS漏洞只需要过滤掉相关的特殊字符即可,特殊字符列表如下:

    1)单引号(')

    2)双引号(")

    3)尖括号(<>)

    4)反斜杠()

    5)冒号(:)

    6)and符(&)

    7)#号(#)

    还有两个问题,这些字符应该怎么过滤,什么时候过滤?为了保证数据原始性,最好的过滤方式是在输出和二次调用的时候进行如HTML实体一类的转码,防止脚本注入的问题。

    • 标签事件属性黑白名单

    上面我们提到过滤特殊字符来防止XSS漏洞,实际上即使过滤了也同样可能会被绕过,比如利用跟宽字节注入一样的方式来吃掉反斜杠,再利用标签的事件来执行js代码,面对这样的情况,我们还得加标签事件的黑名单或者白名单,这里更推荐用白名单的方式,实现规则可以直接用正则表达式来匹配,如果匹配到的事件不在白名单列表,就直接拦截掉,而不是替换为空。

    展开全文
  • 学校大作业,我负责的前端部分,正好前段时间学习了vue和elementUI,就来实践一下,部分...在浏览器里渲染成这样可以看到渲染的时候在input外套了个div元素,我加在el-input的ip这个class也是在这个div元素上,input...

    学校大作业,我负责的前端部分,正好前段时间学习了vue和elementUI,就来实践一下,部分代码如下:

    ......

    后来我发现在el-input舔加样式使文字居中但并没有生效

    ......

    ......

    .ip{

    text-align:center

    }

    ......

    62b62c0afea1ac2cfe73c6a308eb7a19.png

    在浏览器里渲染成这样

    85efd1ccb786b2129e77d64f3298f439.png

    可以看到渲染的时候在input外套了个div元素,我加在el-input的ip这个class也是在这个div元素上,input元素则是el-input__inner这个class

    div为父组件,input为子组件,vue里可以看到

    而以上可以看到我们的原本加在el-input的名为ip的class渲染到了父组件div上,这也就是为什么添加样式无法生效的原因

    所以修改代码如下(可以将/deep/换成>>>)

    ......

    ......

    .ip /deep/ .el-input__inner{

    }

    ......

    重新运行样式就生效了

    20210110152317298.png

    展开全文
  • 代码如下: 前端html: ``` <!DOCTYPE html> <title></title> <!--<script type="text/javascript" src="jquery.js"></script>--> ...
  • 作者:valentinogagliardi译者:前端小智来源:github这几天自己的...作为一种在浏览器中运行的脚本语言,它对于处理web页面非常有用。在本中,我们将看到我们有哪些方法来交互和修改HTML文档及其元素。但首先让我...

    作者:valentinogagliardi
    译者:前端小智
    来源:github

    这几天自己的公众号无套路送现金 200+,参与方式如下 

    OKR 与 KPI 的区别(文中无套路送现金 200+)

    文档对象模型(DOM)

    JS 有很多地方让咱们吐槽,但没那么糟糕。作为一种在浏览器中运行的脚本语言,它对于处理web页面非常有用。在本中,我们将看到我们有哪些方法来交互和修改HTML文档及其元素。但首先让我们来揭开文档对象模型的神秘面纱。

    文档对象模型是一个基本概念,它是咱们在浏览器中所做的一切工作的基础。但那到底是什么? 当咱们访问一个 web 页面时,浏览器会指出如何解释每个 HTML 元素。这样它就创建了 HTML 文档的虚拟表示,并保存在内存中。HTML 页面被转换成树状结构,每个 HTML 元素都变成一个叶子,连接到父分支。考虑这个简单的HTML 页面:

    html>

    当浏览器扫描上面的 HTML 时,它创建了一个文档对象模型,它是HTML结构的镜像。在这个结构的顶部有一个 document 也称为根元素,它包含另一个元素:htmlhtml 元素包含一个 headhead 又有一个 title。然后是含有 h1body。每个 HTML 元素由特定类型(也称为接口)表示,并且可能包含文本或其他嵌套元素

    document (HTMLDocument)
      |
      |
     --> html (HTMLHtmlElement)
              |  
              |
     --> head (HtmlHeadElement)
              |       |
              |       | --> title (HtmlTitleElement)
              |                | --> text: "A super simple title!"
              |
              |
     --> body (HtmlBodyElement)
              |       |
              |       | --> h1 (HTMLHeadingElement)
              |              | --> text: "A super simple web page!"

    每个 HTML 元素都是从 Element 派生而来的,但是它们中的很大一部分是进一步专门化的。咱们可以检查原型,以查明元素属于什么“种类”。例如,h1 元素是 HTMLHeadingElement

    document.quertSelector(

    HTMLHeadingElement 又是 HTMLElement 的“后代”

    document.

    Element 是一个通用性非常强的基类,所有 Document 对象下的对象都继承自它。这个接口描述了所有相同种类的元素所普遍具有的方法和属性。一些接口继承自 Element 并且增加了一些额外功能的接口描述了具体的行为。例如, HTMLElement 接口是所有 HTML 元素的基本接口,而 SVGElement 接口是所有 SVG 元素的基础。大多数功能是在这个类的更深层级(hierarchy)的接口中被进一步制定的。

    在这一点上(特别是对于初学者),documentwindow 之间可能有些混淆。window 指的是浏览器,而 document 指的是当前的 HTML 页面。window 是一个全局对象,可以从浏览器中运行的任何 JS 代码直接访问它。它不是 JS 的“原生”对象,而是由浏览器本身公开的。window 有很多属性和方法,如下所示:

    window.alert(

    由于这些属性是全局属性,因此也可以省略 window

    'Hello world'); 

    你应该已经熟悉其中的一些方法,例如 setTimeout()window.navigator,它可以获取当前浏览器使用的语言:

    if (

    要了解更多 window 上的方法,请查看MDN文档。在下一节中,咱们深入地研究一下 DOM

    节点、元素 和DOM 操作

    document 接口有许多实用的方法,比如 querySelector(),它是用于选择当前 HTML 页面内的任何 HTML 元素:

    document.

    window 表示当前窗口的浏览器,下面的指令与上面的相同:

    window.

    不管怎样,下面的语法更常见,在下一节中咱们将大量使用这种形式:

    document.methodName();

    除了 querySelector() 用于选择 HTML 元素之外,还有很多更有用的方法

    // 返回单个元素

    咱们不仅可以选 择HTML 元素,还可以交互和修改它们的内部状态。例如,希望读取或更改给定元素的内部内容:

    // Read or write

    DOM 中的每个 HTML 元素也是一个“节点”,实际上咱们可以像这样检查节点类型:

    document.

    上述结果返回 1,表示是 Element 类型的节点的标识符。咱们还可以检查节点名:

    document.

    这里,节点名以大写形式返回。通常我们处理 DOM 中的四种类型的节点

    • document: 根节点(nodeType 9)

    • 类型为Element的节点:实际的HTML标签(nodeType 1),例如

    • 类型属性的节点:每个HTML元素的属性(属性)

    Text 类型的节点:元素的实际文本内容(nodeType 3)

    由于元素是节点,节点可以有属性(properties )(也称为attributes),咱们可以检查和操作这些属性:

    // 返回 true 或者 false

    前面我们说过 DOM 是一个类似于树的结构。这种特性也反映在 HTML 元素上。每个元素都可能有父元素和子元素,我们可以通过检查元素的某些属性来查看它们:

    // 返回一个 HTMLCollection

    了解了如何选择和查询 HTML 元素。那创建元素又是怎么样?为了创建 Element 类型的新节点,原生 DOM API 提供了 createElement 方法:

    var heading = 

    使用 createTextNode 创建文本节点:

    var text = 

    通过将 text 附加到新的 HTML 元素中,可以将这两个节点组合在一起。最后,还可以将heading元素附加到根文档中:

    var heading = 

    还可以使用 remove() 方法从 DOM 中删除节点。在元素上调用方法,该节点将从页面中消失:

    document.

    这些是咱们开始在浏览器中使用 JS 操作 DOM 所需要知道的全部内容。在下一节中,咱们将灵活地使用 DOM,但首先要绕个弯,因为咱们还需要讨论“DOM事件”

    DOM 和事件

    DOM 元素是很智能的。它们不仅可以包含文本和其他 HTML 元素,还可以“发出”和响应“事件”。浏览任何网站并打开浏览器控制台。使用以下命令选择一个元素:

    document.

    看看这个属性

    document.

    它是什么类型:

    typeof 

    "object"! 为什么它被称为“onclick”? 凭一点直觉我们可以想象它是元素上的某种神奇属性,能够对点击做出反应? 完全正确。

    如果你感兴趣,可以查看任何 HTML 元素的原型链。会发现每个元素也是一个 Element,而元素又是一个节点,而节点又是一个EventTarget。可以使用 instanceof  来验证这一点。

    document.querySelector(

    我很乐意称 EventTarget 为所有 HTML 元素之父,但在JS中没有真正的继承,它更像是任何 HTML 元素都可以看到另一个连接对象的属性。因此,任何 HTML 元素都具有与 EventTarget 相同的特性:发布事件的能力

    但事件到底是什么呢?以 HTML 按钮为例。如果你点击它,那就是一个事件。有了这个.onclick对象,咱们可以注册事件,只要元素被点击,它就会运行。传递给事件的函数称为“事件监听器”“事件句柄”

    事件和监听

    在 DOM 中注册事件监听器有三种方法。第一种形式比较陈旧,应该避免,因为它耦合了逻辑操作和标签

    第二个选项依赖于以事件命名的对象。例如,咱们可以通过在对象.onclick上注册一个函数来监听click事件:

    document.querySelector(

    此语法更加简洁,是内联处理程序的不错替代方案。还有另一种基于addEventListener的现代形式:

    document.querySelector(

    就我个人而言,我更喜欢这种形式,但如果想争取最大限度的浏览器兼容性,请使用 .on 方式。现在咱们已经有了一 个 HTML 元素和一个事件监听器,接着进一步研究一下 DOM 事件。

    事件对象、事件默认值和事件冒泡

    作为事件处理程序传递的每个函数默认接收一个名为“event”的对象

    var button = 

    它可以直接在函数体中使用,但是在我的代码中,我更喜欢将它显式地声明为参数:

    function handleClick(event{

    事件对象是“必须要有的”,因为咱们可以通过调用事件上的一些方法来控制事件的行为。事件实际上有特定的特征,尤其是“默认”“冒泡”。考虑一 个HTML 链接。使用以下标签创建一个名为click-event.html的新HTML文件:

    html>

    在浏览器中运行该文件并尝试单击链接。它将跳转到一个404的界面。链接上单击事件的默认行为是转到href属性中指定的实际页面。但如果我告诉你有办法阻止默认值呢?输入preventDefault(),该方法可用于事件对象。使用以下代码创建一个名为click-event.js的新文件:

    var button = 

    在浏览器中刷新页面并尝试现在单击链接:它不会跳转了。因为咱们阻止了浏览器的“事件默认” 链接不是默认操作的惟一HTML 元素,表单具有相同的特性。

    当 HTML 元素嵌套在另一个元素中时,还会出现另一个有趣的特性。考虑以下 HTML

    html>

    和下面的 JS 代码:

    // nested-events.js

    有两个事件监听器,一个用于外部 div,一个用于内部 div。准确地点击内部div,你会看到:

    a87b738465647ff72853add787d414d7.png

    两个事件对象被打印。这就是事件冒泡在起作用。它看起来像是浏览器行为中的一个 bug,使用 stopPropagation() 方法可以禁用,这也是在事件对象上调用的

    //

    尽管看起来实现效果很差,但在注册过多事件监听器确实对性能不利的情况下,冒泡还是会让人眼前一亮。考虑以下示例:

    html>

    如果要兼听列表的点击事件,需要在列表中注册多少事件监听器?答案是:一个。只需要一个在ul上注册的侦听器就可以截获任何li上的所有单击:

    // event-bubbling.js

    可以看到,事件冒泡是提高性能的一种实用方法。实际上,对浏览器来说,注册事件监听器是一项昂贵的操作,而且在出现大量元素列表的情况下,可能会导致性能损失。

    用 JS 生成表格

    现在咱们开始编码。给定一个对象数组,希望动态生成一个HTML 表格。HTML 表格由

    元素表示。每个表也可以有一个头部,由 元素表示。头部可以有一个或多个行 ,每个行都有一个单元格,由一个 元 素表示。如下所示:
    <table>

    不止这样,大多数情况下,每个表都有一个主体,由 定义,而 又包含一组行。每一行都可以有包含实际数据的单元格。表单元格由定义。完整如下所示:

    <table>

    现在的任务是从 JS 对象数组开始生成表格。首先,创建一个名为build-table.html的新文件,内容如下:

    html>

    在相同的文件夹中创建另一个名为build-table.js的文件,并使用以下数组开始:

    "use strict";

    考虑这个表格。首先,咱们需要一个

    document.createElement(

    这没有错,但是仔细查看MDN的表格文档会发现一个有趣的细节。

    是一个 HTMLTableElement,它还包含有趣方法。其中最有用的是HTMLTableElement.createTHead(),它可以帮助创建咱们需要的

    首先,编写一个生成 thead 标签的函数 generateTableHead

    function generateTableHead(table{

    该函数接受一个选择器并在给定的表上创建一个 :

    function generateTableHead(table{

    在浏览器中打开 build-table.html:什么都没有.但是,如果打开浏览器控制台,可以看到一个新的 附加到表。

    接着填充 header 内容。首先要在里面创建一行。还有另一个方法可以提供帮助:HTMLTableElement.insertRow()。有了这个,咱们就可以扩展方法了:

    function generateTableHead (table{

    此时,我们可以生成我们的行。通过查看源数组,可以看到其中的任何对象都有咱们需要信息:

    var mountains = [

    这意味着咱们可以将另一个参数传递给我们的函数:一个遍历以生成标题单元格的数组:

    function generateTableHead(table, data{

    不幸的是,没有创建单元格的原生方法,因此求助于document.createElement("th")。同样值得注意的是,document.createTextNode(data[i])用于创建文本节点,appendChild()用于向每个标记添加新元素。

    当以这种方式创建和操作元素时,我们称之为“命令式” DOM 操作。现代前端库通过支持“声明式”方法来解决这个问题。我们可以声明需要哪些 HTML 元素,而不是一步一步地命令浏览器,其余的由库处理。

    回到我们的代码,可以像下面这样使用第一个函数

    var table = 

    现在我们可以进一步生成实际表的数据。下一个函数将实现一个类似于generateTableHead的逻辑,但这一次咱们需要两个嵌套的for循环。在最内层的循环中,使用另一种原生方法来创建一系列td。方法是HTMLTableRowElement.insertCell()。在前面创建的文件中添加另一个名为generateTable的函数

    function generateTable(table, data{

    调用上面的函数,将 HTML表 和对象数组作为参数传递:

    table, mountains);

    咱们深入研究一下 generateTable 的逻辑。参数 data 是一个与 mountains 相对应的数组。最外层的 for 循环遍历数组并为每个元素创建一行:

    function generateTable(table, data{

    最内层的循环遍历任何给定对象的每个键,并为每个对象创建一个包含键值的文本节点

    function generateTable(table, data{

    最终代码:

    var mountains = [

    其中调用:

    var table = 

    执行结果:

    b5feb9cdcfb439df18589b1357ddcd1a.png

    当然,咱们的方法还可以该进,下个章节将介绍。

    总结

    DOM 是 web 浏览器保存在内存中的 web 页面的虚拟副本。DOM 操作是指从 DOM 中创建、修改和删除 HTML 元素的操作。在过去,咱们常常依赖 jQuery 来完成更简单的任务,但现在原生 API 已经足够成熟,可以让 jQuery 过时了。另一方面,jQuery 不会很快消失,但是每个 JS 开发人员都必须知道如何使用原生 API 操作 DOM。

    这样做的理由有很多,额外的库增加了加载时间和 JS 应用程序的大小。更不用说 DOM 操作在面试中经常出现。

    DOM 中每个可用的 HTML 元素都有一个接口,该接口公开一定数量的属性和方法。当你对使用何种方法有疑问时,参考MDN文档。操作 DOM 最常用的方法是 document.createElement() 用于创建新的 HTML 元素,document.createTextNode() 用于在 DOM 中创建文本节点。最后但同样重要的是 .appendchild(),用于将新的 HTML 元素或文本节点附加到现有元素。

    HTML 元素还能够发出事件,也称为DOM事件。值得注意的事件为“click”“submit”“drag”“drop”等等。DOM 事件有一些特殊的行为,比如“默认”和冒泡。

    JS 开发人员可以利用这些属性,特别是对于事件冒泡,这些属性对于加速 DOM 中的事件处理非常有用。虽然对原生 API 有很好的了解是件好事,但是现代前端库提供了不容置疑的好处。用 AngularReactVue 来构建一个大型的JS应用程序确实是可行的。

    代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

    原文:https://github.com/valentinogagliardi/Little-JavaScript-Book/blob/v1.0.0/manuscript/chapter8.md

    交流

    821fd98739eea4a025602b17d81d47e7.png

    延伸阅读

    【JS 口袋书】第 8 章:以更细的角度来看 JS 中的 this

    【JS 口袋书】第 7 章:JS 中的类型转换与比较

    【JS 口袋书】第 6 章:JS 对象生命周期的秘密

    【JS 口袋书】第 5 章:JS 中的闭包与模块

    展开全文
  • 但是这就存在两个问题 pc浏览器模拟手机可能造成调试不准 用手机直接调试 又多一步刷新那怎么能达到pc端修改代码 手机上直接看到修改结果这样的所见即所得的效果呢 chrome做到了 二.功能 我们先看下最终想...
  • <a href="https://github.com/gotwarlost/istanbul">istanbul等等为代码在语法级分支上打点,运行了打点后的代码,根据运行结束后收集到的信息和打点时的信息来统计出当前测试用例的对源码的覆盖情况。 ...
  • 不进行覆盖更新 [除非代码有错误进行修改],这样避免了 <em>2019</em> 年小明同学望着前两章和 <em>Github</em> 最终版本代码发呆 ( <em>release</em> 也不是特别友好) 我们把上文的 renderer/src 改成比较...
  • 以往只能运行在浏览器中的 JavaScript 也可以运行在服务器上,前端工程师可以用自己最熟悉的语言来写服务端的代码。于是前端工程师开始使用 Node.js 做全栈开发,开始由前端工程师向全栈工程师的方向...
  • Web浏览器中,全局执行环境是window对象,这也意味着所有的全局变量或者方法都是window对象的属性或方法。当一个函数被调用的时候都会创建自己的执行环境,而这个函数中所写的代码就开始进入...
  • 二是前端代码在用户端运行时增量安装。 <p>html、css和js的配合才能保证webapp的运行,增量安装是按需加载的需要。开发完成后输出三种以上不同格式的静态资源,静态资源之间有可能存在互相依赖关系&#...
  • 一:背景通常情况我们调试移动端页面最常用的...用手机直接调试 又多一步刷新那怎么能达到pc端修改代码 手机上直接看到修改结果这样的所见即所得的效果呢 chrome做到了 二.功能 我们先看下最终想要达到的效...
  • vscode怎么预览网页?VSCode设置网页代码实时预览一、设置描述1.VSCode作为一款很不错的开发软件,...2.其实我们可以VSCode中配置一个网页服务器,修改代码之后只需要保存代码浏览器就可以实时预览二、操作步骤1...
  • 但是我使用的过程中觉得这个插件并不怎么好用。 <h4>4.<a href="https://github.com/jonschlinkert/sublime-markdown-extended">Markdown Extended</a></h4> 这个插件主要使 Sublime 对 markdown 语法的高亮支持。...
  • 开发web前端的时候,发现IE8 不支持 String.trim() 函数而这个函数被其他浏览器Chrome,Firefox,甚至IE9都支持。 并且我们的代码里面大量应用,这时候怎么改? 方法有很多种,自己实现一个trim方法,或者用...
  • 阿里面试题</li><li><a href="https://juejin.im/post/5a64541bf265da3e2d338862">16年毕业的前端er杭州求职ing</a>,同样也是阿里面试题</li><li>「中高级前端面试」JavaScript手写代码无敌秘籍</a>,...
  • 即,在M645上面做一个功能,电脑网线连接上M645以后在浏览器里面输入M645的ip地址就可以打开一个配置页面,在这个页面里面可以配置和修改M645的IP地址、网关等参数。 首先,HTML文件是有了,这里要明白一个事情:...
  • 在命令行下运行node DOClever的根目录/Server/bin/www(如果是windows环境下,请修改目录分隔符),第一次启动,会出现命令行提示符,按照提示符输入即可完成相关的配置,等到DOClever启动成功后, 在浏览器里输入...
  • HTML

    2020-06-08 22:45:04
    回顾源码学习HTML的五天知识 第一天目标 ...2.学会当前几个主流的标签 ... ...超文本标记语言---官方的解释 ...3.怎么区分静态页面和动态页面------(面试题...动态页面:我们不去改变前端代码,而是通过后台数据的改变来让页
  • 安装后让开发者更加有效率的 Github 页面代码区域跳转(vim ctags) 大部分项目包含很多文件模块和第三方依赖,它们通过特定的语法被引用和导入(如 include, require, import 等)...
  • js的调试

    2020-05-21 00:07:36
    作为一个程序员,不管你使用的编程语言是什么,也不管你开发前端还是开发后端,写的代码不可能是一气呵成并且一点错误也没有的,一般都要经过反复的修改与测试才能写出相对来说更健壮的程序代码,为了能让自己更...
  • 通过RobotFramework实现并完成了项目的UI自动化测试脚本,但是笔记希望是前端开发工程师一旦修改代码就自动执行UI自动化脚本,可以做到随时检测开发人员对项目的影响,刚好和运维人员商量可以拿到开发合完代码产生的...
  • 浏览器为单位,比如IE,搜狗等等,都算一个单独的会话 修改3.5项目 控制器代码 前端显示 startup.cs中配置并启用Session 运行 跳转 第二部分:Cache讲解 应用程序级的,应用程序运行期间...
  • 浏览器为单位,比如IE,搜狗等等,都算一个单独的会话 修改3.5项目 控制器代码 前端显示 startup.cs中配置并启用Session 运行 跳转 第二部分:Cache讲解 应用程序级的,应用程序运行期间...
  • CSRF绕过后端Referer校验分正常情况和不正常的情况,我们这里主要讨论开发写校验referer程序时,不正常的情况下怎么进行绕过。 正常情况 正常的情况指服务器端校验Referer的代码没毛病,那么意味着前端是无法绕过...

空空如也

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

在浏览器怎么修改前端代码