


Perbincangan ringkas tentang peningkatan pelaksanaan kemahiran Sticky component_javascript
Dalam artikel sebelumnyaMenggunakan kaedah getBoundingClientRect untuk melaksanakan komponen melekit mudah memperkenalkan pelaksanaan mudah komponen melekit Selepas memikirkannya sejak dua hari lalu, saya mendapati terdapat lebih banyak pelaksanaan yang disediakan kali terakhir. Kelemahannya ialah kesan yang dicapai pada laman web lain juga agak berbeza apabila menyahbaikan kaedah yang disediakan kali terakhir adalah tidak baik Berdasarkan perkara di atas, artikel ini menyediakan versi yang lebih baik daripada komponen lengkap, saya harap anda berminat untuk membaca.
1. Masalah dengan versi lama
Terdapat pelbagai masalah dalam pelaksanaan komponen melekit sebelumnya:
Pertama, dari segi kesan melekit, sebelum dan selepas elemen melekit dibetulkan, apa yang tidak akan berubah adalah kedudukan berbanding sebelah kiri pelayar dan lebar keseluruhan elemen melekit kedudukan relatif kepada bahagian atas atau bawah pelayar dan ketinggian elemen melekit Dalam pelaksanaan yang disediakan di atas, dua nilai yang berubah-ubah dianggap sebagai nilai tetap. Mengapakah nilai atas atau nilai bawah sentiasa 0 apabila ia ditetapkan? Sudah tentu, ia boleh menjadi selain daripada 0, seperti atas: 20px, bawah: 15px Dalam sesetengah adegan, menambahkan beberapa ofset sedemikian akan menjadikan kesan melekit kelihatan lebih baik, seperti contoh komponen imbuhan yang digunakan dalam dokumentasi rasmi bootstrap (ini. komponen Fungsi ini serupa dengan komponen melekit yang dilaksanakan dalam artikel ini):
Ia menetapkan kedudukan berbanding bahagian atas penyemak imbas ke atas: 20px apabila ditetapkan. Perkara yang sama berlaku untuk ketinggian unsur melekit Untuk memaparkan kesan yang kelihatan lebih baik apabila ditetapkan, ia juga merupakan keperluan yang sangat biasa untuk melaraskan ketinggian Garisan atau padding-top dan atribut lain yang berkaitan dengan ketinggian. halaman Tmall Huabei ini, kandungan Blok ini menggunakan komponen melekit:
Sebelum ditetapkan, ketinggian unsur melekit ialah:
Selepas ditetapkan, ketinggian unsur melekit ialah:
Kedua, apabila membatalkan penetapan, mengambil elemen melekit yang ditetapkan di bahagian atas sebagai contoh, pelaksanaan yang disediakan di atas adalah untuk membatalkan terus kedudukan elemen melekit apabila jarak antara elemen sasaran dan bahagian atas pelayar adalah kurang daripada stickyHeight: atribut tetap, elemen melekat segera dipulihkan kepada aliran dokumen biasa dan kesannya ialah:
Ia hilang serta-merta pada titik kritikal, tetapi kesan Tmall Huabei tidak seperti ini:
Ia tidak hilang serta-merta apabila ia mencapai titik kritikal, tetapi melaraskan semula nilai teratas unsur melekit supaya ia boleh menatal ke atas bersama-sama dengan kandungan utama halaman web bersama-sama dengan bar skrol:
Dari sudut pengalaman, adalah jelas bahawa kesan Tmall Huabei adalah lebih baik Dari sudut fungsi, pelaksanaan yang disediakan di atas mempunyai kelemahan yang membawa maut: apabila ketinggian elemen melekit sangat besar, ia. melebihi keupayaan penyemak imbas Apabila melihat ketinggian kawasan, akan ada pepijat yang tidak kira bagaimana anda menatal, anda tidak boleh menyemak imbas semua kandungan elemen melekit Jika anda berminat, anda boleh mencuba kod yang dilaksanakan kali terakhir bar sisi blog anda. Saya mencuba dan menemui masalah ini, jadi saya ingin memperbaiki komponen melekit: (
Ketiga, pelaksanaan terakhir masih mempunyai beberapa kelemahan:
1) documentElement.clientHeight tidak dicache, menyebabkan ia diperoleh semula setiap kali titik kritikal dinilai:
2) Nilai lalai selang panggil balik skrol adalah terlalu besar dan harus ditetapkan lebih kecil kali ini 5 dan bootstrap menggunakan 1. Hanya dengan cara ini kesannya boleh dijamin lancar
4) Apabila elemen melekit dibetulkan dan tidak dibetulkan, fungsi panggil balik harus disediakan supaya komponen lain boleh melakukan perkara pada titik penting apabila ia bergantung pada komponen ini.
2. Bagaimana untuk menambah baik
Pilihan komponen telah ditakrifkan semula:
var DEFAULTS = { target: '', //target元素的jq选择器 type: 'top', //固定的位置,top | bottom,默认为top,表示固定在顶部 wait: 5, //scroll事件回调的间隔 stickyOffset: 0, //固定时距离浏览器可视区顶部或底部的偏移,用来设置top跟bottom属性的值,默认为0 isFixedWidth: true, //sticky元素宽度是否固定,默认为true,如果是自适应的宽度,需设置为false getStickyWidth: undefined, //用来获取sticky元素宽度的回调,在不传该参数的情况下,stickyWidth将设置为sticky元素的offsetWidth unStickyDistance: undefined, //该参数决定sticky元素何时进入dynamicSticky状态 onSticky: undefined, ///sticky元素固定时的回调 onUnSticky: undefined ///sticky元素取消固定时的回调 };
Yang dalam huruf tebal adalah baharu atau diubah suai Ketinggian asal telah dialih keluar dan digantikan dengan unStickyDistance. Apabila membetulkan, kedudukan relatif kepada bahagian atas atau bawah penyemak imbas ditentukan dengan stickyOffset, supaya tidak perlu menulis nilai atribut atas atau bawah dalam css .sticky--in-top atau .sticky--in -bawah. Jika isFixedWidth palsu, panggilan balik untuk menyegarkan lebar elemen melekit semasa mengubah saiz akan ditambah:
!opts.isFixedWidth && $win.resize(throttle(function () { setStickyWidth(); $elem.hasClass(className) && $elem.css('width', stickyWidth); sticky(); }, opts.wait));
Berbanding dengan kali terakhir, masalah dalam pelaksanaan ini ialah pemprosesan logik apabila membatalkan penetapan Kali terakhir, elemen melekit hanya mempunyai dua keadaan, melekit atau tidak melekit staticSticky dan dynamicSticky yang pertama Ia mewakili keadaan melekit di mana nilai atas atau bawah kekal tidak berubah Untuk menyelesaikan masalah ini dengan lebih jelas, pertimbangan asal ialah Titik kritikal dan kod yang melakukan pemprosesan yang berbeza pada titik kritikal yang berbeza distruktur semula kepada yang berikut:
setSticky = function () { !$elem.hasClass(className) && $elem.addClass(className).css('width', stickyWidth) && (typeof opts.onSticky == 'function' && opts.onSticky($elem, $target)); return true; }, states = { staticSticky: function () { setSticky() && $elem.css(opts.type, opts.stickyOffset); }, dynamicSticky: function (rect) { setSticky() && $elem.css(opts.type, rules[opts.type].getDynamicOffset(rect)); }, unSticky: function () { $elem.hasClass(className) && $elem.removeClass(className).css('width', '').css(opts.type, '') && (typeof opts.onUnSticky == 'function' && opts.onUnSticky($elem, $target)); } }, rules = { top: { getState: function (rect) { if (rect.top < 0 && (rect.bottom - unStickyDistance) > 0) return 'staticSticky'; else if ((rect.bottom - unStickyDistance) <= 0 && rect.bottom > 0) return 'dynamicSticky'; else return 'unSticky'; }, getDynamicOffset: function (rect) { return -(unStickyDistance - rect.bottom); } }, bottom: { getState: function (rect) { if (rect.bottom > docClientHeight && (rect.top + unStickyDistance) < docClientHeight) return 'staticSticky'; else if ((rect.top + unStickyDistance) >= docClientHeight && rect.top < docClientHeight) return 'dynamicSticky'; else return 'unSticky'; }, getDynamicOffset: function (rect) { return -(unStickyDistance + rect.top - docClientHeight); } } } $win.scroll(throttle(sticky, opts.wait)); function sticky() { var rect = $target[0].getBoundingClientRect(), curState = rules[opts.type].getState(rect); states[curState](rect); }
Terdapat sedikit idea model keadaan di dalamnya, tetapi ia lebih ringkas. Apabila saya menulis kod ini, saya benar-benar mahu menggunakan mesin negeri yang telah saya pelajari sebelum ini tunggu suatu hari nanti. Cuba lagi apabila anda ingin berlatih mesin negeri.
Pelaksanaan keseluruhan adalah seperti berikut:
var Sticky = (function ($) { function throttle(func, wait) { var timer = null; return function () { var self = this, args = arguments; if (timer) clearTimeout(timer); timer = setTimeout(function () { return typeof func === 'function' && func.apply(self, args); }, wait); } } var DEFAULTS = { target: '', //target元素的jq选择器 type: 'top', //固定的位置,top | bottom,默认为top,表示固定在顶部 wait: 5, //scroll事件回调的间隔 stickyOffset: 0, //固定时距离浏览器可视区顶部或底部的偏移,用来设置top跟bottom属性的值,默认为0 isFixedWidth: true, //sticky元素宽度是否固定,默认为true,如果是自适应的宽度,需设置为false getStickyWidth: undefined, //用来获取sticky元素宽度的回调,在不传该参数的情况下,stickyWidth将设置为sticky元素的offsetWidth unStickyDistance: undefined, //该参数决定sticky元素何时进入dynamicSticky状态 onSticky: undefined, ///sticky元素固定时的回调 onUnSticky: undefined ///sticky元素取消固定时的回调 }; return function (elem, opts) { var $elem = $(elem); opts = $.extend({}, DEFAULTS, opts || {}, $elem.data() || {}); var $target = $(opts.target); if (!$elem.length || !$target.length) return; var stickyWidth, setStickyWidth = function () { stickyWidth = typeof opts.getStickyWidth === 'function' && opts.getStickyWidth($elem) || $elem[0].offsetWidth; }, docClientHeight = document.documentElement.clientHeight, unStickyDistance = opts.unStickyDistance || $elem[0].offsetHeight, setSticky = function () { !$elem.hasClass(className) && $elem.addClass(className).css('width', stickyWidth) && (typeof opts.onSticky == 'function' && opts.onSticky($elem, $target)); return true; }, states = { staticSticky: function () { setSticky() && $elem.css(opts.type, opts.stickyOffset); }, dynamicSticky: function (rect) { setSticky() && $elem.css(opts.type, rules[opts.type].getDynamicOffset(rect)); }, unSticky: function () { $elem.hasClass(className) && $elem.removeClass(className).css('width', '').css(opts.type, '') && (typeof opts.onUnSticky == 'function' && opts.onUnSticky($elem, $target)); } }, rules = { top: { getState: function (rect) { if (rect.top < 0 && (rect.bottom - unStickyDistance) > 0) return 'staticSticky'; else if ((rect.bottom - unStickyDistance) <= 0 && rect.bottom > 0) return 'dynamicSticky'; else return 'unSticky'; }, getDynamicOffset: function (rect) { return -(unStickyDistance - rect.bottom); } }, bottom: { getState: function (rect) { if (rect.bottom > docClientHeight && (rect.top + unStickyDistance) < docClientHeight) return 'staticSticky'; else if ((rect.top + unStickyDistance) >= docClientHeight && rect.top < docClientHeight) return 'dynamicSticky'; else return 'unSticky'; }, getDynamicOffset: function (rect) { return -(unStickyDistance + rect.top - docClientHeight); } } }, className = 'sticky--in-' + opts.type, $win = $(window); setStickyWidth(); $win.scroll(throttle(sticky, opts.wait)); !opts.isFixedWidth && $win.resize(throttle(function () { setStickyWidth(); $elem.hasClass(className) && $elem.css('width', stickyWidth); sticky(); }, opts.wait)); $win.resize(throttle(function () { docClientHeight = document.documentElement.clientHeight; }, opts.wait)); function sticky() { var rect = $target[0].getBoundingClientRect(), curState = rules[opts.type].getState(rect); states[curState](rect); } } })(jQuery);
Apa yang sukar difahami mungkin logik kaedah getState Beberapa idea dalam bahagian ini dijelaskan dengan lebih terperinci dalam blog sebelum ini.
3. Arahan aplikasi bar sisi blog
Mula-mula, anda mesti menampal pelaksanaan ini ke dalam medan teks html pengaki blog, dan kemudian tambah kod berikut untuk memulakan:
var timer = setInterval(function(){ if($('#blogCalendar').length && $('#profile_block').length && $('#sidebar_search').length) { new Sticky('#sideBar', { target: '#main', onSticky: function($elem, $target){ $target.css('min-height',$elem.outerHeight()); $elem.css('left', '65px'); }, onUnSticky: function($elem, $target){ $target.css('min-height',''); $elem.css('left', ''); } }); } },100);
Pemasa digunakan kerana kandungan bar sisi dimuatkan oleh ajax, dan adalah mustahil untuk menambah panggilan balik semasa permintaan ajax ini Anda hanya boleh menilai sama ada bar sisi dimuatkan melalui kandungan yang dikembalikan.
4. Ringkasan
Hujung minggu ini saya berfikir tentang bagaimana untuk menambah baik komponen melekit, saya menghabiskan hampir sepanjang hari menulis artikel ini masa. Terasa pelik, seperti ada yang kurang, tetapi ternyata kerana masih banyak perkara yang hilang. Pada masa ini, komponen ini hanya boleh mencapai kesan pembetulan dan pembetulan Untuk kerja sebenar, kesan tahap ini mungkin tidak mencukupi. Seterusnya Artikel ini akan memperkenalkan komponen melekit berdasarkan artikel ini, cara melaksanakan komponen navScrollSticky dan tabSticky, jadi nantikan.
Terima kasih kerana membaca :)
Penjelasan tambahan:
Dalam IE dan Firefox, apabila menyegarkan halaman, jika halaman menatal sebelum menyegarkan, operasi penyegaran akan menetapkan kedudukan tatal halaman ke kedudukan penyegaran, tetapi acara tatal tidak akan dicetuskan, jadi ia mesti dipanggil serta-merta selepas komponen dimulakan Fungsi melekit:

Ya, teras enjin JavaScript ditulis dalam C. 1) Bahasa C menyediakan prestasi yang efisien dan kawalan asas, yang sesuai untuk pembangunan enjin JavaScript. 2) Mengambil enjin V8 sebagai contoh, terasnya ditulis dalam C, menggabungkan kecekapan dan ciri-ciri berorientasikan objek C. 3) Prinsip kerja enjin JavaScript termasuk parsing, penyusun dan pelaksanaan, dan bahasa C memainkan peranan penting dalam proses ini.

