做了一些研究,应该算是理清了问题。

首先,我们在这里常说的「属性」(attributes)其实分为两种:内容属性(content attributes)以及 IDL 属性(IDL attributes)。

内容属性指那些在 HTML 中定义的属性,例如在下面这个 HTML 片段中:

<p class="lede" style="font-size: 1.2em;">

定义了 2 个内容属性 class 与 style。
IDL 指接口描述语言(Interface definition language),而描述 HTML 的接口所用的描述语言为 Web IDL(http://www.w3.org/TR/WebIDL/)。脚本语言(如 JavaScript)可以通过 HTML 定义的这些接口来进行诸如 DOM 操作的各种处理。(举个例子,HTML 的 Element 接口描述:http://dom.spec.whatwg.org/#interface-element)。而其中的某些 IDL 属性就是用来对应内容属性的。

HTML 规范中有如下描述(http://dev.w3.org/html5/spec/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes):

Some
IDL attributes are defined to reflect a particular content attribute.
This means that on getting, the IDL attribute returns the current
value of the content attribute, and on setting, the IDL attribute
changes the value of the content attribute to the given value.
In
general, on getting, if the content attribute is not present, the IDL
attribute must act as if the content attribute's value is the empty
string; and on setting, if the content attribute is not present, it
must first be added.

对于 style 属性,又有这样的描述(http://dev.w3.org/html5/spec/global-attributes.html#the-style-attribute):

The
style IDL attribute must return a CSSStyleDeclaration whose value
represents the declarations specified in the attribute. (If the
attribute is absent, the object represents an empty declaration.)
Mutating the CSSStyleDeclaration object must create a style attribute on
the element (if there isn't one already) and then change its value to
be a value representing the serialized form of the CSSStyleDeclaration
object. The same object must be returned each time.

从上面的两段内容
可以看出,浏览器在实现 HTML 的接口规范时,会区分处理内容属性和 IDL 属性,但对在读取、修改 IDL 属性时会对内容属性作同步处理(对于
style 属性,两者具体格式不同,但内容是同质的。比如 div.style.fontSize = '36px' 相当于把内容属性 style
的值设为 "font-size: 36px;")。

看了上面这一堆,我们应该可以猜测题主所述的这个问题的产生过程:
可能是由于对 "style" 这个内容属性做了一定的优化,进行了延迟创建(即在第一次运行 setAttribute('style', value)
或 getAttribute('style') 时才创建)。而最开始的 HTML 代码没有 style 属性,所以 Chrome
开始时没有创建新的内容属性。而在通过 IDL 属性修改 div.style.fontSize 后,并没有导致 Chrome 创建一个新的内容属性
"style"。然后在 removeAttribute('style') 时,因为没有找到此属性所以也没有对 IDL
属性的变化进行修改。从表现来看,最终渲染的属性值是与 IDL 属性值保持一致的,所以无法通过 removeAttribute('style')
来去掉元素的样式。

也就是说,只要我们人工保证先创建了 style 内容属性,就能够解决这个问题。所以你可以试一下以下的各个方法:

  1. 在 HTML 内容中先随便加入一点 style 比如:

    <div style="margin: 0;">测试</div>

    需要注意的是,用这种方法,在第一次删除样式后,内容属性被删除了,之后再删除又不会再生效;

  2. 在每次删除样式之前任意时间先运行一下 div.getAttribute('style');
    在这种情况下,可以发现,如果 getAttribute('style') 之后才首次修改 IDL 属性,删除也无法完成,即在 btn[0].onclick 中修改为下面代码时,也不会导致内容属性被创建:

    div.getAttribute('style');
    div.style.fontSize = '36px';

    于是我们可以进一步认为,所谓的「延迟创建」其实不是在第一次getAttribute('style') 或 setAttribute('style', value) 时总会被创建。如果在此之前对应的 IDL 属性为空,内容属性亦不会被创建;

  3. 通过 div.setAttribute('style', 'font-size: 36px;') 来设置文字大小。

所以,removeAttribute('style') 生效的前提是,在其运行之前,已经

  1. 用 IDL 属性添加了样式并调用了 getAttribute('style') 与 setAttribute('style', value) 其中之一;
  2. 或者直接用 setAttribute('style', value) 来添加样式。

至于为什么打开开发者工具就能够生效,我想也比较明显了:因为开发者工具在渲染内容的过程中,在已经通过 IDL 属性修改样式后调用了 getAttribute('style'),导致这个内容属性被创建,于是也就能被正常删除了。

我测试了一下,这个问题对于 Windows 和 Mac 下的 Chrome 与 Safari 均成立,所以应该是 WebKit 的一个 bug。

webkit内核的浏览器为什么removeAttribute('style')会失效?的更多相关文章

  1. 给Webkit内核的浏览器控件增加互交功能

    转载请说明出处,谢谢~~ 昨天封装了基于webkit的wke浏览器内核,做成了duilib的浏览器控件,实现了浏览功能,但是单单的浏览功能还不满足需求,在我的仿酷狗项目中乐库的功能需要与浏览器互交. ...

  2. webkit内核的浏览器常见7种分别是..

    Google Chrome Safari 遨游浏览器 3.x 搜狗浏览器 阿里云浏览器 QQ浏览器 360浏览器 ...

  3. 八大Webkit内核浏览器

    列举出时下最流行的Webkit内核浏览器,所以我们并不会做出评测和对比.PS:本文列举的浏览器有一部分为IE+Webkit双核浏览器,如果您对其他IE内核浏览器很感兴趣<抛弃数据!用体验和感觉告 ...

  4. 拥有webkit内核浏览器的平台

    1-拥有webkit内核的浏览器: IOS safari Android 的浏览器 Google chrome 猎豹浏览器 百度浏览器 Opera 以上可知手机的浏览器均为webkit内核 2-拥有其 ...

  5. 专为webkit内核而生的javascript库mango正式发布

    专为webkit内核而生的javascript库mango正式发布 Mango(芒果) javascript库 求fork https://github.com/willian12345/mango ...

  6. Webkit内核探究【1】——Webkit简介

    出处:http://www.cnblogs.com/jyli/archive/2010/01/31/1660355.html作者:李嘉昱 研究Webkit内核已经有一段时间了,在这期间我花了很多时间去 ...

  7. CSS3自定义滚动条样式-webkit内核

    自定义滚动条实现 此部分针对webkit内核的浏览器,使用伪类来改变滚动条的默认样式,详情如下: 滚动条组成部分 1. ::-webkit-scrollbar 滚动条整体部分 2. ::-webkit ...

  8. 【前端】webkit内核浏览器DIV滚动条样式修改和设置

    webkit内核浏览器DIV滚动条样式修改和设置 引言: 最近在做自己的小项目,为了设计出好看的页面费劲了心思,大到页面的整体布局,小到DIV的滚动条都不放过,以下是我通过查阅资料总结的webkit内 ...

  9. 【转】.NET多种WebKit内核/Blink内核浏览器初步测评报告

    第1篇:.NET多种WebKit内核/Blink内核浏览器初步测评报告 本文转自“吾乐吧软件站”,原文链接:http://www.wuleba.com/?p=23590 报告研究时间:2013-10- ...

随机推荐

  1. SpringBoot.资料

    1.du 搜 "springboot 视频" 2.SpringBoot视频教程_哔哩哔哩 (゜-゜)つロ 干杯_-bilibili.html(https://www.bilibil ...

  2. 前端框架MVVM是什么(整理)

    前端框架MVVM是什么(整理) 一.总结 一句话总结:vm层(视图模型层)通过接口从后台m层(model层)请求数据,vm层继而和v(view层)实现数据的双向绑定. 1.我大前端应该不应该做复杂的数 ...

  3. ultraedit开发使用技巧

    抛开Mybatis和Hibernate这些dao框架,如果维护老项目时或者不得不用sql拼接时,一个几百行的sql光是去掉navicat中查询的注释或者在sql前后加上双引号就已经很费劲,影响开发效率 ...

  4. xargs -i的用法

    find ... | 后面跟文件,就需要用到xargs,其中-i加{}就能替代管道符之前的文件(标准输出的内容) 在/tmp下创建6个文件,1.txt,2.txt,3.txt,4.txt,5.txt, ...

  5. C++常考面试题

    1 new/delete 与 malloc/free的区别 运算符是语言自身的特性,有固定的语义,编译器知道意味着什么,由编译器解释语义,生成相应的代码. 库函数是依赖于库的,一定程度上独立于语言的. ...

  6. .NET连接MongoDB数据库实例教程

    这则小窍门将讲述如何开发一个.NET应用来连接Mongo数据库并执行多种操作.同时还稍微涉及了Mongo数据库和多种命令. 使用代码 让我们从Mongo数据库的一些细节和基本命令开始,并最终介绍如何创 ...

  7. android 笔记一

    1.Fragment创建extents FragmentView rootView = inflater.inflate(R.layout.fragment_main, container, fals ...

  8. Eclipse 项目有红惊叹号

    Eclipse 项目有红感叹号原因:显示红色感叹号是因为jar包的路径不对 解决:在项目上右击Build Path -> Configure Build Paht...(或Propertise- ...

  9. java静态代理和动态代理(一)

    代理Proxy: Proxy代理模式是一种结构型设计模式,主要解决的问题是:在直接访问对象时带来的问题. 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为 ...

  10. [UIApplication sharedApplication].idleTimerDisabled=YES;不自动锁屏 [UIApplication sharedApplication].idleTimerDisabled=NO;自动锁屏

    [UIApplication sharedApplication].idleTimerDisabled=YES;不自动锁屏 [UIApplication sharedApplication].idle ...