TextHighlighter.js
/** * @author jittagorn pitakmetagoon * create 24/04/2014 * source code : http://na5cent.blogspot.com/2014/04/texthighlighter-javascript.html */ window.TextHighlighter = window.TextHighlighter || (function() { function forEachProperty(obj, callback, ctx_opt) { for (var prop in obj) { if (obj.hasOwnProperty(prop)) { var val = callback.call(ctx_opt, obj[prop], prop, obj); if (val === false) { return false; } } } return true; } function forEachIndex(array, callback, ctx_opt) { var length = array.length; for (var i = 0; i < length; i++) { var val = callback.call(ctx_opt, array[i], i, array, length); if (val === false) { return false; } } return true; } /** * @class Strings */ var Strings = { split: function(text, splitor) { var result = []; var list = text.split(splitor); forEachIndex(list, function(txt) { !!txt && result.push(txt); }); return result; }, escapse: function(text) { return text.replace(/\&/g, '&') .replace(/\>/g, '>') .replace(/\</g, '<'); } }; function toArray(obj) { var array = []; forEachProperty(obj, function(value) { array.push(value); }); return array; } function isEquals(a, b) { if (a.equals) { return a.equals(b); } return a === b; } function removeElementInArray(element, array) { forEachIndex(array, function(value, index) { if (isEquals(element, value)) { array.splice(index, 1); } }); } /** * @class Period * for keep period information */ var Period = function(start, end) { this.start_ = start; this.end_ = end; }; Period.prototype.getStart = function() { return this.start_; }; Period.prototype.getEnd = function() { return this.end_; }; Period.prototype.setStart = function(start) { this.start_ = start; }; Period.prototype.setEnd = function(end) { this.end_ = end; }; Period.prototype.equals = function(object) { if (!(object instanceof Period)) { return false; } if (object.getStart() === this.start_ && object.getEnd() === this.end_) { return true; } return false; }; Period.prototype.toString = function() { return 'period {' + this.start_ + ', ' + this.end_ + '}'; }; /** * @class PeriodIntegrator * for integrate period in timeline * * document : http://na5cent.blogspot.com/2013/12/integrate-period-algorithm-java.html */ var PeriodIntegrator = function() { var periodSet_ = {}; var periodList_; this.addPeriod = function(period) { var key = period.toString(); periodSet_[key] = period; return this; }; this.addAllPeriods = function(periodList) { forEachIndex(periodList, addPeriod, this); return this; }; function sortPeriods() { periodList_ = toArray(periodSet_).sort(function(p1, p2) { if (p1.getStart() === p2.getStart()) { return p1.getEnd() - p2.getEnd(); } return p1.getStart() - p2.getStart(); }); } function forEachPeriodIndex(callback) { var length = periodList_.length; if (length < 2) { return; } for (var i = 1; i < length; i++) { callback.call(null, i, length); } } function changeOverlap() { forEachPeriodIndex(function(i) { var before = periodList_[i - 1]; var current = periodList_[i]; if (current.getStart() < before.getEnd()) { current.setStart(before.getEnd()); } }); } function removeIncorrect() { forEachPeriodIndex(function(i, length) { var periodI = periodList_[i]; for (var j = i + 1; j < length; j++) { var periodJ = periodList_[j]; var isDefined = periodI && periodJ; if (isDefined && (isIncorrect(periodJ) || isSubPeriod(periodJ, periodI))) { removeElementInArray(periodJ, periodList_); length--; } } }); } function isIncorrect(period) { return period.getStart() >= period.getEnd(); } function isSubPeriod(period1, period2) { return period1.getStart() >= period2.getStart() && period1.getEnd() <= period2.getEnd(); } function integratePeriods() { forEachPeriodIndex(function(i, length) { var before = periodList_[i - 1]; var current = periodList_[i]; var isDefined = current && before; if (isDefined && current.getStart() === before.getEnd()) { current.setStart(before.getStart()); removeElementInArray(before, periodList_); i--; length--; } }); } this.integrate = function() { sortPeriods(); changeOverlap(); removeIncorrect(); integratePeriods(); return periodList_; }; }; /** * @class TextHighlighter */ var TextHighlighter = function(options_opt) { options_opt = options_opt || {}; this.styleClass_ = options_opt.styleClass || 'ns-text-highlighter'; this.totalHighlight_ = 0; }; /** * @private */ TextHighlighter.prototype.wrapKeywordByHighlightBox = function(keyword) { return '<span class="' + this.styleClass_ + '">' + keyword + '</span>'; }; TextHighlighter.prototype.getTotalHighlight = function() { return this.totalHighlight_; }; /** * @private */ TextHighlighter.prototype.findPeriodsOfSentenceByKeyword = function(sentence, keyword) { var integrator = new PeriodIntegrator(); forEachIndex(Strings.split(keyword, ' '), function(kword) { var length = kword.length; var start = 0; var end = 0; while (true) { var indexOf = sentence.indexOf(kword, end); if (indexOf === -1) { break; } start = indexOf; end = indexOf + length; integrator.addPeriod(new Period(start, end)); } }); return integrator.integrate(); }; /** * @param {String} sentence * @param {String} keyword * @returns {String} highlighted sentence */ TextHighlighter.prototype.highlight = function(sentence, keyword) { sentence = Strings.escapse(sentence); var periods = this.findPeriodsOfSentenceByKeyword(sentence.toLowerCase(), keyword.toLowerCase()); var size = 0; forEachIndex(periods, function(period) { var start = period.getStart() + size; var end = period.getEnd() + size; var infront = sentence.substring(0, start); //---------------------------------------------------------------- var word = sentence.substring(start, end); var highlighted = this.wrapKeywordByHighlightBox(word); //---------------------------------------------------------------- var behind = sentence.substring(end); sentence = infront + highlighted + behind; size = size + highlighted.length - word.length; this.totalHighlight_++; }, this); return sentence; }; return TextHighlighter; })();ตัวอย่างการใช้งาน
<style type="text/css"> .ns-text-highlighter{ background-color : #FFFBA0; } </style> <div id="content"> ในป่าแห่งหนึ่่ง สัตว์ทุกตัว ทุกชนิดต้องการก่อตั้งโรงเรียนขึ้นมา โดยการออกหลักสูตรนั้น สัตว์ทุกชนิดช่วยกันออก โดยการเลือกผู้นำหัวกะทิที่เก่งที่สุดของสัตว์แต่ละชนิดของพวกตน มาเขียนหลักสูตรช่วยกัน เช่น ปลาบอกว่าต้องมีวิชาว่ายน้ำ ลิงบอกว่าต้องมีวิชาไต่ราวหรือปีนต้นไม้ ช้างบอกว่า ต้องมีวิชาลากท่อนซุงหรือโค่นต้นไม้ เสือบอกว่าต้องมีวิชาล่าเหยื่อ นกบอกว่าต้องมีวิชาบินเหินเวหา ตัวตุ่นบอกว่าต้องมีวิชาขุดโพรงเพื่อทำที่อยู่อาศัย ฯลฯ จากนั้นจึงได้นำหลักสูตรต่างๆ ที่สัตว์ทุกชนิดเสนอมาตั้งเป็นหลักสูตรกลาง เพื่อให้สัตว์ทุกชนิดได้เรียนในทุกๆวิชาที่กล่าวมาทั้งหมด เพราะอยากให้สัตว์ทุกตัวในป่ามีคุณภาพ และมีความสามารถเท่าๆกันหมด เพราะคิดว่าทุกตัวได้เรียนในสิ่งเดียวกัน จะต้องมีความสามารถทำได้เหมือนกัน ผลออกมาคือ ช้างสอบตกวิชาบิน วิชาปีนต้นไม้ วิชาขุดโพรง ... แต่สอบผ่านวิชาลากท่อนซุงหรือวิชาโค่นต้นไม้ เสือสอบตกวิชาบิน วิชาไต่ราว เสืออาจจะพอปีนต้นไม้ได้ แต่ก็ไม่ได้ถนัด เพราะสอบได้คะแนนไม่ถึงเกณฑ์ตามที่ลิงได้ตั้งเอาไว้ เลยสอบตก ปลาสอบตกวิชาบิน ... สอบผ่านวิชาว่ายน้ำ แถมได้คะแนนเต็มซ่ะด้วย นกสอบตกวิชาว่ายน้ำ.. แต่สอบผ่านวิชาบินเหินเวหา ฯลฯ สัตว์หัวกะทิทุกชนิดพากันสงสัยว่าทำไมลักสูตรที่ตนออกมานั้น มันจึงไม่มีประสิทธิภาพ ทำไมสัตว์ทุกตัวถึงทำได้ไม่เหมือนกัน ทั้งๆที่พวกเขาก็เรียนวิชาเดียวกัน ทุกวิชาเหมือนกันทั้งหมด </div>
var highlighter = new TextHighlighter(); var content = document.getElementById('content'); var html = content.innerHTML; content.innerHTML = highlighter.highlight(html, 'สัตว์ วิชา สอบ สอบได้ สัตว์ทุกตัว');การประยุกต์ใช้
slide search ทางซ้ายมือของ blog นี้ครับ เอาไว้ highlight keyword search
ไม่มีความคิดเห็น:
แสดงความคิดเห็น