JavaScript adalah di tengah -tengah laman web moden kerana ia meningkatkan interaktiviti dan dinamik laman web. 1) Ia membolehkan untuk menukar kandungan tanpa menyegarkan halaman, 2) memanipulasi laman web melalui Domapi, 3) menyokong kesan interaktif kompleks seperti animasi dan drag-and-drop, 4) mengoptimumkan prestasi dan amalan terbaik untuk meningkatkan pengalaman pengguna.

C dan JavaScript mencapai interoperabilitas melalui webassembly. 1) Kod C disusun ke dalam modul WebAssembly dan diperkenalkan ke dalam persekitaran JavaScript untuk meningkatkan kuasa pengkomputeran. 2) Dalam pembangunan permainan, C mengendalikan enjin fizik dan rendering grafik, dan JavaScript bertanggungjawab untuk logik permainan dan antara muka pengguna.

JavaScript digunakan secara meluas di laman web, aplikasi mudah alih, aplikasi desktop dan pengaturcaraan sisi pelayan. 1) Dalam pembangunan laman web, JavaScript mengendalikan DOM bersama -sama dengan HTML dan CSS untuk mencapai kesan dinamik dan menyokong rangka kerja seperti JQuery dan React. 2) Melalui reaktnatif dan ionik, JavaScript digunakan untuk membangunkan aplikasi mudah alih rentas platform. 3) Rangka kerja elektron membolehkan JavaScript membina aplikasi desktop. 4) Node.js membolehkan JavaScript berjalan di sisi pelayan dan menyokong permintaan serentak yang tinggi.

