# pardnchiu/RenderJS > RenderJS:邱敬幃 Pardn Chiu(pardnchiu)的零依賴 JS 模板引擎,具鏈式 DOM 語法與原生 prototype 擴充。 依導覽順序收錄所有文件頁;每段開頭標示來源 URL。 --- Source: https://renderjs.pardn.io/zh/index.md > [!NOTE] > 此 README 由 [SKILL](https://github.com/agenvoy/skill-readme-generate) 生成,英文版請參閱 [這裡](https://github.com/pardnchiu/renderjs/blob/main/README.md)。 ***

EXTEND NATIVE JS PROTOTYPES, RENDER WITHOUT THE OVERHEAD

npm Downloads License

*** > JavaScript 函式庫,具備鏈式 DOM 建構、一次性模板引擎與原生原型擴充 ## 目錄 - [功能特點](#功能特點) - [架構](#架構) - [授權](#授權) - [Author](#author) ## 功能特點 > `npm i @pardnchiu/renderjs` · [完整文件](https://github.com/pardnchiu/renderjs/blob/main/doc/doc.zh.md) - **鏈式 DOM 建構** — 以標籤選擇器字串直接產生真實 DOM 元素,取代冗長的 createElement 呼叫鏈。 - **一次性模板引擎** — 宣告式指令單次渲染進 DOM,不做虛擬 DOM 比對也不做自動響應式監聽,更新時機完全由開發者掌控。 - **原生原型擴充** — 為 String、Array、Object、Element、URL 與 window 補上數十個可串接的方法,涵蓋元素查詢、請求、查詢字串與 Cookie。 - **內建延遲載入與 SVG 內嵌** — 一行啟用以 IntersectionObserver 驅動的圖片延遲載入與外部 SVG 自動內嵌。 - **零相依單檔部署** — 單一壓縮檔即可透過 npm 或 CDN script 標籤直接在瀏覽器執行。 ## 架構 > [完整架構](https://github.com/pardnchiu/renderjs/blob/main/doc/architecture.zh.md) ```mermaid graph TB S["script copyright 屬性"] --> G[初始化閘門] T[HTML 模板] --> R[RJS 核心] G --> R R --> D[指令解析器] D --> O[渲染後 DOM] P[原型擴充] -.-> O L[延遲載入 / SVG 監聽器] -.-> O ``` ## 授權 本專案採用 [MIT LICENSE](https://github.com/pardnchiu/renderjs/blob/main/LICENSE)。 ## Author Just [open an issue](https://github.com/pardnchiu/renderjs/issues/new) to share an idea. renderjs contributors *** ©️ 2022 [邱敬幃 Pardn Chiu](https://www.linkedin.com/in/pardnchiu) --- Source: https://renderjs.pardn.io/zh/getting-started.md # 快速開始 安裝 RenderJS 所需的環境與兩種引入方式(npm、CDN)。 ## 前置需求 - 現代瀏覽器(支援 ES2022,需要 `IntersectionObserver`、`navigator.clipboard`、`fetch`) - Node.js(僅建置/開發時需要;執行期不依賴 Node 環境) - 無其他執行期相依套件 ## 安裝 ### 透過 npm 安裝 ```shell npm i @pardnchiu/renderjs ``` ### 透過 CDN 引入 ```html ``` > `copyright="Pardn Ltd"` 是 `RJS` 模板引擎的必要屬性:缺少時 script 標籤會自行移除且不設定初始化旗標(`document.$init`),`RJS` 只處理根節點本身的文字,子節點的指令與 `{{ }}` 全部不渲染。原型擴充與鏈式 DOM 建構不受影響。 ## 下一步 - [建構 DOM 元素](/zh/getting-started-dom):鏈式 DOM 建構與元素查詢 - [第一個 RJS 模板](/zh/getting-started-rjs):建立 `RJS` 實例並以 `renew()` 更新 - [核心概念](/zh/core-concepts):`RJS` 的實例生命週期與非響應式設計 - [API 參考](/zh/api-reference):RenderJS 加入的所有 prototype 方法 - [Listener 系統](/zh/listener-system):lazyload 與 SVG 內嵌的內部運作 --- Source: https://renderjs.pardn.io/zh/getting-started-dom.md # 建構 DOM 元素 以標籤選擇器字串建構真實 DOM 元素,並用字串 getter 查詢元素。 ## 第一次渲染:鏈式 DOM 建構 `"tag.class#id"._(attrs, children)` 依標籤選擇器字串建立真實 DOM 元素,自動處理 SVG 命名空間與 `input`/`textarea` 型別解析。 ```demo ``` ## 元素查詢 ```demo
#test
first .test
second .test


