Kemas kini keadaan komponen apabila pilihan perlu memastikan kawalan, teks dan tingkah laku kekal selaras. Gantikan CSS apabila hanya persembahan yang berubah. Panduan ini menggunakan pratonton jubin setempat dalam Safari pada Mac untuk menunjukkan cara memilih dan mengesahkan kedua-dua pendekatan.

Tugas pembaca adalah khusus: ubah suai halaman web kecil yang anda karang supaya kawalan bentuknya kekal disegerakkan, sementara gayaan hiasannya mudah diedit. Di sini, keadaan komponen bermaksud objek JavaScript yang diurus oleh fungsi kemas kini halaman itu sendiri. Tiada rangka kerja atau ciri penyuntingan khusus produk yang diandaikan.

Perubahan manakah patut diletakkan dalam keadaan komponen?

Mulakan dengan bertanya perkara yang mesti selaras selepas perubahan. Jika memilih jubin bulat mesti mengemas kini kotak pilihan, pratonton dan perihalan bertulis, tetapkan satu pemilik bagi pilihan itu dalam keadaan. Kemudian terbitkan ketiga-tiga output daripadanya. Ini ialah saranan pelaksanaan: ia menjadikan hubungan antara pilihan dengan hasil paparannya jelas.

Sifat tersuai CSS seperti --tile-size mempunyai fungsi yang berbeza. Sifat ini membekalkan nilai kepada pengisytiharan yang merujuknya dengan var(). Sifat tersuai mengambil bahagian dalam lata dan biasanya diwarisi; tingkah lakunya mengikut peraturan CSS walaupun JavaScript menetapkannya. Spesifikasi CSS Custom Properties mentakrifkan kontrak ini.

Gunakan panduan keputusan ini sebelum mengedit:

Perubahan yang diminta Pemilik pilihan Sebab dalam contoh ini
Pembaca memilih jubin bulat atau segi empat sama Keadaan komponen Kotak pilihan, perihalan dan bentuk mesti selaras
Pembaca memilih saiz jubin Keadaan komponen, dipaparkan ke dalam CSS Kawalan julat, perihalan dan dimensi berkongsi satu nilai
Semua jubin patut menggunakan warna hiasan yang berbeza Pengisytiharan helaian gaya Tiada nilai pilihan atau teks yang perlu dikemas kini
Pratonton memerlukan lebih banyak ruang di sekelilingnya Pengisytiharan helaian gaya Ini mengubah reka letak di sekeliling jubin
Dimensi sementara diperlukan semasa pemeriksaan Penggantian CSS setempat Ini eksperimen visual yang perlu dibuang selepas itu

Perbezaan ini bergantung pada tugas. Dalam pratonton ini, warna diletakkan dalam CSS kerana ia hiasan tetap. Jika anda kemudian menambah pemilih warna dan perihalan warna yang dipilih, anggap pilihan itu sebagai keadaan dan paparkan kesan visualnya. Elakkan mewujudkan dua nilai yang boleh diedit secara berasingan bagi pilihan yang sama.

Kawalan natif juga mempunyai keadaannya sendiri. Untuk kotak pilihan, baca sifat semasanya checked. Atribut HTML checked menetapkan keadaan tanda pilihan lalai dan tidak menjejaki perubahan pengguna selepas itu. Perbezaan ini didokumenkan dalam rujukan sifat kotak pilihan MDN.

Bina satu pratonton kendiri pada Mac anda

Gunakan penyunting kod teks biasa untuk menyimpan dokumen lengkap berikut sebagai tile-preview.html, kemudian bukanya dalam Safari. Kekalkan sambungan .html. Contoh ini mengandungi CSS dan JavaScriptnya sendiri, menggunakan fon sistem dan melukis jubin geometri ringkas tanpa aset luaran.