Python lebih sesuai untuk sains data dan automasi, manakala JavaScript lebih sesuai untuk pembangunan front-end dan penuh. 1. Python berfungsi dengan baik dalam sains data dan pembelajaran mesin, menggunakan perpustakaan seperti numpy dan panda untuk pemprosesan data dan pemodelan. 2. Python adalah ringkas dan cekap dalam automasi dan skrip. 3. JavaScript sangat diperlukan dalam pembangunan front-end dan digunakan untuk membina laman web dinamik dan aplikasi satu halaman. 4. JavaScript memainkan peranan dalam pembangunan back-end melalui Node.js dan menyokong pembangunan stack penuh.

C dan C memainkan peranan penting dalam enjin JavaScript, terutamanya digunakan untuk melaksanakan jurubahasa dan penyusun JIT. 1) C digunakan untuk menghuraikan kod sumber JavaScript dan menghasilkan pokok sintaks abstrak. 2) C bertanggungjawab untuk menjana dan melaksanakan bytecode. 3) C melaksanakan pengkompil JIT, mengoptimumkan dan menyusun kod hot-spot semasa runtime, dan dengan ketara meningkatkan kecekapan pelaksanaan JavaScript.

Aplikasi JavaScript di dunia nyata termasuk pembangunan depan dan back-end. 1) Memaparkan aplikasi front-end dengan membina aplikasi senarai TODO, yang melibatkan operasi DOM dan pemprosesan acara. 2) Membina Restfulapi melalui Node.js dan menyatakan untuk menunjukkan aplikasi back-end.

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

SecLists
SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

SublimeText3 versi Inggeris
Disyorkan: Versi Win, menyokong gesaan kod!

Muat turun versi mac editor Atom
Editor sumber terbuka yang paling popular

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa
