ฉันสร้างปลั๊กอิน One Page Scroll แบบโอเพ่นซอร์สได้อย่างไร

เคล็ดลับของวันนี้เกี่ยวข้องกับเว็บไซต์ของเราอย่างไร เมื่อมองแวบแรกไม่มีอะไร แต่ถ้าบน Mac ของคุณ ส่วนการบูตแคมป์อาศัยอยู่บน Windows คุณอาจสังเกตเห็นแล้วว่า Microsoft ไม่ได้วางแผนและไม่ได้ตั้งใจที่จะเปลี่ยนทิศทางการเลื่อนเมาส์และแทร็กแพด ด้วยเหตุนี้ ปรากฎว่าใน Mac OS X เนื้อหาในหน้าต่างจะเป็นไปตามการเคลื่อนไหวของนิ้วของคุณ (เช่น การเลื่อนแบบย้อนกลับ) และใน Windows คุณจะเลื่อนแถบเลื่อนบนหน้าจอ และเนื้อหาจะเคลื่อนที่ไปใน ทิศทางอื่น

โดยทั่วไป หากคุณไม่สามารถเปลี่ยนจากวิธีหนึ่งไปเป็นการควบคุมเมาส์ไปยังอีกวิธีหนึ่งได้ ก็ถึงเวลาที่ต้องดำเนินการอย่างเด็ดขาด มีสองวิธี (ตัวเลือกด้วย ถอนการติดตั้ง Windowsและโอนไปที่ เครื่องเสมือนเราจะไม่พิจารณา):

  • ปิดการใช้งานการย้อนกลับใน Lion หรือ สิงโตภูเขา - ซึ่งทำได้ในการตั้งค่าระบบในรีโมทคอนโทรล "เมาส์" และ "แทร็กแพด" ตามลำดับ
  • เปิดใช้งานการเลื่อนย้อนกลับใน Windows- น่าแปลกที่มีพารามิเตอร์สำหรับสิ่งนี้ในรีจิสทรีของระบบอย่างไรก็ตามการค้นหาว่าเป็นการผจญภัยที่แยกจากกัน

เนื่องจากเราไม่ได้มองหาวิธีง่ายๆ วันนี้เราจะมาพูดถึงทางเลือกที่สอง - การเปิดใช้งานการเลื่อนแบบย้อนกลับใน Windows

ก่อนอื่นคุณจะต้องเข้าไปก่อน ซึ่งสามารถทำได้ผ่านแผงควบคุม ในตัวจัดการ ให้ดูที่ส่วน “เมาส์และอุปกรณ์ชี้ตำแหน่งอื่นๆ”:

เลือกเมาส์ของคุณจากรายการอุปกรณ์ ดับเบิลคลิก- ไปที่แท็บ "รายละเอียด" ในรายการแบบเลื่อนลงคุณจะต้องมีรายการ "รหัสอุปกรณ์":

ให้ความสนใจกับบรรทัดแรก โดยเริ่มต้นด้วยตัวอักษร VID (เช่น VID_203A&PID_FFFC&REV_0100&MI_01) จำชุดค่าผสมนี้

บนแป้นพิมพ์ กด Command+R พิมพ์ regedit ในหน้าต่างที่เปิดขึ้นแล้วกด Enter ตัวแก้ไขจะเปิดขึ้น รีจิสทรีของ Windows- ทางด้านซ้ายเลือกสาขา HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\HID- คุณจะเห็นรายการเมาส์และแทร็กแพดที่มีป้ายกำกับว่ารวม VID, PID และ MI คุณจะต้องระบุอุปกรณ์ที่คุณกำลังกำหนดค่าที่นี่:

ภายในอุปกรณ์คุณจะพบโฟลเดอร์อีกหลายโฟลเดอร์ ในแต่ละอันคุณจะต้องเข้าไปภายในโฟลเดอร์พารามิเตอร์อุปกรณ์และเปลี่ยนค่าพารามิเตอร์ FlipFlopWheelจาก 0 ถึง 1 หลังจากรีบูตเครื่อง การเลื่อนแบบย้อนกลับจะทำงานใน Windows

  • การแปล

เอฟเฟ็กต์การเลื่อนมีอยู่ในเว็บมานานแล้ว และถึงแม้ว่าจะมีปลั๊กอินให้เลือกมากมาย แต่มีเพียงไม่กี่ปลั๊กอินเท่านั้นที่มีน้ำหนักเบาและความเรียบง่ายตามที่นักออกแบบและนักพัฒนาหลายคนต้องการ ปลั๊กอินส่วนใหญ่ที่ฉันเคยเห็นพยายามทำมากเกินไป ทำให้ยากต่อการรวมไว้ในโปรเจ็กต์ของคุณ

ไม่นานมานี้ Apple ได้เปิดตัว iPhone 5S และไซต์นำเสนอโดยแบ่งหน้าออกเป็นส่วนๆ และแต่ละส่วนจะอธิบายคุณลักษณะอย่างหนึ่งของผลิตภัณฑ์ ฉันคิดว่านี่เป็นวิธีที่ดีในการนำเสนอผลิตภัณฑ์โดยไม่พลาดข้อมูลสำคัญ

ฉันไปหาปลั๊กอินที่เหมาะสม และต้องประหลาดใจมากที่ไม่พบเลย นี่คือวิธีที่ปลั๊กอินการเลื่อนหน้าเกิดขึ้น

ปลั๊กอินเลื่อนหน้า

ปลั๊กอินที่ใช้ jQuery ช่วยให้คุณสร้างเลย์เอาต์สำหรับเพจที่มีหลายส่วนโดยใช้มาร์กอัปขั้นต่ำ

