aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/api/cssstylesheet/insertrule/index.html
blob: 4b89a1584ec4d87d49404bf07525f6494b399741 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
---
title: CSSStyleSheet.insertRule()
slug: Web/API/CSSStyleSheet/insertRule
tags:
  - API
  - CSSOM
  - CSSStyleSheet
translation_of: Web/API/CSSStyleSheet/insertRule
---
<div>
<p>{{ APIRef("CSSOM") }}</p>
</div>

<p><strong><code>CSSStyleSheet.insertRule()</code> </strong>方法用来给当前样式表插入新的样式规则(<a href="/zh-CN/docs/Web/API/CSSRule">CSS rule</a>),并且包含一些<a href="/zh-CN/docs/Web/API/CSSStyleSheet/insertRule$edit#Restrictions">限制</a></p>

<div class="blockIndicator note">
<p><strong>注意:</strong>尽管 <code>insertRule()</code> 是 {{domxref("CSSStyleSheet")}} 的一个方法,但它实际插入的地方是 <code>{{domxref("CSSStyleSheet", "", "", "1")}}.cssRules</code> 的内部 {{domxref("CSSRuleList")}}</p>
</div>

<h2 id="Syntax" name="Syntax">语法</h2>

<pre class="syntaxbox"><var>stylesheet</var>.insertRule(<var>rule [</var>, <var>index]</var>)</pre>

<h3 id="Parameters" name="Parameters">参数</h3>

