ปากกาเน้นข้อความ MarkIt
นี่คือลิงก์ส่วนขยายของ Chrome ที่ให้คุณเน้นข้อความสำคัญบนหน้าเว็บใดก็ได้ กลับมาเยี่ยมชมหน้าเว็บอีกครั้งใน 1 นาที 1 สัปดาห์ หรือ 1 ปี - ข้อมูลของคุณจะอยู่ที่นั่นเสมอ
เทคโนโลยี
- (วานิลลา) JavaScript
- Google API
คุณสมบัติ
- ไฮไลต์ข้อความใดก็ได้แล้วกด Command+K เพื่อบันทึกโดยอัตโนมัติ
- ผู้ใช้สามารถล้างไฮไลท์ที่เก็บไว้สำหรับ URL ใด ๆ ได้ด้วยคำสั่งง่ายๆ เพียงคำสั่งเดียว Command+Shift+A
- ซิงค์กับทุกอุปกรณ์ - หากคุณไฮไลต์ข้อความจากแล็ปท็อป แล้วดูหน้าเว็บเดียวกันจากโทรศัพท์ของคุณ ไฮไลต์ของคุณก็จะอยู่ที่นั่น (หากคุณลงชื่อเข้าใช้ Chrome ทั้งสองเครื่อง)
โครงสร้างข้อมูลที่เก็บไว้ของฉัน (วัตถุ)
highlights = {
google.com: {
text1: ["query selector", index, note, color]
text2: ["query selector", index, note, color]
},
yahoo.com: {
text3: ["query selector", index, note, color],
text4: ["query selector", index, note, color]
},
https://developer.mozilla.org/en-US/docs/Web/API/document/execCommand: {
"When an HTML document has been switched to designMode, its document object exposes an execCommand": ["p.summary", 20],
"A DOMString specifying the name of the command to execute. See Commands for a list of possible commands.": ["p", 0, "example note", #CFFFDF]
}
}
มันทำงานอย่างไร
ฉันมีสองสคริปต์ที่โหลดในทุกหน้า อย่างแรกคือ background.js ซึ่งคอยฟังเหตุการณ์เฉพาะ เหตุการณ์ Command+K ทริกเกอร์ฟังก์ชันที่แทรกสคริปต์ลงในเบราว์เซอร์ (injection_script.js) ซึ่งไฮไลต์ข้อความที่เลือก
หากต้องการไฮไลต์ ให้ลากเมาส์ไปเหนือข้อความ แล้วกด Command+K สิ่งนี้จะทริกเกอร์ฟังก์ชันที่เรียกใช้ฟังก์ชันอื่นหลายรายการ ลำดับเหตุการณ์:
- หยิบข้อความที่เลือก
- เปิดโหมดการออกแบบเป็น "เปิด" เพื่อให้เราทำการเปลี่ยนแปลง DOM ชั่วคราวได้
- หากพื้นหลังถูกเน้นไว้แล้ว เราจำเป็นต้องลบไฮไลต์ออก:
- เลือก < span > แท็กข้อความรอบๆ และตั้งค่า style.พื้นหลังสี = โปร่งใส (ลบไฮไลต์)
- รับวัตถุ 'ไฮไลท์' จากที่เก็บข้อมูล -
chrome.storage.get()
- วนซ้ำปุ่มทั้งหมด (ซึ่งเป็นไฮไลท์ที่บันทึกไว้) เพื่อค้นหาการจับคู่ และลบออกจากที่เก็บข้อมูล
- มิฉะนั้น ให้ล้อมข้อความด้วย < span > และใช้สีพื้นหลัง
- ในการรีเฟรชหน้า: ดึง 'ไฮไลท์' จากที่เก็บข้อมูล
- หากไม่มีข้อมูลสำหรับ URL ที่ใช้งานอยู่ ให้ตั้งค่าคีย์เป็น URL ปัจจุบันและค่าเป็นวัตถุว่าง (aol.com: {})
- หากมี ให้คว้าโครงสร้างข้อมูลไฮไลท์จากที่เก็บข้อมูล (chrome.storage.get())
- ดึงข้อมูลและกำหนดค่าตัวเลือกแบบสอบถามที่ถูกต้องสำหรับข้อความที่เลือก (ซึ่งจะใช้ในการสืบค้น DOM และใช้ไฮไลต์ในภายหลัง โปรดดูโครงสร้างวัตถุด้านบนเพื่อการชี้แจง)
- หากองค์ประกอบหลักของข้อความที่ไฮไลต์มีชื่อคลาส ให้เก็บสตริง "element.className" ("p.firstParagraph", "h2.sectionHeader" ฯลฯ)
- หากไม่มีชื่อคลาส เก็บสตริง "องค์ประกอบ" ("p", "h2", "li" ฯลฯ)
- กำหนดค่าให้กับคีย์ (ข้อความที่เน้นสี) (อาร์เรย์ที่มี 2 ค่า - ตัวแรก ตัวเลือกคิวรี และตัวที่สอง ดัชนีของตำแหน่งที่ข้อความที่เลือกเกิดขึ้นในองค์ประกอบหลัก)
- ฉันจัดเก็บดัชนีของสตริงเพราะถ้าฉันเก็บเฉพาะข้อความและตัวเลือกแบบสอบถาม สมมติว่าคุณไฮไลต์ "the" ใต้แท็ก "p" เมื่อใช้ไฮไลต์หากคุณรีเฟรชหน้า ทุกการเกิด "the" ใน แท็ก "p" จะถูกไฮไลต์ การเพิ่มค่า indexOf ช่วยให้ฉันตรวจสอบว่าดัชนีตรงกับ DOM จากนั้นจึงใช้ไฮไลต์เท่านั้น ดังนั้นฉันจึงใช้ไฮไลต์กับคำที่ถูกต้อง
- จัดเก็บตัวแปรไฮไลต์ที่อัปเดตซึ่งมีข้อความที่ไฮไลต์ใหม่โดยใช้ chrome.storage.set()
- ปิดโหมดการออกแบบ "ปิด"
ไฟล์ JavaScript ไฟล์ที่สองที่ทำงานในแต่ละหน้าคือ content_script.js จะตรวจสอบว่ามีวัตถุที่เก็บไว้ที่เรียกว่า 'ไฮไลท์' หรือไม่ หากไม่มี แสดงว่าผู้ใช้ไม่เคยไฮไลต์สิ่งใดเลย จากนั้นจะสร้างวัตถุว่างและจัดเก็บไว้ใน Chrome
หากพบวัตถุ 'ไฮไลต์' ระบบจะตรวจสอบว่ามีข้อมูลที่เก็บไว้สำหรับ URL ที่ใช้งานอยู่หรือไม่ หากไม่มี สคริปต์จะกลับมา
หากมีไฮไลท์เก็บไว้สำหรับ URL:
- ฟังก์ชัน ApplyHighlights() ทำงาน
- ต้องใช้พารามิเตอร์สองตัว ได้แก่ ออบเจ็กต์ 'ไฮไลต์' และ URL ที่ใช้งานอยู่
- วนซ้ำคีย์ของวัตถุที่เก็บไว้ (คีย์คือไฮไลท์ที่เก็บไว้ ในขณะที่ค่าของคีย์เหล่านั้นคืออาร์เรย์ที่ประกอบด้วยค่า querySelector และ indexOf)
- รัน document.body.querySelectorAll() เพื่อรับอาร์เรย์ของโหนดที่ตรงกันทั้งหมด
- วนซ้ำแต่ละโหนดที่ส่งคืน และหาก innerHTML มี "สตริง" ที่ตรงกับคีย์อ็อบเจ็กต์ (ข้อความที่เน้นสี) และที่ค่า indexOf เดียวกัน: 1. รันฟังก์ชัน .replace() โดยล้อมข้อความที่ตรงกันในแท็ก < span > ด้วย แอตทริบิวต์สไตล์อินไลน์สำหรับสีพื้นหลัง
- หมายเหตุด้านข้าง: เดิมทีฉันใช้ทุกโหนด DOM ซ้ำๆ เพื่อตรวจสอบการจับคู่ แต่การจัดเก็บค่า querySelector และการเปรียบเทียบค่า HTML ของโหนดที่ตรงกันกับค่าที่เก็บไว้ของฉันนั้นเร็วกว่ามาก
การอัพเกรดสำหรับเวอร์ชันถัดไป
- เก็บสตริงเฉพาะที่คุณไฮไลต์ไว้
- "ดาวน์โหลดไลบรารี jQuery จาก jQuery.com"
- หากคุณไฮไลต์ "jQuery" ตัวที่สอง ค่าที่เก็บไว้จะเป็นของอินสแตนซ์แรก
- เนื่องจากค่า indexOf ที่ฉันจัดเก็บส่งคืนหลังจากการจับคู่ครั้งแรก
- PLAN - เริ่มนับดัชนีหลังแท็ก span
- ไม่สามารถเน้นข้ามองค์ประกอบบล็อกได้ (หากคุณลากไฮไลต์จาก h2 ลงในแท็ก ap เฉพาะ h2 เท่านั้นที่จะลงทะเบียน)
- อยู่ระหว่างดำเนินการ: อนุญาตให้ผู้ใช้เลือกสีไฮไลต์
- ให้จำนวนไฮไลต์และไฮไลต์จริงสำหรับหน้าเว็บปรากฏในส่วนขยาย popup.html
- ข้อจำกัด/กรณีขอบ: อีเมล, PDF
- ฉันขออนุญาตสำหรับทุกไซต์ ซึ่งบางเว็บไซต์บล็อกการเข้าถึง '*' (cnn.com)
- หากคุณไฮไลต์ "jQuery" ในองค์ประกอบหนึ่ง แล้วไฮไลต์อีกครั้งในอีกองค์ประกอบหนึ่ง องค์ประกอบที่สองจะแทนที่องค์ประกอบแรก (เนื่องจากคีย์เหมือนกัน)
- หากองค์ประกอบหลักเป็นแท็กอินไลน์ innertext/html indexOf จะไม่ลงทะเบียน (-1) หรือสิ้นสุดการเน้นที่ส่วนท้ายของแท็กอินไลน์ ค้นหาดัชนีของแท็ก span และเริ่มทำดัชนีนั้น
- โหมดยุบ - ยุบเอกสารให้เหลือเฉพาะองค์ประกอบหลักของไฮไลท์ที่เก็บไว้
แก้ไขปัญหาแล้ว
- การจัดเก็บไฮไลต์ซึ่งครอบคลุมแท็กองค์ประกอบแบบอินไลน์ (a, em, st ฯลฯ)
- ก่อนหน้านี้ เฉพาะข้อความที่อยู่หน้าแท็กอินไลน์เท่านั้นที่ถูกบันทึก เนื่องจากฉันเก็บข้อความด้านในไว้
- ฉันแก้ไขมันด้วยการจัดเก็บ innerHTML แทน
- ปัญหาที่เกิดขึ้นจากการเปลี่ยนแปลงนี้คือ ฉันกำลังจัดเก็บ indexOf the innerText ซึ่งจะนำไฮไลท์ไปใช้กับข้อความมาตรฐานภายในองค์ประกอบข้อความ เช่น แท็ก "p" แต่ indexOf จะแตกต่างกันสำหรับรายการที่อยู่ในองค์ประกอบแบบอินไลน์เนื่องจาก indexOf นับอักขระแต่ละตัวในแท็ก
- เพื่อแก้ปัญหานี้ ฉันเปรียบเทียบค่า innerText.indexOf และ innerHTML.indexOf แล้วเปรียบเทียบแต่ละค่ากับโหนดที่ตรงกันเมื่อใช้ไฮไลต์กับหน้าที่ผู้ใช้เข้าชมอีกครั้ง
- หากคุณดับเบิลคลิกเพื่อไฮไลต์ส่วนใดส่วนหนึ่ง ค่าดัชนีของจะไม่ลงทะเบียน ดังนั้นแอปของฉันจึงไม่สามารถใช้ไฮไลต์อีกครั้งได้
- เพื่อแก้ปัญหานี้ฉันได้เพิ่ม .toString() และ .trim() วิธีการใน indexOf(...)
- การเน้นแท็ก < a > จะเป็นการลบลิงก์ในการโหลดหน้าเว็บ
การอัพเกรดในอนาคต
## ภาพตัวอย่าง

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