ฉันจะบอกคุณว่ามันถูกสร้างขึ้นอย่างไร ตั้งแต่แนวคิด ไปจนถึงการวางแผน การทดสอบ และการปล่อยโค้ดฟรี

หมายเหตุ: ก่อนที่จะสร้างปลั๊กอิน ฉันทราบอยู่แล้วว่ามีการอภิปรายว่าสคริปต์ควรเปลี่ยนพฤติกรรมการเลื่อนตามธรรมชาติของเบราว์เซอร์หรือไม่ ซึ่งอาจทำให้ผู้ใช้สับสนได้ ดังนั้นฉันจึงพยายามลดผลกระทบด้านลบจากการเปลี่ยนแปลงพฤติกรรมที่เป็นนิสัย ในการตั้งค่าปลั๊กอิน คุณสามารถตั้งค่าขนาดหน้าจอที่ปลั๊กอินจะกลับสู่การเลื่อนหน้าจอปกติได้ ดังนั้นบนอุปกรณ์ที่ใช้พลังงานต่ำ เช่น สมาร์ทโฟนและแท็บเล็ต คุณสามารถรักษาประสิทธิภาพของไซต์ได้ นอกจากนี้ คุณยังสามารถกำหนดระยะเวลาของภาพเคลื่อนไหวได้เมื่อเปลี่ยนระหว่างส่วนต่างๆ

ทั้งหมดนี้เพื่ออะไร?

ดังที่ฉันได้กล่าวไปแล้ว ปลั๊กอินสำเร็จรูปส่วนใหญ่มีปลั๊กอินมากมายรวมอยู่ด้วย ฟังก์ชั่นเสริมซึ่งทำให้บูรณาการได้ยาก ปลั๊กอินนี้ควรเป็น:

ใช้งานง่าย
- ง่ายต่อการบูรณาการ
- ต้องการมาร์กอัปขั้นต่ำ
- ทำหน้าที่เดียว แต่ก็ดี

1. ภาพวาด

ฉันเริ่มวางแผนปลั๊กอินตั้งแต่ทั่วไปไปจนถึงเฉพาะเจาะจง ควรเลื่อนไปตามส่วน ในการดำเนินการนี้ คุณจะต้องปิดการใช้งานการเลื่อนแบบปกติในเบราว์เซอร์ ในขณะที่ให้บริการส่วนต่างๆ ทีละส่วน และเลื่อนหน้าหากจำเป็น

คุณสามารถจินตนาการทุกอย่างในใจหรือวาดภาพร่างได้

แบ่งแนวคิดออกเป็นงานเล็กๆ โดยแก้ไขแต่ละงานตามลำดับ

1. เตรียมเค้าโครงของส่วนต่างๆ
มาปิดการใช้งานการเลื่อนแบบปกติโดยใช้โอเวอร์โฟลว์: ซ่อนอยู่ในเนื้อหา เราจะจัดเรียงส่วนต่างๆ ตามลำดับที่ต้องการ คำนวณ และปรับเปลี่ยน ข้อมูลที่จำเป็นและชั้นเรียน

2. ตั้งค่าทริกเกอร์การเลื่อนแบบแมนนวล
เราจับทริกเกอร์โดยใช้ jQuery กำหนดทิศทางการเลื่อน และย้ายเค้าโครงโดยใช้ CSS

3. มาเพิ่มคุณสมบัติกัน
มาเพิ่มการตอบสนอง การวนซ้ำ การรองรับการเลื่อนบนหน้าจอสัมผัส การแบ่งหน้า ฯลฯ

4. มาตรวจสอบเบราว์เซอร์ต่างๆ กัน
มาตรวจสอบกัน เบราว์เซอร์ Chrome, ซาฟารี, ไฟร์ฟอกซ์, อินเทอร์เน็ตเอ็กซ์พลอเรอร์ 10 และระบบปฏิบัติการยอดนิยม Windows, Mac OS X, iOS และระบบปฏิบัติการ Android 4.0+.

5. มาทำให้ปลั๊กอินพร้อมใช้งานในพื้นที่เก็บข้อมูลกันดีกว่า
มาสร้างพื้นที่เก็บข้อมูลและเขียนคำแนะนำในการใช้ปลั๊กอินกันดีกว่า

6. มาขยายการสนับสนุนกัน
เรามาสำรวจวิธีอื่นๆ ในการเพิ่มการรองรับปลั๊กอินกันดีกว่า

2. การสร้างรากฐาน

หลังจากออกแบบปลั๊กอินแล้ว ฉันก็เริ่มสร้างรากฐานบนเทมเพลตนี้:

Function($) ( var defaults = (sectionContainer: "section", ... ); $.fn.onepage_scroll = function(options) ( var settings = $.extend((), defaults, options); ... ) )($)

เทมเพลตเริ่มต้นด้วย module!function($) ( … )($) ซึ่งวางตัวแปรโกลบอล jQuery ไว้ พื้นที่ท้องถิ่น– ซึ่งจะช่วยลดภาระและป้องกันความขัดแย้งกับไลบรารีอื่น

ตัวแปรเริ่มต้นประกอบด้วยการตั้งค่าเริ่มต้น

$.fn.onepage_scroll เป็นฟังก์ชันหลักที่เริ่มต้นทุกอย่าง หากคุณกำลังสร้างปลั๊กอินของคุณเอง อย่าลืมเขียนชื่ออื่นแทน onepage_scroll