```

完整方法列表見 [String 擴充](/zh/api-reference-string) 與 [Element 擴充](/zh/api-reference-element)。

---

Source: https://renderjs.pardn.io/zh/getting-started-rjs.md

# 第一個 RJS 模板

建立 `RJS` 實例、定義 `data`/`event`/`when`,並以 `renew()` 觸發下一次渲染。

## 建立與更新

`RJS` 只渲染一次(不做 vDOM 比對),下一次渲染需透過 `renew()` 手動觸發。指令解析流程詳見 [指令解析](/zh/core-concepts-directives)。

```javascript
const app = "#app".RJS({
    data: {
        // 定義資料
    },
    event: {
        // 定義事件方法
    },
    when: {
        before_render: function () {
            // 渲染前執行,return false 可中止渲染
        },
        rendered: function () {
            // 渲染完成後執行
        }
    }
});

// 更新:僅需傳入要更新的項目,未提及的項目維持初始值
app.renew({
    data: { /* ... */ },
    event: { /* ... */ },
    when: { /* ... */ }
});
```

## 即時範例

`data` 填入 `{{ title }}`,`event.greet` 透過 `@click` 綁定,`when.rendered` 在渲染完成後執行。

```demo

{{ title }}

``` --- Source: https://renderjs.pardn.io/zh/core-concepts.md # 核心概念 `RJS` 實例(`src/model/RJS.ts`)如何建立與重新渲染,以及每次渲染為何是單次、非響應式。 ## 實例生命週期 `"#selector".RJS(body)` 透過 `body.id` 查找目標元素,複製一份作為原始模板(`#model`),並將 `data`/`event`/`when` 儲存於實例上。若選擇器解析結果為 `null`,建構子會提早返回,不會初始化任何實例。 ```mermaid graph TB Entry["#selector.RJS(body)"] --> Ctor["建構子: 查找節點, cloneNode(true)"] Ctor --> Init["#init()"] Init --> Before["when.before_render()"] Before -->|"回傳 false"| Cancel["渲染中止"] Before -->|"繼續"| SetDOM["#SET_DOM(body, data) — 遞迴走訪"] SetDOM --> After["when.rendered()"] ``` `app.renew(body)` 會從複製的 `#model` 還原 DOM(`replaceChildren(...this.#model.children)`),將傳入的 `data`/`event`/`when` 鍵合併進現有實例狀態(未提及的鍵維持原值),並重新執行 `#init()`。這是 `RJS` 實例重新渲染的唯一方式——沒有自動響應式或髒值檢查機制。 `before_render` 回傳 `false` 會中止這次渲染,`rendered` 不會執行,模板文字維持原樣: ```demo

{{ msg }}

``` ## 非響應式是刻意設計 `RJS.ts` 中每一段被註解掉的程式碼(`#dataListener`、`Object.defineProperty` 的 getter/setter 對)都是被移除的響應式 observer 機制。現行設計每次 `#init()` 只渲染一次,需要明確呼叫 `renew()` 才會更新——這項取捨正是 [README](/zh/) 所述「移除自動監聽帶來的效能負擔」。 ## 延伸主題 - [指令解析](/zh/core-concepts-directives):`#SET_DOM` 的指令處理順序與各指令行為 - [文字插值](/zh/core-concepts-interpolation):`{{ }}` 的取值與輔助函式 --- Source: https://renderjs.pardn.io/zh/core-concepts-directives.md # 指令解析 `RJS` 的 `#SET_DOM` 走訪模板時套用指令的順序,以及每個指令(`:path`、`:for`、`:if`、`:model`、`:[attr]`、`@[event]`)的行為。 ## 指令解析順序 `#SET_DOM` 依序走訪每個子元素並套用指令。帶有 `:path` 或 `:for` 標籤的節點會短路進入各自的處理函式,並跳過該節點後續的流程: ```mermaid graph TB Node["子元素"] --> PathCheck{"有 :path 屬性?"} PathCheck -->|是| SetPath["#setPath: 抓取片段並內嵌,返回"] PathCheck -->|否| ForCheck{"有 :for 屬性?"} ForCheck -->|是| FitFor["#FIT_FOR: 展開迴圈,返回"] ForCheck -->|否| SetIf["#setIf: :if / :else-if / :else"] SetIf --> FitModel["#FIT_MODEL: 表單雙向綁定"] FitModel --> FitAttr["#FIT_ATTRIBUTE: :[attr] / :[css]"] FitAttr --> FitEvent["#FIT_EVENT: @[event]"] FitEvent --> FitText["#FIT_TEXT: {{ }} 文字插值"] FitText --> Recurse["#SET_DOM(child) — 遞迴至孫節點"] ``` 尚未由 `#setIf` 判定完成(後方仍有待解析的 `:else-if`/`:el-if`/`:else` 兄弟節點)的元素會在這一輪被跳過;`#setIf` 移除落敗分支後,會對父節點重新呼叫一次 `#SET_DOM`。 ## 各指令行為 ### `:path` — 非同步片段載入 僅套用於帶 `:path` 屬性的元素。`#setPath` 會 `fetch` 目標 URL,將回傳的 HTML 作為子節點插入,並對該片段重新執行 `#SET_DOM`(除非片段內含 `new PD` 建構式,此時不處理)。片段中的 `script` 標籤會被移至 `document.body` 底部執行;其餘內容原地展開,原本的佔位節點會被移除。fetch 失敗時同樣會移除該節點。 ### `:for` — 迴圈展開 支援三種格式:`item in items`、`(item, index) in items`、`(key, value) in object`。`#FIT_FOR` 針對每個陣列項目(或物件鍵)複製一份模板節點,綁定 `subItem = { [val0]: item, [val1]: index }`(或 `{ [val0]: key, [val1]: value }`),對每份複本渲染屬性/事件/文字後,將整批節點插回原節點所在位置。巢狀物件項目會進行完整的遞迴 `#SET_DOM`;純值項目則只做屬性/事件/文字代換。 ### `:if` / `:else-if` / `:el-if` / `:else` `#setIf` 會將 `:if` 節點與其後緊接的 `:else-if`/`:el-if`/`:else` 兄弟節點收集為一組,依序評估各條件,僅保留第一個符合的節點(同組內即使後方節點自身條件成立,也一律移除)。支援的運算子:`>`、`<`、`>=`/`>==`、`<=`/`<==`、`==`/`===`、`!=`/`!==`。`==`/`!=` 會先特判 `null`、`true`、`false`、`empty`(空字串檢查)等字面值,其餘才回退為字串相等比較。 ```demo

Grade: A

Grade: pass

Grade: fail

No note

Active

``` ### `:model` — 表單雙向綁定 `#FIT_MODEL` 依綁定元素型別分派:checkbox/radio 監聽 `change`,並將所有勾選值以 `,` 串接;`select` 監聽 `change`;純 `input`/`textarea` 同時監聽 `keyup` 與 `change`。無論哪種情況,handler 都是直接寫入該次渲染傳入的 `data` 物件——寫入本身不會觸發任何 observer 或響應式重新渲染。 ```demo

``` ### `:[attr]` / `:[css]` — 屬性與樣式綁定 `#FIT_ATTRIBUTE` 收集所有符合 `/^:[\w\-]+$/`(排除上述指令名稱)的屬性,透過 `#GET_VALUE` 解析其值後交給 `#SET_ATTRIBUTE`。`:class` 會呼叫 `_class()`(見 [Element 擴充](/zh/api-reference-element));`:id`/`:src`/`:alt`/`:href`/`:html` 直接對應到相同名稱的 DOM 屬性;其餘 camel-case 後存在於 `element.style` 上的鍵視為 CSS 屬性;其餘一律作為純 HTML attribute(若解析值為空則移除)。 ```demo
{{ link.text }}
``` ### `@[event]` — 事件綁定 `#FIT_EVENT` 比對 `/^@[\w]+$/` 格式的屬性,將 `@click` 改寫為 `onclick`,並在 `this.event` 中查找對應的 handler 名稱。在 `:for` 迴圈內,handler 名稱本身也可以是逐項資料值(透過與 `{{ }}` 插值相同的 key-path 解析),而非固定方法名。 ```demo

``` --- Source: https://renderjs.pardn.io/zh/core-concepts-interpolation.md # 文字插值 `RJS` 如何解析文字節點中的 `{{ }}`,以及可用的取值輔助函式。 ## 解析流程 `#FIT_TEXT`(頂層)/`#FIT_TEXT_IN_ARRAY`/`#FIT_TEXT_IN_OBJECT`(`:for` 內部)會掃描文字節點中的 `{{ ... }}`,並透過 `#GET_VALUE` 解析每個符合項,支援: ## 輔助函式 | 輔助函式 | 行為 | | --- | --- | | `{{ key.path }}` | 逐層 dot-path 查找 `data`,透過 `#GET_VALUE_FROM_LAYERS` 走訪 | | `{{ CALC(key + n) }}` | 算術運算:`+ - * / %`,透過 `#CALC` 執行 | | `{{ LENGTH(key) }}` | 純物件為 `Object.keys(value).length`,其餘為 `value.length` | | `{{ UPPER(key) }}` / `{{ LOWER(key) }}` | `.toUpperCase()` / `.toLowerCase()` | | `{{ DATE(key, format) }}` | 將 `key` 解析為 Unix timestamp 並格式化(見 [Date 與 Number 擴充](/zh/api-reference-date-time) 的 `Number.$format`)| ```demo

