範圍滑桿
範圍滑桿版面
單一範圍
單一範圍滑桿版面相當簡單
<!-- Range Slider element -->
<div class="range-slider">
<!-- range input -->
<input type="range" min="0" max="100" step="1" value="10" />
</div>
雙重範圍
雙重範圍滑桿較為簡單,因為它不需要輸入元素,因為 input:range 不支援雙重範圍
<!-- Range Slider element -->
<div class="range-slider"></div>
範圍滑桿色彩
範圍滑桿支援所有 預設色彩。因此,若要變更其色彩,只需將 color-[color] 類別新增至範圍滑桿元素即可。
<!-- red range -->
<div class="range-slider color-red">...</div>
<!-- orange range -->
<div class="range-slider color-orange">...</div>
範圍滑桿應用程式方法
讓我們來看看相關的應用程式方法,以搭配範圍滑桿使用
app.range.create(parameters)- 建立範圍滑桿執行個體
- parameters - 物件。包含範圍滑桿參數的物件
方法傳回已建立的範圍滑桿執行個體
app.range.destroy(el)- 銷毀範圍滑桿執行個體
- el - HTMLElement 或 字串(包含 CSS 選擇器)或 物件。要銷毀的範圍滑桿元素或範圍滑桿執行個體。
app.range.get(el)- 透過 HTML 元素取得範圍滑桿執行個體
- el - HTMLElement 或 字串(包含 CSS 選擇器)。範圍滑桿元素。
方法傳回範圍滑桿執行個體
app.range.getValue(el)- 取得範圍滑桿值
- el - HTMLElement 或 字串(包含 CSS 選擇器)。範圍滑桿元素。
方法傳回範圍滑桿值
app.range.setValue(el, value)- 設定新的範圍滑桿值
- el - HTMLElement 或 字串(包含 CSS 選擇器)。範圍滑桿元素。
- value - 數字(在單一範圍的情況下)或值 陣列(在雙重範圍的情況下)
方法傳回範圍滑桿執行個體
範圍滑桿參數
現在讓我們來看看建立範圍滑桿時所需的可用參數清單
參數 | 類型 | 預設值 | 說明 |
---|---|---|---|
el | HTMLElement 字串 | 範圍滑桿元素。HTMLElement 或包含範圍滑桿元素 CSS 選擇器的字串 | |
inputEl | HTMLElement 字串 | 範圍滑桿輸入元素或輸入元素的 CSS 選擇器。如果未指定,將嘗試在範圍滑桿元素中尋找 input type="range" | |
dual | 布林值 | false | 啟用雙重範圍滑桿 |
step | 數字 | 1 | 值之間的最小步驟 |
label | 布林值 | false | 在範圍滑桿旋鈕周圍啟用額外標籤 |
formatLabel | 函式(value) | 方法必須傳回格式化的範圍旋鈕標籤文字。它接收標籤值作為參數 | |
min | 數字 | 最小值 | |
max | 數字 | 最大值 | |
value | 數字 陣列 | 初始值。如果是單一範圍,則為數字;如果是雙重範圍,則為值陣列 | |
draggableBar | 布林值 | true | 啟用後,也可以透過點擊和滑動範圍列來與範圍滑桿互動(變更值)。 |
vertical | 布林值 | false | 啟用垂直範圍滑桿 |
verticalReversed | 布林值 | false | 使垂直範圍滑桿反向(也必須啟用 vertical ) |
scale | 布林值 | false | 啟用範圍滑桿比例 |
scaleSteps | 數字 | 5 | 比例步驟數 |
scaleSubSteps | 數字 | 0 | 比例子步驟數(每個步驟將除以這個值) |
formatScaleLabel | 函式 (value) | 方法必須傳回格式化的比例值。它接收目前的比例步驟值作為參數。這個方法會針對每個比例步驟呼叫。 | |
limitKnobPosition | 布林值 | 將旋鈕位置限制在範圍列的大小。預設從 iOS 主題啟用 | |
on | 物件 | 包含事件處理常式的物件。例如
|
範圍滑桿方法和屬性
因此,若要建立範圍滑桿,我們必須呼叫
var range = app.range.create({ /* parameters */ })
之後,我們會取得已初始化的執行個體(就像上面範例中的 range
變數),其中包含有用的方法和屬性
屬性 | |
---|---|
range.app | 連結到全域應用程式執行個體 |
range.el | 範圍滑桿 HTML 元素 |
range.$el | 包含範圍滑桿 HTML 元素的 Dom7 執行個體 |
range.inputEl | 範圍滑桿輸入 HTML 元素 |
range.$inputEl | 包含範圍滑桿輸入 HTML 元素的 Dom7 執行個體 |
range.rangeWidth | 範圍滑桿寬度(以像素為單位) |
range.dual | 布林屬性,表示是否為雙向 |
range.min | 範圍最小值 |
range.max | 範圍最大值 |
range.value | 範圍值 |
range.scale | 布林屬性,表示是否啟用scale |
range.scaleSteps | 比例步驟數 |
range.scaleSubSteps | 刻度子步驟數 |
range.$scaleEl | 具有已產生刻度 HTML 元素的 Dom7 實例 |
range.knobs | 陣列,其中每個元素代表已建立範圍旋鈕的 HTMLElement(在雙滑塊的情況下為 2 個旋鈕) |
range.labels | 陣列,其中每個元素代表已建立範圍旋鈕標籤的 HTMLElement(在雙滑塊的情況下為 2 個標籤) |
range.vertical | 布林屬性,表示是否為垂直 |
range.verticalReversed | 布林屬性,表示是否為垂直且反向 |
range.params | 範圍滑塊參數 |
方法 | |
range.getValue() | 傳回範圍滑塊值 |
range.setValue(value) | 設定新的範圍滑塊值 |
range.updateScale() | 重新計算並重新呈現滑塊刻度 |
range.destroy() | 銷毀範圍滑塊實例 |
range.on(event, handler) | 新增事件處理常式 |
range.once(event, handler) | 新增事件處理常式,在觸發後會移除 |
range.off(event, handler) | 移除事件處理常式 |
range.off(event) | 移除指定事件的所有處理常式 |
range.emit(event, ...args) | 在實例上觸發事件 |
範圍滑塊事件
範圍滑塊會在範圍元素上觸發下列 DOM 事件,以及在應用程式和範圍實例上觸發事件
DOM 事件
事件 | 目標 | 說明 |
---|---|---|
range:change | 範圍滑塊元素<div class="range-slider"> | 當範圍滑塊值已變更時,將觸發事件 |
range:changed | 範圍滑塊元素<div class="range-slider"> | 在值變更後,將在滑塊旋鈕釋放時觸發事件 |
range:beforedestroy | 範圍滑塊元素<div class="range-slider"> | 在範圍滑塊實例將被銷毀之前,將觸發事件 |
應用程式和範圍滑塊實例事件
範圍滑塊實例會在自身實例和應用程式實例上發出事件。應用程式實例事件具有相同的名稱,但前綴為range
。
事件 | 參數 | 目標 | 說明 |
---|---|---|---|
change | (範圍, 值) | 範圍 | 當範圍值變更時,將觸發事件。事件處理常式接收範圍實例作為參數 |
rangeChange | (範圍, 值) | 應用程式 | |
已變更 | (範圍, 值) | 範圍 | 值變更後,當滑桿按鈕釋放時,將觸發事件。事件處理常式接收範圍實例作為參數 |
rangeChanged | (範圍, 值) | 應用程式 | |
beforeDestroy | (範圍) | 範圍 | 在 Range Slider 實例即將被銷毀之前,將觸發事件。事件處理常式接收範圍實例作為參數 |
rangeBeforeDestroy | (範圍) | 應用程式 |
Range Slider 自動初始化
如果您不需要使用 Range Slider API,且您的 Range Slider 在頁面內部,並在頁面初始化時顯示在 DOM 中,則只需新增額外的 range-slider-init
類別,即可自動初始化。
<!-- Add range-slider-init class -->
<div class="range-slider range-slider-init">
<input type="range" min="0" max="100" step="1" value="10" />
</div>
在這種情況下,如果您需要存取已建立的 Range Slider 實例,可以使用 app.range.get
應用程式方法
var range = app.range.get('.range-slider');
if (range.value > 50) {
// do something
}
使用自動初始化時,您可能需要傳遞額外的參數。這可以用兩種方式來完成
在您使用單一範圍滑桿,且內部有 input:range 時,則
step
、min
、max
、value
參數可以從相同的輸入屬性設定<!-- min, max, step, value parameters will be set for same input attributes --> <div class="range-slider range-slider-init"> <input type="range" min="0" max="100" step="1" value="10" /> </div>
否則,如果您沒有內部的 input:range,或您使用雙重範圍輸入,則您可以透過範圍滑桿元素上的
data-
屬性設定所有可用的參數。<!-- parameters set via data- attributes --> <div class="range-slider range-slider-init" data-min="0" data-max="100" data-step="10" data-label="true" data-value="50" ></div>
如果您有雙重範圍滑桿,則您需要使用
data-value-left
和data-value-right
屬性傳遞兩個值<!-- parameters set via data- attributes --> <div class="range-slider range-slider-init" data-dual="true" data-min="0" data-max="100" data-step="10" data-label="true" data-value-left="30" data-value-right="60" ></div>
CSS 變數
以下是相關 CSS 變數 (CSS 自訂屬性) 清單。
請注意,已註解的變數並未預設指定,其值是它們在此情況下的後備值。
:root {
/*
--f7-range-bar-active-bg-color: var(--f7-theme-color);
--f7-range-scale-bg-color: var(--f7-range-bar-bg-color);
--f7-range-scale-substep-bg-color: var(--f7-range-bar-bg-color);
*/
--f7-range-scale-step-height: 5px;
--f7-range-scale-substep-width: 1px;
--f7-range-scale-substep-height: 4px;
--f7-range-bar-bg-color: rgba(0, 0, 0, 0.2);
}
:root .dark,
:root.dark {
--f7-range-bar-bg-color: rgba(255, 255, 255, 0.2);
}
.ios {
--f7-range-size: 28px;
--f7-range-bar-size: 4px;
--f7-range-bar-border-radius: 2px;
--f7-range-knob-size: 28px;
--f7-range-knob-color: #fff;
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
--f7-range-label-size: 24px;
--f7-range-label-text-color: #000;
--f7-range-label-bg-color: #fff;
--f7-range-label-font-size: 12px;
--f7-range-label-font-weight: 500;
--f7-range-label-border-radius: 5px;
--f7-range-label-padding: 0px 2px;
--f7-range-scale-text-color: #666;
--f7-range-scale-step-width: 1px;
--f7-range-scale-font-size: 12px;
--f7-range-scale-font-weight: 400;
--f7-range-scale-label-offset: 4px;
}
.md {
--f7-range-size: 20px;
--f7-range-bar-size: 2px;
--f7-range-bar-border-radius: 0px;
--f7-range-knob-size: 12px;
--f7-range-knob-box-shadow: none;
--f7-range-label-size: 26px;
--f7-range-label-font-weight: normal;
--f7-range-label-font-size: 10px;
--f7-range-label-border-radius: 50%;
--f7-range-label-padding: 0px;
--f7-range-scale-step-width: 2px;
--f7-range-scale-font-size: 12px;
--f7-range-scale-font-weight: 400;
--f7-range-scale-label-offset: 4px;
}
.md,
.md .dark,
.md [class*='color-'] {
--f7-range-knob-color: var(--f7-theme-color);
--f7-range-label-text-color: var(--f7-md-on-primary);
--f7-range-label-bg-color: var(--f7-theme-color);
--f7-range-scale-text-color: var(--f7-md-on-surface-variant);
}
範例
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner sliding">
<div class="title">Range Slider</div>
</div>
</div>
<div class="page-content">
<div class="block-title">Volume</div>
<div class="list list-strong-ios list-outline-ios simple-list">
<ul>
<li>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">speaker_fill</i>
<i class="icon material-icons md-only" style="width: 24px">volume_mute</i>
</div>
<div style="width: 100%; margin: 0 16px">
<div class="range-slider range-slider-init">
<input type="range" min="0" max="100" step="1" value="10" />
</div>
</div>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">speaker_3_fill</i>
<i class="icon material-icons md-only" style="width: 24px">volume_up</i>
</div>
</li>
</ul>
</div>
<div class="block-title">Brightness</div>
<div class="list list-strong-ios list-outline-ios simple-list">
<ul>
<li>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">sun_min</i>
<i class="icon material-icons md-only" style="width: 24px">brightness_low</i>
</div>
<div style="width: 100%; margin: 0 16px">
<div class="range-slider range-slider-init color-orange" data-label="true">
<input type="range" min="0" max="100" step="1" value="50" />
</div>
</div>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">sun_max_fill</i>
<i class="icon material-icons md-only" style="width: 24px">brightness_high</i>
</div>
</li>
</ul>
</div>
<div class="block-title display-flex justify-content-space-between">
Price Filter <span class="price-value">$${priceMin} - $${priceMax}</span>
</div>
<div class="list list-strong-ios list-outline-ios simple-list">
<ul>
<li class="item-row">
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">money_dollar_circle</i>
<i class="icon material-icons md-only" style="width: 24px">attach_money</i>
</div>
<div style="width: 100%; margin: 0 16px">
<div class="range-slider range-slider-init color-green" @range:change=${onPriceChange} data-label="true"
data-dual="true" data-min="0" data-max="500" data-step="1" data-value-left="200" data-value-right="400">
</div>
</div>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">money_dollar_circle_fill</i>
<i class="icon material-icons md-only" style="width: 24px">monetization_on</i>
</div>
</li>
</ul>
</div>
<div class="block-title">With Scale</div>
<div class="block block-strong-ios block-outline-ios">
<div class="range-slider range-slider-init" data-min="0" data-max="100" data-label="true" data-step="5"
data-value="25" data-scale="true" data-scale-steps="5" data-scale-sub-steps="4"></div>
</div>
<div class="block-title">Vertical</div>
<div class="block block-strong-ios block-outline-ios display-flex justify-content-center">
<div class="range-slider range-slider-init margin-right" data-vertical="true" data-min="0" data-max="100"
data-label="true" data-step="1" data-value="25" style="height: 160px"></div>
<div class="range-slider range-slider-init margin-horizontal" data-vertical="true" data-min="0" data-max="100"
data-label="true" data-step="1" data-value="50" style="height: 160px"></div>
<div class="range-slider range-slider-init margin-horizontal" data-vertical="true" data-min="0" data-max="100"
data-label="true" data-step="1" data-value="75" style="height: 160px"></div>
<div class="range-slider range-slider-init margin-left" data-dual="true" data-vertical="true" data-min="0"
data-max="100" data-label="true" data-step="1" data-value-left="25" data-value-right="75"
style="height: 160px"></div>
</div>
<div class="block-title">Vertical Reversed</div>
<div class="block block-strong-ios block-outline-ios display-flex justify-content-center">
<div class="range-slider range-slider-init color-red margin-right" data-vertical="true"
data-vertical-reversed="true" data-min="0" data-max="100" data-label="true" data-step="1" data-value="25"
style="height: 160px"></div>
<div class="range-slider range-slider-init color-red margin-horizontal" data-vertical="true"
data-vertical-reversed="true" data-min="0" data-max="100" data-label="true" data-step="1" data-value="50"
style="height: 160px"></div>
<div class="range-slider range-slider-init color-red margin-horizontal" data-vertical="true"
data-vertical-reversed="true" data-min="0" data-max="100" data-label="true" data-step="1" data-value="75"
style="height: 160px"></div>
<div class="range-slider range-slider-init color-red margin-left" data-dual="true" data-vertical="true"
data-vertical-reversed="true" data-min="0" data-max="100" data-label="true" data-step="1" data-value-left="25"
data-value-right="75" style="height: 160px"></div>
</div>
</div>
</div>
</template>
<script>
export default (props, { $f7, $el, $update }) => {
let priceMin = 200;
let priceMax = 400;
const onPriceChange = (e) => {
const range = $f7.range.get(e.target);
priceMin = range.value[0];
priceMax = range.value[1];
$update();
};
return $render;
};
</script>