<dl>
 <dt><code>rule</code></dt>
 <dd>
 <p>一个包含了将要插入的规则的 {{domxref("DOMString")}}。规则字符串必须包含的内容取决于它的类型:</p>

 <ul>
  <li><strong><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Syntax#CSS_statements">rule-sets</a> 类型</strong>(普通带有选择器的规则)<strong></strong>需要<a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors">选择器</a>和样式声明;</li>
  <li><strong><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule">at-rules</a> 类型</strong>(以 <code>@</code> 开头的规则,如 <code>@import, @media</code> 等)<strong></strong>需要 at-identifier 和规则内容。</li>
 </ul>
 </dd>
 <dt><code>index</code> {{optional_inline}}</dt>
 <dd>一个小于或等于 <code>stylesheet.cssRules.length</code> 的正整数,表示新插入的规则在<code>{{domxref("CSSStyleSheet", "", "", "1")}}.cssRules</code> 中的位置。默认值是 <code>0</code>。(在过去的实现中,这个参数是必需的,详情参见<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/CSSStyleSheet/insertRule$edit#Browser_compatibility">浏览器兼容性</a>。)</dd>
</dl>

<h3 id="返回值">返回值</h3>

<p>新插入的规则在当前样式表规则列表中的索引。</p>

<h3 id="限制">限制</h3>

<p>CSS 中存在一些直观和不是太直观能感受到的限制规则影响着某些样式规则能否被插入。违反这些规则可能会导致一些 DOM 异常({{domxref("DOMException")}})。</p>

<ul>
 <li>如果 <code>index</code> &gt; <code>{{domxref("CSSRuleList", "", "", "1")}}.length</code>,该方法会中止并返回一个 <code>IndexSizeError</code> 错误;</li>
 <li>如果 <code>rule</code> 由于一些 CSS 约束而不能被插入到 <code>index</code> <code>0</code>,该方法会中止并返回一个 <code>HierarchyRequestError</code> 错误;</li>
 <li>如果 <code>rule</code> 参数中包含超过一条样式规则,该方法会中止并返回一个 <code>SyntaxError</code></li>
 <li>如果尝试在一条普通规则后插入一条 {{cssxref("@import")}} 这种类型的规则,该方法会中止并返回一个 <code>HierarchyRequestError</code> 错误;</li>
 <li>如果 <code>rule</code> 是 {{cssxref("@namespace")}} 并且规则列表中有另外的 <code>@import</code> 和/或 <code>@namespace</code> 规则,该方法中止并返回一个 <code>InvalidStateError</code> 错误;</li>
</ul>

<h2 id="Example" name="Example">示例</h2>

<h3 id="在样式表顶部插入新的规则">在样式表顶部插入新的规则</h3>

<p>下面的代码片段将在样式表 <code>myStyle</code> 的顶部插入一条新规则:</p>

<pre class="brush: js"> myStyle.insertRule("#blanc { color: white }", 0);
</pre>

<h3 id="Notes" name="Notes">实现一个添加样式表规则的函数</h3>

<pre class="brush: js">/**
 * 在文档中添加一条样式表规则(这可能是动态改变 class 名的更好的实现方法,
 * 使得 style 样式内容可以保留在真正的样式表中,以斌面添加额外的元素到 DOM 中)。
 * 注意这里有必要声明一个数组,因为 ECMAScript 不保证对象按预想的顺序遍历,
 * 并且 CSS 也是依赖于顺序的。
 * 类型为数组的参数 decls 接受一个 JSON 编译的数组。
 * @example
addStylesheetRules([
  ['h2', // 还接受第二个参数作为数组中的数组
    ['color', 'red'],
    ['background-color', 'green', true] // 'true' for !important rules
  ],
  ['.myClass',
    ['background-color', 'yellow']
  ]
]);
 */
function addStylesheetRules (decls) {
    var style = document.createElement('style');
    document.getElementsByTagName('head')[0].appendChild(style);
    if (!window.createPopup) { /* For Safari */
       style.appendChild(document.createTextNode(''));
    }
    var s = document.styleSheets[document.styleSheets.length - 1];
    for (var i=0, dl = decls.length; i &lt; dl; i++) {
        var j = 1, decl = decls[i], selector = decl[0], rulesStr = '';
        if (Object.prototype.toString.call(decl[1][0]) === '[object Array]') {
            decl = decl[1];
            j = 0;
        }
        for (var rl=decl.length; j &lt; rl; j++) {
            var rule = decl[j];
            rulesStr += rule[0] + ':' + rule[1] + (rule[2] ? ' !important' : '') + ';\n';
        }

        if (s.insertRule) {
            s.insertRule(selector + '{' + rulesStr + '}', s.cssRules.length);
        }
        else { /* IE */
            s.addRule(selector, rulesStr, -1);
        }
    }
}</pre>

<h2 id="Notes" name="Notes">兼容补丁</h2>

<p>以下补丁将会在 IE 5-8 中纠正提供给 <code>insertRule()</code> 的参数,使其标准化。to standardize them in Internet Explorer 5–8. 它通过一个函数对 <code>insertRule()</code> 进行补充,使得在参数传递给原生的 <code>insertRule()</code> 函数之前将其中的选择器从规则中分离出来。</p>

<pre><code>(function(Sheet_proto){
  var originalInsertRule = Sheet_proto.insertRule;

  if (originalInsertRule.length === 2){ // 2 个托管参数: (selector, rules)
    Sheet_proto.insertRule = function(selectorAndRule){
      // 首先,从规则中分离选择器
      a: for (var i=0, Len=selectorAndRule.length, isEscaped=0, newCharCode=0; i !== Len; ++i) {
        newCharCode = selectorAndRule.charCodeAt(i);
        if (!isEscaped &amp;&amp; (newCharCode === 123)) { // 123 = "{".charCodeAt(0)
          // 其次,找到花括号
          var openBracketPos = i, closeBracketPos = -1;

          for (; i !== Len; ++i) {
            newCharCode = selectorAndRule.charCodeAt(i);
            if (!isEscaped &amp;&amp; (newCharCode === 125)) { // 125 = "}".charCodeAt(0)
              closeBracketPos = i;
            }
            isEscaped ^= newCharCode===92?1:isEscaped; // 92 = "\\".charCodeAt(0)
          }

          if (closeBracketPos === -1) break a; // No closing bracket was found!
            /*else*/ return originalInsertRule.call(
            this, // 想要改变的样式表
            selectorAndRule.substring(0, openBracketPos), // 选择器
            selectorAndRule.substring(closeBracketPos), // 规则
            arguments[3] // 插入的索引
          );
        }

        // Works by if the char code is a backslash, then isEscaped
        // gets flipped (XOR-ed by 1), and if it is not a backslash
        // then isEscaped gets XORed by itself, zeroing it
        isEscaped ^= newCharCode===92?1:isEscaped; // 92 = "\\".charCodeAt(0)
      }
      // Else, there is no unescaped bracket
      return originalInsertRule.call(this, selectorAndRule, "", arguments[2]);
    };
  }
})(CSSStyleSheet.prototype);</code>
</pre>

<h2 id="Notes" name="Notes">规范</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('CSSOM', '#dom-cssstylesheet-insertrule', 'CSSStyleSheet.insertRule')}}</td>
   <td>{{Spec2('CSSOM')}}</td>
   <td>No change from {{SpecName('DOM2 Style')}}.</td>
  </tr>
  <tr>
   <td>{{SpecName('DOM2 Style', 'css.html#CSS-CSSStyleSheet-insertRule', 'CSSStyleSheet.insertRule')}}</td>
   <td>{{Spec2('DOM2 Style')}}</td>
   <td>Initial definition</td>
  </tr>
 </tbody>
</table>

<h2 id="sect1"></h2>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<div class="hidden">
<p>The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
</div>

<p>{{Compat("api.CSSStyleSheet.insertRule")}}</p>

<h3 id="传统浏览器支持">传统浏览器支持</h3>

<p>为了支持 Internet Explorer 8 和更早版本,请使用: <code>addRule(selector, rule [, index]);</code>。例如:<code>addRule('pre', 'font: 14px verdana'); // add rule at end</code></p>

<p>另外注意非标准的 <code><a href="http://www.quirksmode.org/dom/w3c_css.html#change">removeRule()</a></code> 和 <code><a href="http://www.quirksmode.org/dom/w3c_css.html#access">.rules</a></code> 方法分别用 {{domxref("CSSStyleSheet.deleteRule","deleteRule()")}}{{domxref("CSSStyleSheet",".cssRules")}} 代替。</p>

<h2 id="相关链接">相关链接</h2>

<ul>
 <li>{{domxref("CSSStyleSheet.deleteRule")}}</li>
 <li><a href="http://www-archive.mozilla.org/docs/web-developer/css1technote/css1tojs.html#priority">Cross-Browser CSS-rules ordering (CSS1)</a></li>
 <li><a href="http://www.quirksmode.org/dom/w3c_css.html">Quirksmode - CSS</a></li>
</ul>

<p>
 <audio class="hidden"></audio>
</p>