Name: {{ user.name }}

Upper: {{ UPPER(user.name) }} / Lower: {{ LOWER(user.role) }}

Next year: {{ CALC(user.age + 1) }}

Tags: {{ LENGTH(tags) }}

Joined: {{ DATE(joined, YYYY-MM-DD) }}

``` ## 嵌入前後文字 `REGEX_TEXT` 也支援值嵌入周圍字面文字中的情況(`prefix {{ key }} suffix`),代換時會保留前後綴。 --- Source: https://renderjs.pardn.io/zh/architecture.md # 架構 RenderJS 的模組層級配置:單一 `data.ts` 常數模組同時支撐 `RJS` 模板引擎與原生 prototype 擴充,另有獨立的 `IntersectionObserver` listener 層負責 lazyload/SVG。 ## 概覽 ```mermaid graph TB A[HTML 模板 / DOM 節點] --> B[RJS 核心] B --> C[指令解析器] C --> D[渲染後的 DOM] E[Prototype 擴充模組] -.鏈式方法.-> D F[Lazyload / SVG Listener] -.IntersectionObserver.-> D G[data.ts 常數與工具] --> B G --> E ``` ## 分層 | 層級 | 位置 | 職責 | | --- | --- | --- | | 常數與工具 | `src/data.ts` | 縮寫屬性名稱別名(`$GET`、`$ADD`、`$IS` ...)、共用正則(`REGEX_TEXT`、`REGEX_FOR_VAL0` ...),以及跨模組共用的全域變數如 `requestMap`/`userHistory` | | RJS 核心 | `src/model/RJS.ts` | `RJS` 類別:實例生命週期(`constructor`、`renew`、`#init`)與指令解析流程(`#SET_DOM` 及其 `#FIT_*`/`#setIf`/`#setPath` 輔助函式)| | Prototype 擴充 | `src/prototype/*.ts`(型別定義於 `src/interface/*.ts`)| 每個檔案在模組載入時直接擴充對應原生建構子的 `.prototype`——涵蓋 `String`、`Element`、`Array`、`Object`、`URL`、`window`、`Date`、`Number`、`Map`、`Image`、`HTMLElement`、`File`、`HTMLVideoElement`、`HTMLFormElement`、`HTMLLinkElement`、`FormData`、`DocumentFragment` | | Listener 子系統 | `src/listener/*.ts`、`src/function/listener.ts` | 全域 `IntersectionObserver` 實例,負責圖片延遲載入與 SVG 內嵌,透過 `window._Listener(...)` 進入 | | 輔助函式 | `src/function/*.ts` | `getCamelString`(kebab 轉 camel,供 CSS 屬性查找)、`printLog`/`printCopyright`(console 橫幅)| | 打包進入點 | `src/RenderJS.js` | 上述模組編譯/串接後的產物,透過 `terser` 壓縮為 `dist/RenderJS.js`(`npm run minify`)| ## 跨切面說明 - **載入順序耦合**:prototype 檔案以 `(_this => { ... })($Type[_prototype])` IIFE 形式在載入時執行——沒有明確的 init 呼叫,因此 `src/RenderJS.js` 的 import 順序決定了 `RJS.ts` 首次執行時哪些擴充已存在。 - **無虛擬 DOM**:指令解析器(`RJS.ts`)直接原地修改真實 DOM 節點;重新渲染僅由明確呼叫 `renew()` 觸發,絕不自動發生。 - **屬性名稱混淆**:`data.ts` 將其他模組使用的每個 DOM/JS 屬性名稱定義為 `const _xxx = "xxx"`(並進一步組合,如 `_appendChild = "append" + _Child`)。這是一種壓縮策略,而非執行期抽象層——閱讀原始碼時可將 `_ary[_push](x)` 理解為 `ary.push(x)`。 指令解析流程細節見 [指令解析](/zh/core-concepts-directives);完整 prototype 方法列表見 [API 參考](/zh/api-reference);模組層級的 sequence/state diagram 見 [完整架構文件](https://github.com/pardnchiu/renderjs/blob/main/doc/architecture.md)。 --- Source: https://renderjs.pardn.io/zh/api-reference.md # API 參考 RenderJS 直接擴充原生建構子的 `.prototype`(`src/prototype/*.ts`),並非獨立 import 的模組。載入 bundle 後,以下所有方法即全域可用。 ## 依擴充對象分頁 | 頁面 | 擴充對象 | | --- | --- | | [String 擴充](/zh/api-reference-string) | `String` | | [Element 擴充](/zh/api-reference-element) | `Element` / `DocumentFragment` | | [HTMLElement 與連結擴充](/zh/api-reference-html-element) | `HTMLElement` / `HTMLLinkElement` | | [Array 與 Object 擴充](/zh/api-reference-array-object) | `Array` / `Object` | | [Map 與表單資料擴充](/zh/api-reference-map-form) | `Map` / `FormData` / `HTMLFormElement` | | [URL 擴充](/zh/api-reference-url) | `URL` | | [全域函式](/zh/api-reference-window) | `window` | | [Date 與 Number 擴充](/zh/api-reference-date-time) | `Date` / `Number` | | [Image、File 與 Video 擴充](/zh/api-reference-media) | `Image` / `File` / `HTMLVideoElement` | --- Source: https://renderjs.pardn.io/zh/api-reference-string.md # String 擴充 RenderJS 為 `String.prototype` 加入的方法與 getter:以標籤選擇器字串建構 DOM、元素查詢、JSON/HTML 工具與 URL 捷徑。 ## String 原始碼:`src/prototype/String.ts` | 方法/屬性 | 說明 | | --- | --- | | `"selector".RJS(body)` | 於符合選擇器的元素上啟動 `RJS` 實例;見 [核心概念](/zh/core-concepts) | | `"tag.class#id"._(attrs, children)` | 依標籤選擇器字串建立真實 DOM 元素(含 SVG 命名空間偵測、`input`/`textarea` type/placeholder 解析、`lazyload` 屬性接線)| | `"selector".$` | 取得符合的單一元素(`#id` 走 `getElementById`,其餘走 `querySelector`)| | `"selector".$all` | 取得所有符合元素的陣列(`[...querySelectorAll(...)]`)| | `"icon-a icon-b"._fa` | Getter,建構 `"i.icon-a.icon-b"._()` —— 依空格分隔的 class 名稱產生 Font Awesome `` 元素 | | `"str".$json` | 安全的 `JSON.parse(this)`;解析失敗時回傳 `undefined`(並記錄 log)| | `"str".$$json` | `$json` 未失敗時為 `true` | | `"str".$html` | HTML 逸出 ` `、`<`、`>`、`"`、`'` | | `"str".copy()` | 非同步;透過 `navigator.clipboard.writeText` 寫入剪貼簿 | | `"str".$regexp(flags?, force?)` | 依字串建構 `RegExp`;`force: true` 會先逸出正則特殊字元 | | `"str".$base64(mimeType)` | 將 base64 字串解碼為 `Blob` | | `"str".$$(filter?)` | 正則測試、字串完全相等,或(無參數時)去除空白後非空的判斷 | | `"url".$url` | `new URL(this)`,相對路徑時 fallback 為 `new URL(location.origin + this)` | | `"url".$queryAll` | 解析後的 query string 物件(透過 `$url.$queryAll`)| | `"url".$img` / `$$200(isImg)` / `$req(body, once)` / `$query` / `_history(title)` / `_query(obj)` / `__history(title)` / `__query(obj)` / `query_(keys)` / `query__()` | 轉發至下方 `URL` 對應的方法/getter,套用於 `this.$url` | ## 範例 建立元素後,印出查詢、JSON、HTML 跳脫、查詢字串與 regex 輔助函式的結果。 ```demo
``` --- Source: https://renderjs.pardn.io/zh/api-reference-element.md # Element 擴充 `Element.prototype` 與 `DocumentFragment.prototype` 上的鏈式方法:內容、class、屬性、子元素、節點走訪與事件處理。 ## Element 原始碼:`src/prototype/Element.ts` | 方法/屬性 | 說明 | | --- | --- | | `el.length` | `this.children.length` | | `el.$i` | 元素在父層子節點中的索引 | | `el.$attributes` | 所有屬性組成的 `{ name: value }` 物件 | | `el._(value)` / `el.__(value)` | 新增/取代子節點——字串與數字轉為文字節點;純物件會格式化為 `
` 分行的 JSON | | `el._style(map)` / `el._data(map)` / `el._attr(map)` | 鏈式:依物件批次設定 `style` / `dataset` / attribute 鍵值 | | `el._class(list)` | 鏈式:新增一或多個 class(字串以逗號/空白/點分隔,或陣列)| | `el.class_(list)` / `el.style_(list)` / `el.data_(list)` / `el.attr_(list)` | 鏈式:移除 class/清除樣式/刪除 dataset 鍵/移除屬性 | | `el.$style(key)` / `el.$data(key)` / `el.$attr(key)` | 讀取單一樣式屬性/dataset 項目/屬性值 | | `el.class__()` | 鏈式:完全清空 `className` | | `el.__class(list)` | 鏈式:取代整個 class 列表 | | `el.$$class(list)` | 僅當 `list` 中**每個** class 都存在時為 `true` | | `el.$$class_(bool, list)` | 鏈式:`bool` 為假時新增 `list`,為真時移除(省略 `bool` 時自動偵測目前狀態)| | `el.$$data(key, value?)` / `el.$$attr(key, value?)` | dataset/屬性值等於 `value` 時為 `true`;省略 `value` 時檢查是否非空 | | `el._children(...args)` | 鏈式:透過 `_child` 逐一新增每個引數 | | `el._child(value, before)` | 鏈式:依索引或參照 `Element` 新增/插入子節點(或子節點陣列)| | `el.__child(value)` | 鏈式:取代子節點(`replaceChildren`)| | `el.$child(value)` | 依混合的選擇器字串與數字索引陣列查詢子節點 | | `el.$parent(count)` / `el.$pre(count)` / `el.$next(count)` | 沿 `parentElement` / `previousElementSibling` / `nextElementSibling` 走訪 `count` 步 | | `el.$sel(selector)` / `el.$selAll(selector)` | 有空值保護的 `querySelector` / `querySelectorAll` | | `el._click(fn)`(及所有 DOM 事件名,如 `_input`、`_keydown`、`_touchstart`、`_drop` 等)| 鏈式指定 `on = fn` | ## DocumentFragment 原始碼:`src/prototype/DocumentFragment.ts` | 方法/屬性 | 說明 | | --- | --- | | `fragment.innerHTML` | 透過一個未掛載的 `
` 序列化片段內容 | | `fragment.length` | `this.children.length` | | `fragment._children(...args)` | 逐一新增每個引數作為子節點 | | `fragment._child(value)` | 新增一個值(或值陣列);字串/數字轉為文字節點 | ## 範例 在同一個清單上串接子元素、class 與屬性設定,再讀回結果。 ```demo
    ``` --- Source: https://renderjs.pardn.io/zh/api-reference-html-element.md # HTMLElement 與連結擴充 `HTMLElement.prototype` 的版面與捲動工具,以及 `HTMLLinkElement.prototype` 的導覽工具。 ## HTMLElement 原始碼:`src/prototype/HTMLElement.ts` | 方法/屬性 | 說明 | | --- | --- | | `el._display(value)` | 鏈式 `style.display = value` | | `el.width(v)` / `height(v)` / `paddingTop(v)` / `paddingLeft(v)` / `paddingBottom(v)` / `paddingRight(v)` / `marginTop(v)` / `marginLeft(v)` / `marginBottom(v)` / `marginRight(v)` | 鏈式數值型樣式設定;純數字/數字字串會自動補上 `px` | | `el.padding(top, right?, bottom?, left?)` / `el.margin(...)` | CSS 簡寫式鏈式設定(1–4 個引數,回退規則與 CSS `padding`/`margin` 屬性相同)| | `el.scrollToX(value, animation?)` / `el.scrollToY(value, animation?)` | 捲動至絕對位置(會限制在內容邊界內),可選擇 `behavior: "smooth"` | | `el.scrollToT(animation?)` / `el.scrollToB(animation?)` | 捲動至頂部/底部邊緣 | | `el.scrollToL(animation?)` / `el.scrollToR(animation?)` | 捲動至左側/右側邊緣 | ## HTMLLinkElement 原始碼:`src/prototype/HTMLLinkElement.ts` | 方法 | 說明 | | --- | --- | | `a._go(href?)` | 鏈式:設定 `href`(若有給定)並在目前分頁導航(`target = "_self"`)| | `a._open(href?)` | 鏈式:設定 `href`(若有給定)並在新分頁導航(`target = "_blank"`)| ## 範例 數值設定會自動補 `px`;`padding` 依 CSS 簡寫規則展開。 ```demo
    box
    ``` --- Source: https://renderjs.pardn.io/zh/api-reference-array-object.md # Array 與 Object 擴充 `Array.prototype` 與 `Object.prototype` 新增的負索引存取、聚合與存在判斷。 ## Array 原始碼:`src/prototype/Array.ts` | 方法/屬性 | 說明 | | --- | --- | | `arr.$sum` | 透過 `reduce` 計算數值陣列總和 | | `arr.$shuffle` | 原地 Fisher–Yates 洗牌;回傳 `this` | | `arr.$map` | 每個項目的 `value → index` 組成的 `Map` | | `arr._(value, index?)` | 支援負索引的插入(`splice`);省略 `index` 時附加至末尾 | | `arr.$(index)` | 支援負索引的讀取 | | `arr.$i(target)` | `indexOf(target)`,找不到時回傳 `undefined` 而非 `-1` | | `arr.$_(index)` | 支援負索引的移除(`splice`)| | `arr.$$(target?)` | 無參數時判斷非空,有參數時判斷 `target` 是否存在 | | `arr.$req(body)` | 將陣列以 `/` 串接為 URL 路徑片段,再對該路徑呼叫 `$req` | ## Object 原始碼:`src/prototype/Object.ts`(擴充 `Object.prototype`,故適用於純物件) | 方法/屬性 | 說明 | | --- | --- | | `obj.length` | `Object.keys(this).length` | | `obj.$keys` / `obj.$values` | `Object.keys(this)` / `Object.values(this)` | | `obj.$map` | 自身可列舉屬性組成的 `Map` | | `obj.forEach(cb)` | 類陣列迭代:對自身可列舉屬性執行 `cb(key, value)` | | `obj._(key, value, replace = true)` | 條件式設定——僅當 `replace` 為 `true` 時才覆蓋已存在的鍵 | | `obj.$$(key?)` | 有 `key` 時為 `hasOwnProperty(key)`,否則為 `this.length > 0` | ## 範例 負索引從尾端計算;`obj._` 在 `replace = false` 時保留既有值。 ```demo ``` --- Source: https://renderjs.pardn.io/zh/api-reference-map-form.md # Map 與表單資料擴充 `Map` 的鏈式工具,以及 `FormData` 與 `
    ` 元素的 `$map`/`$json` 轉換。 ## Map 原始碼:`src/prototype/Map.ts` | 方法/屬性 | 說明 | | --- | --- | | `map.length` | `this.size` | | `map.$keys` / `map.$values` | keys/values 的迭代器 | | `map.$json` | `Object.fromEntries(this)` | | `map._(key, value?)` | 鏈式 `set(key, value)` | | `map.$(key?)` | `get(key)` | | `map.$_(key?)` | 鏈式 `delete(key)` | | `map.$$(key?)` | 有 `key` 時為 `has(key)`,否則為 `this.size > 0` | ## FormData 原始碼:`src/prototype/FormData.ts` | 方法/屬性 | 說明 | | --- | --- | | `formData.$map` | 條目組成的 `Map` | | `formData.$json` | 條目組成的純物件 | ## HTMLFormElement 原始碼:`src/prototype/HTMLFormElement.ts` | 方法/屬性 | 說明 | | --- | --- | | `form.$map` | 表單欄位組成的 `Map`(透過內部 `FormData` 封裝)| | `form.$json` | 表單欄位組成的純物件 | ## 範例 `` 直接轉成純物件;`Map` 的設定方法可串接。 ```demo
    ``` --- Source: https://renderjs.pardn.io/zh/api-reference-url.md # URL 擴充 RenderJS 為 `URL.prototype` 加入的請求、瀏覽紀錄與 query string 方法。 ## URL 原始碼:`src/prototype/URL.ts` | 方法/屬性 | 說明 | | --- | --- | | `url.$queryAll` | 解析後的 query string 物件 | | `url.$image` | 回傳預先載入該 URL 圖片的 Promise | | `url.$$200(isImg = false)` | fetch 該 URL;若回應為圖片,轉換為 object-URL blob(`{ src, img }`),除非是 SVG 且 `isImg` 為假 | | `url.$req(body, once = false)` | fetch 封裝:JSON 或 `FormData` body(透過 `body.json`/`body.files`/`body.tag`)、自訂 `header`/`credentials`、以共用 `Map`(以 URL 為 key)去重請求、自動 JSON/文字回應解析,4xx/5xx 時以回應文字 reject | | `url.$$query(key)` | `searchParams.get(key)` | | `url._history(title?)` | 對此 URL 執行 `pushState`,記錄至記憶體中的歷史堆疊,可選擇同步設定 `document.title` | | `url._query(obj)` | 回傳一個**新** `URL`,將 `obj` 的鍵合併進現有 query string | | `url.__history(title?)` | 對此 URL 執行 `replaceState`(同步更新歷史堆疊)| | `url.__query(obj)` | 回傳一個**新** `URL`,query string 整個由 `obj` 取代 | | `url.query_(keys)` | 回傳一個**新** `URL`,移除指定的鍵(單一或陣列)| | `url.query__()` | 回傳一個**新** `URL`,query string 已清空 | ## 範例 查詢字串方法回傳新的 `URL`;`$req` 依 `Content-Type` 解析回應,4xx/5xx 時以回應文字 reject。預覽在 `location.origin` 為 `null` 的 `about:srcdoc` 框架中執行,因此以 `document.baseURI` 解析路徑;一般頁面直接寫 `"/llms.txt".$req()` 即可。 ```demo ``` --- Source: https://renderjs.pardn.io/zh/api-reference-window.md # 全域函式 RenderJS 掛在 `window` 上的函式:listener 啟用、檔案讀取、cookie 與 `document.body` 捷徑。 ## window 原始碼:`src/prototype/window.ts` | 方法 | 說明 | | --- | --- | | `_Listener(target?)` | 無參數時同時啟用 lazyload 與 SVG 兩個 observer。有參數時,`target.svg` 決定是否啟用 lazyload observer,`target.lazyload` 決定是否啟用 SVG observer(observer 內部實作見 [Listener 系統](/zh/listener-system))| | `$file(file)` | 以 `FileReader.readAsDataURL` 包裝 `File`/`Blob`,於 `load` 事件時 resolve | | `$cookie(key)` | 讀取並 URI 解碼 cookie;若值看起來像 JSON 會自動 `JSON.parse` | | `_cookie(key, body, expire = 3600)` | 寫入 cookie(`expire` 單位為秒);物件會先 `JSON.stringify` | | `$(selector)` | 模組層級的 `"selector".$` 捷徑 | | `$all(selector)` | 模組層級的 `"selector".$all` 捷徑 | | `_child(value, before)` / `__child(value)` | 新增至/取代 `document.body` 的子節點 | ## 範例 `_child` 附加到 `document.body`,`__child` 取代其所有子節點。 ```demo ``` --- Source: https://renderjs.pardn.io/zh/api-reference-date-time.md # Date 與 Number 擴充 `Date.prototype` 的日期欄位 getter、`$format` 格式化與相對時間,以及 `Number.prototype` 的時間戳與隨機鍵工具。 ## Date 原始碼:`src/prototype/Date.ts` | 方法/屬性 | 說明 | | --- | --- | | `date.$y` / `$yy` / `$yyyy` | 年(原始、兩位數、四位數)| | `date.$M` / `$MM` | 月,從 1 起算(原始、補零)| | `date.$D` / `$DD` | 日(原始、補零)| | `date.$d` / `$dd` / `$ddd` / `$dddd` | 星期:索引,接著依長度遞增的本地化名稱(英文縮寫或 `zh` locale 的「星期X」,依 `navigator.language` 偵測)| | `date.$H` / `$HH` | 24 小時制時(原始、補零)| | `date.$h` / `$hh` | 12 小時制時(原始、補零)| | `date.$a` / `$A` | `am`/`pm`(小寫/大寫)| | `date.$m` / `$mm` | 分(原始、補零)| | `date.$s` / `$ss` | 秒(原始、補零)| | `date.$S` / `$SS` / `$SSS` | 毫秒,取 1/2/3 位數 | | `date.$timestamp` | Unix 秒級時間戳 | | `date.$gone` | 人性化相對時間(`"3 days"`/`"3天"`、`"Coming in..."`/`"還有..."`,未滿 1 分鐘為 `"recent"`/`"剛剛"`),依 `navigator.language` 本地化 | | `date.$format(format = "yyyy/MM/DD (ddd) HH:mm:ss")` | Token 式格式化;支援上表列出重複次數的 `Y`/`M`/`D`/`H`/`h`/`m`/`s`/`S`/`A`/`a`/`d` token | | `date.$date(body?)` | 依 `{ start }`/`{ end }`/`{ pre: { start } }`/`{ pre: { end } }` 回傳當月或上個月的第一天/最後一天;否則回傳 `new Date()` | ## Number 原始碼:`src/prototype/Number.ts` | 方法/屬性 | 說明 | | --- | --- | | `n.$uniKey` | 長度為 `n` 的隨機字串,取自 52 字元字母表,在該行程生命週期內去重 | | `n.$ASCII` | `String.fromCharCode(n)` | | `n.$date` | 將 `n` 視為 Unix 秒級時間戳,回傳對應的 `Date` | | `n.$y` / `$M` / `$D` / `$d` / `$H` / `$h` / `$a` / `$A` / `$m` / `$s` / `$S`(及其補零/重複變體)/ `$gone` | 轉發至 `n.$date` 對應的 `Date` getter | | `n.$format(format)` | 轉發至 `n.$date.$format(format)` | ## 範例 日期欄位取自本地時間;`$gone` 與星期名稱依 `navigator.language` 而定。 ```demo ``` --- Source: https://renderjs.pardn.io/zh/api-reference-media.md # Image、File 與 Video 擴充 `Image` 的剪貼簿、下載與重新編碼,`File` 的縮圖擷取,以及 `