คุณสามารถป้องกันการเลื่อนแบบมาตรฐานได้โดยการกำหนดคุณสมบัติ overflow: Hidden ให้กับแท็ก body
ผ่านชื่อคลาสเฉพาะปลั๊กอิน สิ่งสำคัญคือต้องใช้ชื่อสไตล์ที่ไม่ซ้ำใครเพื่อหลีกเลี่ยงความขัดแย้งกับชื่อที่มีอยู่ ฉันมักจะใช้ตัวย่อจากชื่อของปลั๊กอิน จากนั้นตามด้วยเครื่องหมายขีดคั่นด้วยชื่อของสไตล์ เช่น .onepage-wrapper

วางรากฐานแล้ว มาดูฟังก์ชันแรกกันดีกว่า

3. เตรียมเค้าโครงและจัดเรียงส่วนต่างๆ

ตอนแรกผมไปผิดทาง ฉันคิดว่าฉันจะจัดทุกส่วนตามลำดับและไล่ดูพวกมันแบบวนซ้ำ สิ่งที่ฉันได้รับก่อน:

ส่วน Var = $(settings.sectionContainer); var topPos = 0; $.each(sections, function(i) ( $(this).css(( ตำแหน่ง: "absolute", top: topPos + "%" )).addClass("ops-section").attr("data-index ", i+1); topPos = topPos + 100; ));

การวนซ้ำจะวนซ้ำผ่านตัวเลือกทั้งหมด (sectionContainer ถูกกำหนดไว้ในส่วนตัวแปรเริ่มต้น) กำหนดตำแหน่ง: สัมบูรณ์ และกำหนดตำแหน่งบนสุดที่ถูกต้องให้แต่ละส่วนถัดไป เพื่อไม่ให้ทำงานทับกัน

ตำแหน่งบนสุดจะถูกเก็บไว้ใน topPos เราเริ่มต้นจากศูนย์และเพิ่มในแต่ละรอบ เพื่อให้แต่ละส่วนกินพื้นที่ทั้งหน้า ฉันตั้งค่าความสูงเป็น 100% และเพิ่ม 100 ใน topPos

การพัฒนาและการทดสอบใช้เวลาสองสามชั่วโมง แต่ในขั้นตอนต่อไปฉันก็ตระหนักว่าทั้งหมดนี้ไม่จำเป็น

4. ทริกเกอร์ด้วยตนเองและการแปลงหน้า

คุณคงคิดว่าขั้นตอนต่อไปคือย้ายแต่ละส่วนไปยังตำแหน่งใหม่เมื่อทริกเกอร์การเลื่อนเริ่มทำงาน... แต่มีวิธีที่ดีกว่า แทนที่จะย้ายแต่ละส่วนในลูป ฉันแค่รวมพวกมันทั้งหมดไว้ในคอนเทนเนอร์เดียว และใช้ฟังก์ชัน CSS3 Translate3d เพื่อเลื่อนมัน ฟังก์ชันนี้รองรับเปอร์เซ็นต์ เราสามารถย้ายส่วนต่างๆ เพื่อให้อยู่ในตำแหน่งที่แม่นยำในหน้าต่างโดยไม่ต้องคำนวณทุกอย่างใหม่อีกครั้ง นอกจากนี้ยังทำให้ควบคุมความเร็วและพารามิเตอร์ภาพเคลื่อนไหวอื่นๆ ได้ง่ายขึ้น


วิธีแก้ปัญหาแรกไม่ได้มีประสิทธิภาพสูงสุดเสมอไป ดังนั้นอย่าลืมเผื่อเวลาไว้สำหรับการทดลองด้วย

ตอนนี้สิ่งที่เหลืออยู่คือการกำหนดทิศทางการเลื่อนและย้ายคอนเทนเนอร์ไปในทิศทางที่ต้องการ

ฟังก์ชั่น init_scroll(event, delta) ( var deltaOfInterest = delta, timeNow = new Date().getTime(), quietPeriod = 500; // ยกเลิกการเลื่อนหากกำลังเคลื่อนไหวอยู่หรืออยู่ในช่วงเวลาที่เงียบ ถ้า (timeNow - LastAnimation< quietPeriod + settings.animationTime) { event.preventDefault(); return; } if (deltaOfInterest < 0) { el.moveDown() } else { el.moveUp() } lastAnimation = timeNow; } $(document).bind("mousewheel DOMMouseScroll", function(event) { event.preventDefault(); var delta = event.originalEvent.wheelDelta || -event.originalEvent.detail; init_scroll(event, delta); });

ขั้นแรก เราเชื่อมโยงฟังก์ชันเข้ากับเหตุการณ์ mousewheel (DOMMouseScroll ใน Firefox) จากนั้นเราสามารถดักข้อมูลและกำหนดทิศทางได้ เรารวมมันเข้ากับการประมวลผล init_scroll ซึ่งรับ wheelData สำหรับสิ่งนี้

ใน โลกในอุดมคติการคำนวณการเปลี่ยนแปลงใน wheelData ก็เพียงพอแล้ว อย่างไรก็ตาม เมื่อสร้างภาพเคลื่อนไหวตามลำดับ คุณต้องสร้างการตรวจสอบเพื่อให้แน่ใจว่าเหตุการณ์ทริกเกอร์จะไม่ซ้ำกัน (ไม่เช่นนั้นรูปภาพจะทับซ้อนกันระหว่างภาพเคลื่อนไหว) คุณสามารถใช้ setInterval เพื่อเรียกแต่ละภาพเคลื่อนไหวตามลำดับ แต่สิ่งนี้จะไม่ให้ความแม่นยำและความน่าเชื่อถือเนื่องจาก แต่ละเบราว์เซอร์จะจัดการมันต่างกัน ตัวอย่างเช่น ใน Chrome และ Firefox setInterval จะช้าลงในแท็บที่ไม่ได้ใช้งาน ส่งผลให้ฟังก์ชันทำงานไม่ตรงเวลา ด้วยเหตุนี้ ฉันจึงตัดสินใจใช้ฟังก์ชันที่ส่งคืนเวลาปัจจุบัน

Var timeNow = วันที่ใหม่ ().getTime(), quietPeriod = 500; … ถ้า (timeNow - LastAnimation< quietPeriod + settings.animationTime) { event.preventDefault(); return; } … lastAnimation = timeNow;

ในตัวอย่างนี้ ซึ่งฉันยกมาจากโค้ดก่อนหน้า ฉันกำลังจัดเก็บเวลาปัจจุบันเป็นเวลาตอนนี้ เพื่อที่ฉันจะได้ตรวจสอบในภายหลังว่าแอนิเมชันใช้เวลามากกว่า 500ms หรือไม่ หากไม่ถูกครอบครอง การเปลี่ยนแปลงจะไม่เกิดขึ้นและภาพเคลื่อนไหวจะไม่ทับซ้อนกัน ทำงานร่วมกับ เวลาปัจจุบันเชื่อถือได้มากขึ้นเพราะว่า มันเหมือนกันสำหรับทุกคน

ถ้า (deltaOfInterest< 0) { el.moveDown() } else { el.moveUp() }

ฟังก์ชัน MoveUp และ MoveDown จะเปลี่ยนแอตทริบิวต์เค้าโครงเพื่อให้สะท้อนให้เห็น สถานะปัจจุบันเว็บไซต์. ในตอนท้ายของงานแต่ละคนจะเรียกใช้วิธีการเปลี่ยนแปลงขั้นสุดท้ายเพื่อย้ายส่วนถัดไปไปยังวิวพอร์ต

$.fn.transformPage = function(settings, pos, index) ( … $(this).css(( "-webkit-transform": (settings.direction == "horizontal") ? "translate3d(" + pos + " %, 0, 0)" : "translate3d(0, " + pos + "%, 0)", "-webkit-transition": "all " + settings.animationTime + "ms " + settings.easing, "-moz -transform": (settings.direction == "แนวนอน") ? "translate3d(" + pos + "%, 0, 0)" : "translate3d(0, " + pos + "%, 0)", "-moz -transition": "all " + settings.animationTime + "ms " + settings.easing, "-ms-transform": (settings.direction == "horizontal") ? "translate3d(" + pos + "%, 0, 0)" : "translate3d(0, " + pos + "%, 0)", "-ms-transition": "all " + settings.animationTime + "ms " + settings.easing, "transform": (การตั้งค่า ทิศทาง == "แนวนอน") ? "translate3d(" + pos + "%, 0, 0)" : "translate3d(0, " + pos + "%, 0)", "transition": "all " + settings AnimationTime + "ms" + settings.easing ));

นี่เป็นวิธีการเปลี่ยนแปลงที่เลื่อนส่วนต่างๆ ฉันสร้างมันขึ้นมาใน JavaScript แทนที่จะระบุสไตล์แยกกัน เพื่อให้นักพัฒนามีโอกาสที่จะเปลี่ยนการตั้งค่าในปลั๊กอินเอง (ส่วนใหญ่เป็นความเร็วของแอนิเมชั่นและการเร่งความเร็ว) และไม่ต้องค้นหาไฟล์สไตล์เพื่อค้นหาการตั้งค่า นอกจากนี้ ยังต้องคำนวณเปอร์เซ็นต์การเปลี่ยนแปลงใหม่ ดังนั้นคุณจึงไม่สามารถทำได้หากไม่มี JavaScript

5. คุณสมบัติเพิ่มเติม

ตอนแรกฉันไม่ต้องการเพิ่มอะไร แต่ได้รับการตอบรับมากมายจากชุมชน GitHub ทำให้ฉันตัดสินใจค่อยๆ ปรับปรุงปลั๊กอิน ฉันเปิดตัวเวอร์ชัน 1.2.1 ซึ่งเพิ่มการโทรกลับและการวนซ้ำจำนวนมาก และส่วนที่ยากที่สุดคือการตอบสนอง

ในตอนแรกฉันไม่ได้สร้างปลั๊กอินโดยคำนึงถึงแพลตฟอร์มมือถือ (ซึ่งฉันเสียใจ) แต่เราต้องติดตามและคำนวณเหตุการณ์บนหน้าจอสัมผัสใหม่ให้อยู่ในรูปแบบที่เหมาะสมสำหรับใช้ใน init_scroll สิ่งนี้ทำงานได้ไม่ดีในทุกเบราว์เซอร์ ดังนั้นเราจึงต้องสร้างฟีเจอร์การย้อนกลับโดยที่เบราว์เซอร์จะกลับสู่การเลื่อนตามปกติเมื่อถึงความกว้างของหน้าต่างที่กำหนด

ค่าเริ่มต้นของ Var = (responsiveFallback: false ... ); ฟังก์ชั่นตอบสนอง () ( ถ้า ($(หน้าต่าง).ความกว้าง()< settings.responsiveFallback) { $("body").addClass("disabled-onepage-scroll"); $(document).unbind("mousewheel DOMMouseScroll"); el.swipeEvents().unbind("swipeDown swipeUp"); } else { if($("body").hasClass("disabled-onepage-scroll")) { $("body").removeClass("disabled-onepage-scroll"); $("html, body, .wrapper").animate({ scrollTop: 0 }, "fast"); } el.swipeEvents().bind("swipeDown", function(event) { if (!$("body").hasClass("disabled-onepage-scroll")) event.preventDefault(); el.moveUp(); }).bind("swipeUp", function(event){ if (!$("body").hasClass("disabled-onepage-scroll")) event.preventDefault(); el.moveDown(); }); $(document).bind("mousewheel DOMMouseScroll", function(event) { event.preventDefault(); var delta = event.originalEvent.wheelDelta || -event.originalEvent.detail; init_scroll(event, delta); }); } }

มากำหนดตัวแปรเริ่มต้นกัน เราใช้ responsiveFallback เพื่อพิจารณาว่าเมื่อใดที่ปลั๊กอินควรย้อนกลับ รหัสนี้กำหนดความกว้างของเบราว์เซอร์ ถ้ากว้าง น้อยกว่ามูลค่าจาก responsiveFallback ฟังก์ชันจะลบเหตุการณ์ทั้งหมด ย้ายเพจไปที่จุดเริ่มต้น และให้คุณเลื่อนได้ตามปกติ หากความกว้างเกินค่า ปลั๊กอินจะตรวจสอบการมีอยู่ของคลาสที่ปิดใช้งาน onepage-scroll เพื่อดูว่าได้รับการเตรียมใช้งานหรือไม่ หากไม่เป็นเช่นนั้น ระบบจะเริ่มต้นใหม่อีกครั้ง

โซลูชันนี้ไม่ได้สมบูรณ์แบบ แต่เปิดโอกาสให้นักพัฒนาและนักออกแบบสามารถเลือกวิธีแสดงไซต์ของตนได้ แพลตฟอร์มมือถือแทนที่จะปฏิเสธแพลตฟอร์มเหล่านี้โดยสิ้นเชิง

6. การทดสอบในเบราว์เซอร์ต่างๆ

การทดสอบเป็นส่วนสำคัญของการพัฒนา ก่อนที่จะปล่อยปลั๊กอิน คุณต้องตรวจสอบให้แน่ใจว่าปลั๊กอินใช้งานได้กับเครื่องส่วนใหญ่ ฉันพัฒนาใน Chrome อยู่เสมอ ประการแรก ฉันชอบเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ และประการที่สอง ฉันรู้ว่าหากปลั๊กอินใช้งานได้ใน Chrome ก็มักจะใช้งานได้ใน Safari และ Opera

ฉันมักจะใช้ แมคบุคแอร์เพื่อการพัฒนาและที่บ้านก็มีพีซีไว้ทดสอบ หลังจากที่ปลั๊กอินทำงานใน Chrome ฉันจะทดสอบด้วยตนเองใน Safari, Opera และสุดท้ายคือ Firefox บน Mac OS X จากนั้นจึงทดสอบ Chrome, Firefox และ Internet Explorer 10 บน Windows

นั่นไม่ใช่ทั้งหมด เบราว์เซอร์ที่เป็นไปได้แต่ข้อดีเกี่ยวกับโอเพ่นซอร์สก็คือนักพัฒนารายอื่นจะสามารถทดสอบและแก้ไขข้อผิดพลาดได้ด้วยตนเอง นั่นคือประเด็น คุณไม่จำเป็นต้องสร้างผลิตภัณฑ์ที่สมบูรณ์แบบในทันที แต่ควรตั้งจุดเริ่มต้นไว้ล่วงหน้า

อย่าลืมทดสอบปลั๊กอินของคุณด้วย อุปกรณ์เคลื่อนที่.

เพื่อให้การทดสอบง่ายขึ้น หลังจากเสร็จสิ้นปลั๊กอิน ฉันจึงสร้างหน้าสาธิตเพื่อแสดงความสามารถทั้งหมดและอัปโหลดไปยังไซต์ของฉัน มีข้อผิดพลาดที่ไม่สามารถตรวจพบได้ในเครื่อง แต่จะปรากฏขึ้นเมื่อทำงานบนไซต์จริง เมื่อหน้าสาธิตทำงาน ฉันจะเริ่มทดสอบบนอุปกรณ์มือถือ

7. อัปโหลดปลั๊กอินไปยังโอเพ่นซอร์ส

ขั้นตอนสุดท้ายคือการแชร์ปลั๊กอินบน GitHub ในการดำเนินการนี้ คุณจะต้องสร้างบัญชีที่นั่น กำหนดค่า Git และสร้างพื้นที่เก็บข้อมูลใหม่ แล้วทำการโคลนไปที่ เครื่องท้องถิ่น– สิ่งนี้จะสร้างไดเร็กทอรีพร้อมชื่อของปลั๊กอิน เราคัดลอกปลั๊กอินที่นั่นและตั้งค่าโครงสร้าง

โครงสร้างพื้นที่เก็บข้อมูล

ปรับแต่งได้ตามที่คุณต้องการ ฉันทำสิ่งนี้:

ไดเร็กทอรีสาธิตประกอบด้วยการสาธิตการทำงาน พร้อมด้วยทรัพยากรที่จำเป็นทั้งหมด
- ปลั๊กอินเวอร์ชันปกติและเวอร์ชันบีบอัดอยู่ในรูท
- CSS และทรัพยากรการทดสอบ เช่น รูปภาพ (หากจำเป็น) อยู่ในรูท
- ไฟล์ readme ในรูท

โครงสร้าง Readme

ขั้นตอนสำคัญคือการเขียน คำแนะนำที่ชัดเจนสำหรับชุมชนโอเพ่นซอร์ส ฉันมักจะเขียนมันลงใน readme แต่สำหรับกรณีที่ซับซ้อน อาจจำเป็นต้องมีหน้าวิกิ ฉันจะเขียน readme ได้อย่างไร:

1. บทนำ
ฉันอธิบายวัตถุประสงค์ของปลั๊กอิน จัดเตรียมรูปภาพและลิงก์ไปยังการสาธิต
2. ข้อกำหนดและความเข้ากันได้
เป็นการดีกว่าที่จะย้ายส่วนนี้ให้สูงขึ้นเพื่อให้ชัดเจนทันทีว่าบุคคลนั้นสามารถใช้ปลั๊กอินได้หรือไม่
3. หลักการใช้งานเบื้องต้น
คำแนะนำทีละขั้นตอนเริ่มต้นจาก การเชื่อมต่อ jQueryที่ลงท้ายด้วยมาร์กอัป HTML และการเรียกใช้ฟังก์ชัน มีการอธิบายการตั้งค่าด้วย
4. การใช้งานขั้นสูง
คำแนะนำที่ซับซ้อนยิ่งขึ้น - วิธีการสาธารณะการโทรกลับและข้อมูลที่เป็นประโยชน์อื่น ๆ
5. ทรัพยากรอื่นๆ
ลิงก์ไปยังบทช่วยสอน ขอบคุณ ฯลฯ

8 การขยายการสนับสนุน

โดยทั่วไป มันสามารถทำได้โดยไม่ต้องใช้ jQuery แต่ฉันรีบที่จะทำให้เป็นโอเพ่นซอร์ส ดังนั้นฉันจึงตัดสินใจลดเวลาในการพัฒนาและพึ่งพาฟังก์ชันสำเร็จรูปใน jQuery

แต่เพื่อล้างมโนธรรมของฉัน ฉันจึงปรับปรุงปลั๊กอินใหม่ใน JavaScript ล้วนๆ (มีเวอร์ชันที่รองรับ Zepto ด้วย) ด้วย JS ล้วนๆ ไม่จำเป็นต้องรวม jQuery ทุกอย่างใช้งานได้ทันที

เพื่อเป็นการแก้ไข และเฉพาะสำหรับผู้อ่านนิตยสาร Smashing Magazine ฉันได้สร้าง One Page Scroll ขึ้นมาใหม่โดยใช้ JavaScript ล้วนๆ (มีเวอร์ชัน Zepto ให้เลือกด้วย) ด้วยเวอร์ชัน JavaScript ล้วนๆ คุณไม่จำเป็นต้องรวม jQuery อีกต่อไป ปลั๊กอินทำงานได้ทันทีที่แกะกล่อง

เวอร์ชัน Pure JS และ Zepto

การทำงานปลั๊กอินใหม่เป็น จาวาสคริปต์บริสุทธิ์

การประมวลผลดังกล่าวอาจดูเหมือนเป็นงานที่ยาก แต่นี่เป็นเพียงช่วงแรกเท่านั้น สิ่งที่ยากที่สุดคือการไม่ทำผิดพลาดกับคณิตศาสตร์ เพราะ ฉันทำไปแล้วการพัฒนา ฟังก์ชั่นเสริมฉันใช้เวลาเพียงไม่กี่ชั่วโมงในการกำจัด jQuery

ปลั๊กอินนี้ใช้ CSS3 ดังนั้นเราจึงจำเป็นต้องแทนที่การเรียก jQuery ด้วยการโทรที่คล้ายกันของเราเอง ในเวลาเดียวกัน ฉันได้จัดโครงสร้างของสคริปต์ใหม่:

ค่าตัวแปรเริ่มต้น
ทุกอย่างเหมือนกับใน รุ่นก่อนหน้า
- ฟังก์ชั่นการเริ่มต้น
จัดเตรียมและจัดเรียงเค้าโครงและการเริ่มต้นของสิ่งที่เกิดขึ้นเมื่อมีการเรียกใช้ฟังก์ชัน onePageScroll นี่คือที่ขั้นตอนทั้งหมดที่กำหนดชื่อคลาส คุณลักษณะ และรูปแบบการวางตำแหน่ง
- วิธีการส่วนตัว
ทั้งหมด วิธีการภายในปลั๊กอิน - เหตุการณ์การเลื่อน การแปลงหน้า การย้อนกลับแบบปรับได้ และการติดตามการเลื่อน
- วิธีการสาธารณะ
วิธีการทั้งหมดสำหรับนักพัฒนา: moveDown(), moveUp() และ moveTo()
- วิธีการช่วยเหลือ
สิ่งใดก็ตามที่แทนที่การโทร jQuery

คู่รักคู่หนึ่งได้พบกัน ช่วงเวลาที่ไม่พึงประสงค์- แยกฟังก์ชันเพียงเพื่อเพิ่มหรือลบชื่อสไตล์ หรือใช้ document.querySelector แทน $ แต่สุดท้ายแล้ว เราก็ได้ปลั๊กอินที่มีโครงสร้างดีกว่า

การสร้างปลั๊กอินใหม่สำหรับ Zepto

ฉันตัดสินใจสนับสนุน Zepto แม้ว่าจะมีจุดประสงค์เพื่อประโยชน์สูงสุดเท่านั้นก็ตาม เบราว์เซอร์ที่ทันสมัย(IE10+) เพราะ มันทำงานเร็วและมีประสิทธิภาพมากกว่า jQuery 2.0+ ในขณะที่มี API ที่ยืดหยุ่นมากกว่า Zpeto มีขนาดเล็กกว่า jQuery ถึง 4 เท่า ซึ่งส่งผลต่อความเร็วในการโหลดหน้าเว็บ เนื่องจากผู้คนที่ใช้สมาร์ทโฟนบ่อยขึ้น Zepto จึงกลายเป็นทางเลือกที่ดีกว่า

การแปลงปลั๊กอินจาก jQuery เป็น Zepto นั้นง่ายกว่าเนื่องจากมี API ที่คล้ายกัน เกือบทุกอย่างเหมือนกัน ยกเว้นส่วนของแอนิเมชั่น เนื่องจากฟังก์ชัน $.fn.animate() ของ Zepto มีการรองรับภาพเคลื่อนไหว CSS3 และการสนับสนุนการเรียกกลับ AnimationEnd ส่วนต่อไปนี้:

$(นี้).css(( "-webkit-transform": "translate3d(0, " + pos + "%, 0)", "-webkit-transition": "-webkit-transform " + settings.animationTime + " ms " + settings.easing, "-moz-transform": "translate3d(0, " + pos + "%, 0)", "-moz-transition": "-moz-transform" + settings.animationTime + "ms " + settings.easing, "-ms-transform": "translate3d(0, " + pos + "%, 0)", "-ms-transition": "-ms-transform" + settings.animationTime + "ms " + settings.easing, "transform": "translate3d(0, " + pos + "%, 0)", "transition": "transform" + settings.animationTime + "ms " + settings.easing )); $(this).one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend", function(e) ( if (typeof settings.afterMove == "function") settings.afterMove(index, next_el); ));

สามารถแทนที่ด้วยรหัสนี้:

$(this).animate(( Translate3d: "0, " + pos + "%, 0" ), settings.animationTime, settings.easing, function() ( if (typeof settings.afterMove == "function") การตั้งค่า afterMove(ดัชนี, next_el )); -

Zepto ช่วยให้คุณสร้างแอนิเมชั่นโดยไม่ต้องกำหนดสไตล์ทั้งหมดหรือกำหนดการโทรกลับด้วยตัวเอง

และทำไมต้องกังวลกับเรื่องนี้?

เมื่อมีคนใช้ jQuery มากขึ้น มันก็จะซับซ้อนมากขึ้นและบางครั้งก็ช้าลงด้วย หากคุณรองรับเฟรมเวิร์กอื่นๆ ปลั๊กอินของคุณจะได้รับความนิยมมากขึ้น
การออกแบบใหม่ตั้งแต่ต้นจะช่วยให้คุณสร้างปลั๊กอินได้ดีขึ้นในอนาคต jQuery และไลบรารีอื่นๆ สามารถให้อภัยข้อผิดพลาดเล็กๆ น้อยๆ เช่น เครื่องหมายจุลภาคหายไป ดังนั้น คุณจึงไม่สนใจเกี่ยวกับคุณภาพของงานของคุณมากนัก หากปราศจากการใช้ JavaScript ล้วนๆ เหล่านี้ ฉันก็จะรู้สึกดีขึ้นว่าปลั๊กอินของฉันทำงานอย่างไร อะไรทำงาน อะไรส่งผลต่อประสิทธิภาพ และอะไรสามารถปรับปรุงได้

แม้ว่าไลบรารีเช่น jQuery จะทำให้ชีวิตของเราง่ายขึ้น แต่การใช้ไลบรารีเหล่านั้นก็ไม่ใช่สิ่งที่ดีที่สุด วิธีการที่มีประสิทธิภาพบรรลุเป้าหมาย ปลั๊กอินบางตัวสามารถทำได้

บทสรุป.

นี่คือกระบวนการทั้งหมดในการสร้างปลั๊กอิน One Page Scroll มีข้อผิดพลาด แต่ฉันเรียนรู้จากสิ่งเหล่านั้นเมื่อการพัฒนาก้าวหน้า หากฉันกำลังพัฒนามันในวันนี้ ฉันจะมุ่งเน้นไปที่อุปกรณ์มือถือและเพิ่มความคิดเห็นเพิ่มเติมให้กับโค้ด

หากไม่มีการสนับสนุนจากชุมชนเช่น GitHub, StackOverflow และ Smashing Magazine ฉันคงไม่สามารถสร้างปลั๊กอินได้เร็วขนาดนี้ ชุมชนเหล่านี้ช่วยฉันได้มากในการทำงาน ซึ่งเป็นเหตุผลว่าทำไมฉันถึงทำให้ทุกคนสามารถใช้ปลั๊กอินได้ฟรี นี่คือวิธีการตอบแทนการสนับสนุนที่ยอดเยี่ยมของฉัน

ในบทความสั้น ๆ นี้ ฉันต้องการแสดงวิธีการกำหนดทิศทางการเลื่อนของล้อเมาส์ ขอบเขตของการสมัครอาจไม่กว้างขวางนัก แต่ตัวฉันเองเจอมากกว่าหนึ่งครั้งเมื่อจำเป็น ตัวอย่างเช่น ในการสร้าง "เอฟเฟกต์พารัลแลกซ์" โดยที่หน้าเว็บไม่จำเป็นต้องเลื่อน และเอฟเฟกต์จะเกิดขึ้นขึ้นอยู่กับว่าผู้ใช้หมุนวงล้อของเมาส์หรือไม่และไปในทิศทางใด เป็นไปได้ว่าคุณจะพบแอปพลิเคชันในโครงการของคุณ หากไม่ใช่ตอนนี้ก็ในอนาคต

ฟังก์ชัน addEvent(elem, type, handler)( if(elem.addEventListener)( elem.addEventListener(type, handler, false); ) else ( elem.attachEvent("on"+type, handler); ) ส่งคืน false; ) ฟังก์ชัน scrollDirection())( var weelEvt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel", el = document.body; addEvent(el, weelEvt, function(e)( var evt = e .OriginalEvent ? e.OriginalEvent: e, delta = evt.detail ? evt.detail*(-40) : evt.wheelDelta console.log("เลื่อน " + (เดลต้า > 0 ? "ขึ้น" : "ลง") ; )); ) // วางสายตัวจัดการเหตุการณ์การโหลดเอกสาร - DOM-Ready addEvent(window, "load", scrollDirection); // สำหรับ jQuery - เพียงเรียกใช้ฟังก์ชันหลังจากโหลด DOM แล้ว /*$(function())( scrollDirection(); ));*/

ฉันไม่เห็นประเด็นในการอธิบายอะไรเป็นพิเศษ สิ่งเดียวที่คุณสามารถสังเกตได้ด้วยตัวเองก็คือว่าใน ในกรณีนี้ FireFox "สร้างความโดดเด่น" ด้วยเหตุการณ์ "DOMMousScroll" ที่ไม่ได้มาตรฐาน
เพื่อความเข้าใจและการรับรู้ที่ดีขึ้น ฉันตัดสินใจยกตัวอย่างขึ้นมาหนึ่งตัวอย่าง โดยเราถือว่าภารกิจต่อไปนี้: เมื่อผู้ใช้แต่ละคนเลื่อนดู เขาควรไปที่ส่วนถัดไป/ก่อนหน้าของหน้าอย่างชัดเจน โดยไม่ต้องข้ามมัน แม้ว่าเขาจะเลื่อนอย่างเข้มข้นก็ตาม ในเวลาเดียวกัน เราจะโหลดเนื้อหาที่เกี่ยวข้องลงในบล็อกปัจจุบัน มาสร้าง HTML และ CSS ต่อไปนี้:

* ( Margin: 0; padding: 0; ) #grid li ( list-style: none; height: 300px; border-bottom: 1px dotted #333; ) #fake (height: 5000px;) /* เพียงเท่านี้ก็มีแน่นอน แถบเลื่อน */

เรามาต่อกันที่ JS กันดีกว่า หน้าที่ของเราคือยกเลิกพฤติกรรมปกติระหว่างเหตุการณ์การเลื่อนเมาส์ ( โดยพื้นฐานแล้ว - ป้องกันผู้ใช้จากการเลื่อนหน้าด้วยตนเอง) คำนวณขึ้นอยู่กับทิศทางการเคลื่อนที่ของวงล้อ บล็อกถัดไปหรือก่อนหน้า เลื่อนไปที่บล็อกนี้อย่างเคลื่อนไหวและโหลดเนื้อหาที่จำเป็นลงไป

$(function())( var flag = false, // จำเป็นเพื่อป้องกันการกระทำระหว่างแอนิเมชั่น bn = 0, // ดัชนีของบล็อกปัจจุบัน บล็อก = $("#grid li"), // บล็อกทั้งหมด cnt = บล็อก length, // จำนวนบล็อก mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel"; // ล้อเลื่อนเหตุการณ์ lines.eq(0).load("loadblocks.html # b0"); // โหลดเนื้อหาลงในบล็อกแรกทันที // ฟังก์ชั่นสำหรับกำหนดทิศทางการเลื่อนของฟังก์ชันล้อ getDelta(e)( var evt = e || window.event; evt = evt.OriginalEvent ? evt. originalEvent: evt; return delta = evt.detail ? evt.detail*(-40) : evt.wheelDelta; ) // จับเหตุการณ์การเลื่อน $(document).on(mousewheelevt+".my_wheel", function(e)( e .preventDefault(); / / ยกเลิกพฤติกรรมปกติ (หน้าจะไม่เลื่อน) ถ้า(ตั้งค่าสถานะ) กลับเท็จ; // ถ้าตั้งค่าสถานะ == จริงแล้วใน ในขณะนี้ภาพเคลื่อนไหวเกิดขึ้น if(getDelta(e) > 0)( if(bn<= 0) return false; // если дошли до первого блока, то отменяем การดำเนินการเพิ่มเติม--bn; // หากบล็อกไม่ใช่บล็อกแรก ให้คำนวณดัชนีของบล็อกก่อนหน้า) else ( if(bn >= cnt-1) return false; // ถ้าเราไปถึงบล็อกสุดท้าย ให้ยกเลิกการดำเนินการเพิ่มเติม ++bn; // ถ้าบล็อกไม่ใช่บล็อกสุดท้าย เราจะคำนวณดัชนีของบล็อกถัดไป) flag = true; // ตั้งค่าสถานะเพื่อระบุว่าภาพเคลื่อนไหวได้เริ่มต้นแล้ว $("html, body").finish().animate(( scrollTop: Blocks.eq(bn).offset().top // เลื่อนหน้าไปยังบล็อกที่คำนวณแล้ว โดยดัชนี), , 1,000, function())( Blocks.eq(bn).load("loadblocks.html #b" + bn); // โหลดเนื้อหาสำหรับบล็อกแฟล็ก = false; // ลบแฟล็ก โดยระบุว่า แอนิเมชั่นเสร็จสมบูรณ์ ));

- - ฉันอธิบายทุกอย่างในความคิดเห็น แต่ยังคงต้องอธิบายว่าข้อมูลถูกโหลดจากที่ใด ในวิธีการโหลด() เป็นไปได้ไม่เพียงแต่จะระบุเอกสารที่ต้องโหลดเท่านั้น แต่ยังเพื่อกำหนดองค์ประกอบที่เราต้องการด้วย ในตัวอย่าง ฉันใช้เอกสาร html ธรรมดาที่มีองค์ประกอบหลายอย่าง (ตามจำนวนบล็อกของเรา

ลอง ทดลอง และที่สำคัญที่สุด จำไว้ว่าบางสิ่งที่คุณอาจไม่ต้องการในวันนี้อาจมีประโยชน์มากในวันพรุ่งนี้ และหากคุณมีคำถามหรืองานที่ผิดปกติให้เขียนไว้ในหัวข้อนี้หรือในส่วน "