Helaian gaya terletak dalam bahagian kepala dokumen. HTML mentakrifkan elemen style sebagai cara untuk membenamkan CSS, dan membezakan gaya dalaman kendiri daripada helaian gaya yang merujuk sumber tambahan. Dengan menjadikan contoh ini kendiri, input gayanya dapat dinyatakan dengan jelas. Lihat bahagian gaya dan skrip dalam Standard HTML.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Tile preview</title>
  <style>
    body {
      font-family: system-ui, sans-serif;
      margin: 2rem;
      color: #222;
      background: #fff;
    }
    label { display: block; margin-block: 1rem; }
    .preview { padding: 24px; background: #eee; }
    .tile {
      width: 80px;
      height: 80px;
      border-radius: 0;
      width: var(--tile-size, 80px);
      height: var(--tile-size, 80px);
      border-radius: var(--tile-radius, 0);
      background-color: #547899;
    }
  </style>
</head>
<body>
  <h1>Tile preview</h1>
  <label>
    <input id="round" type="checkbox"> Round tile
  </label>
  <label>
    Tile size
    <input id="size" type="range" min="40" max="160"
           step="1" value="80">
  </label>
  <button id="reset" type="button">Reset choices</button>
  <p id="summary"></p>
  <div class="preview">
    <div id="tile" class="tile" aria-hidden="true"></div>
  </div>
  <script>
    const state = { rounded: false, size: 80 };
    const round = document.getElementById('round');
    const size = document.getElementById('size');
    const summary = document.getElementById('summary');
    const tile = document.getElementById('tile');
    const reset = document.getElementById('reset');

    function render() {
      round.checked = state.rounded;
      size.value = String(state.size);
      tile.style.setProperty('--tile-size', `${state.size}px`);
      tile.style.setProperty('--tile-radius', state.rounded ? '50%' : '0');
      summary.textContent = `Tile A: ${state.rounded ? 'round' : 'square'}, ${state.size}px.`;
    }

    function update(patch) {
      const next = { ...state, ...patch };
      if (typeof next.rounded !== 'boolean' ||
          !Number.isInteger(next.size) ||
          next.size < 40 || next.size > 160) {
        throw new RangeError('Use a boolean and a size from 40 to 160.');
      }
      Object.assign(state, next);
      render();
    }

    round.addEventListener('change', () => {
      update({ rounded: round.checked });
    });
    size.addEventListener('input', () => {
      update({ size: Number(size.value) });
    });
    reset.addEventListener('click', () => {
      update({ rounded: false, size: 80 });
    });
    render();
  </script>
</body>
</html>

Antara muka gaya yang digunakan di sini didokumenkan: element.style.setProperty() menulis pengisytiharan sebaris, termasuk sifat tersuai. Nama sifat menggunakan ejaan CSS, seperti --tile-size. Lihat rujukan setProperty MDN.

Cuba pilih Jubin bulat, gerakkan Saiz jubin ke nilai lain, dan pilih Tetapkan semula pilihan. Dua tindakan pertama sepatutnya mengemas kini bentuk serta perihalan; tetapan semula sepatutnya memulihkan segi empat sama berukuran 80 piksel. Dalam program ini, menetapkan medan dalam state sahaja tidak memanggil render(). Salurkan perubahan melalui update() supaya pengesahan dan pemaparan berlaku bersama.

Logik kemas kini dan pemaparan disemak dalam Node menggunakan kawalan olok-olok dan objek gaya olok-olok untuk nilai awal, nilai yang berubah, saiz tidak sah dan tetapan semula. Semakan itu berjaya; namun, semakan tersebut tidak membuktikan pemaparan dalam pelayar. Gunakan semakan visual di atas untuk mengesahkan fail dalam Safari.

Bilakah anda patut menggantikan pengisytiharan CSS?

Untuk perubahan hiasan yang berkekalan, edit helaian gaya yang disimpan. Contohnya, tukar background-color milik .tile kepada warna CSS yang lain, atau laraskan pelapik .preview. Kedua-dua perubahan ini tidak memerlukan medan keadaan baharu dalam program ini kerana kedua-duanya tidak mewakili pilihan yang dibuat.

Untuk eksperimen sementara, aktifkan pemeriksa Safari melalui Safari → Settings… → Advanced → Show features for web developers. Buka Develop → Show Web Inspector, atau tekan Option-Command-I. Ini ialah langkah Mac yang didokumenkan dalam panduan pemeriksa WebKit.

Dengan contoh dibuka, cebisan konsol lengkap berikut mengubah warna jubin buat sementara waktu, kemudian menyediakan fungsi untuk membuang penggantian itu:

const previewTile = document.getElementById('tile');
if (!previewTile) throw new Error('Open tile-preview.html first.');
previewTile.style.setProperty('background-color', '#8069a6');
function restoreTileColor() {
  previewTile.style.removeProperty('background-color');
}
// Run restoreTileColor() when finished comparing colors.

Membuang pengisytiharan sebaris ini membolehkan lata yang selebihnya menentukan warna semula. Ia tidak memadamkan pengisytiharan warna dalam helaian gaya. Kaedah pembuangan ini ditakrifkan dalam rujukan removeProperty MDN. Untuk mengekalkan warna yang dipilih merentas muat semula dalam contoh ini, edit dan simpan sumber CSS.

Jauhkan penggantian sementara daripada nilai yang dimiliki oleh pemapar. Jika anda menukar --tile-size secara manual, perihalan akan tetap melaporkan nilai keadaan, dan panggilan render() yang seterusnya akan menggantikan eksperimen anda. Ubah saiz melalui kawalan atau fungsi kemas kini apabila anda mahu seluruh komponen selaras.

Mengapakah penggantian nampaknya tidak berkesan?

Jejaki laluan nilai itu sebelum meningkatkan kekhususan pemilih. Sesuatu pengisytiharan boleh sah tetapi kalah dalam lata, atau ia mungkin menyasarkan sifat tersuai yang tidak lagi digunakan oleh pengisytiharan yang menang.

  1. Periksa sasaran. Pastikan anda memilih elemen yang memaparkan bentuk itu.
  2. Periksa input. Dalam contoh ini, saiz mestilah integer antara 40 hingga 160. Kemas kini tidak sah akan mencetuskan ralat sebelum keadaan berubah.
  3. Periksa pengguna nilai itu. Dimensi jubin menggunakan var(--tile-size). Pengisytiharan terus width yang menang boleh memintas nilai itu untuk lebar, sementara ketinggian masih menggunakannya.
  4. Periksa keutamaan. Bandingkan pengisytiharan yang terpakai, kepentingan, lapisan dan kekhususan.
  5. Periksa interaksi seterusnya. Jika perubahan itu hilang selepas menggerakkan kawalan, periksa perkara yang ditulis oleh render().

Pengisytiharan sebaris biasa mengatasi peraturan helaian gaya pengarang biasa. Walau bagaimanapun, kepentingan, animasi dan peralihan mempengaruhi turutan yang lebih luas. Pengisytiharan yang muncul kemudian tidak semestinya menang, dan pemilih yang lebih khusus tidak dapat menyelesaikan semua konflik. Panduan lata MDN mendokumenkan syarat-syarat ini.

Bezakan juga nilai sebaris daripada nilai yang diselesaikan. element.style memaparkan penggayaan sebaris, jadi nilai sebaris yang kosong tidak bermaksud elemen itu tiada gaya. getComputedStyle() membaca nilai yang diselesaikan selepas helaian gaya aktif digunakan. Lihat rujukan style MDN dan rujukan getComputedStyle.

Jalankan cebisan diagnostik lengkap ini dalam konsol halaman contoh:

const inspectedTile = document.getElementById('tile');
if (!inspectedTile) throw new Error('Open tile-preview.html first.');
console.table({
  inlineSizeToken: inspectedTile.style.getPropertyValue('--tile-size'),
  inlineWidth: inspectedTile.style.getPropertyValue('width'),
  resolvedWidth: getComputedStyle(inspectedTile).width,
  resolvedHeight: getComputedStyle(inspectedTile).height
});

Sejurus selepas membuka contoh yang belum diubah suai, nilai yang dijangka ialah token saiz sebaris 80px, lebar sebaris yang kosong dan dimensi terselesaikan 80px. Ini menunjukkan cara sifat tersuai sebaris boleh membekalkan nilai kepada pengisytiharan helaian gaya tanpa mewujudkan pengisytiharan sebaris width.

Apakah had pelayar dan sumber yang perlu diketahui?

MDN menandakan sifat tersuai CSS sebagai tersedia secara meluas merentas pelayar sejak April 2017. Itu tidak membuktikan sokongan dalam setiap pelayar yang lebih lama. Contoh ini menyertakan pengisytiharan dimensi biasa sebelum pengisytiharan var() supaya jubin mempunyai penampilan statik apabila sifat tersuai tidak tersedia. Lihat rujukan sifat tersuai MDN.

Pilihan sandaran di dalam var(--tile-size, 80px) tidak menyediakan keserasian dengan pelayar yang tidak dapat mentafsir sifat tersuai. Pilihan itu juga tidak mengesahkan setiap token yang dibekalkan: nilai yang ditakrifkan seperti blue tidak boleh menjadi lebar yang sah semata-mata kerana pilihan sandaran wujud. Had ini diterangkan dalam panduan sifat tersuai MDN.

Jika pelayar sasaran yang lebih lama tidak menyokong sifat tersuai, alternatif yang disokong ialah mengubah pemapar supaya menulis pengisytiharan sebaris biasa width, height dan border-radius dengan setProperty(). Kekalkan pengesahan keadaan dan penyegerakan kawalan yang sama. Ini mengubah kontrak pemaparan, jadi buang penulisan pemapar yang bercanggah dan sahkan pelayar sasaran dan bukannya menganggap sokongannya sama.

Untuk pratonton setempat ini, pilihan praktikalnya jelas: gunakan keadaan untuk pilihan bentuk dan saiz, paparkan pilihan tersebut melalui beberapa input CSS, dan kekalkan hiasan dalam helaian gaya. Selepas sebarang perubahan, uji interaksi kawalan dan tetapan semula. Pratonton, kawalan dan perihalan sepatutnya terus menunjukkan nilai pilihan yang sama.

Sumber