我正在嘗試使用HTML 定義列表,作爲帶有工具提示的詞彙表。有關預期結果,請參閱this fiddle(底部)。查找發生 - 尚未包含在A標記中 - 由A標記包圍
如果文章中的部分文本與定義列表中的條款匹配,則會顯示工具提示氣泡並顯示匹配的定義。這是由周圍的A標籤完成的。到現在爲止還挺好。
現在的問題是如何解析文章,以便可以在術語表中找到的所有部分將自動被A-tags包圍。此項目可以是例如:
- 組
- 社會團體
- 羣體行爲
- 研究
解析必須是「貪婪」,所以它首先解析最長的定義。
var arr = []; /* Array of terms, sorted by length */
$('#glossary dt').each(function() { arr.push($(this).text()); });
arr.sort(function(a,b) { return b.length - a.length; });
接着,它具有由標籤包圍的第一陣列項出現在#article.html,除非他們已經是一個標籤內。這也應該是不區分大小寫的。
/* don't know how to approach this */
最後移動到下一個數組項並重復。
/* ok, i can figure the loop out myself */
我的問題是檢查是否某些字符串已經是一個標籤內,並與周圍放置文本的一部分的標籤。應避免更換以保持大寫/小寫相同。檢查JSfiddle的預期結果。
編輯:下面plalx的解決方案構建,我想出了下面的代碼:
/*
This script matches text strings in an article with terms in a defintion list (DL);
the DL acts as a glossary. The text strings are wrapped in '<span>' tags,
with the 'title' attribute containing the definition. This allows for easy custom tooltips.
- This script is 'greedy' the longest terms are matched first;
- This script preserves capitalization and escapes HTML in the definitions
*/
var $article = $('#container-inhoud');
var $terms = $('#glossary dt');
//clone to avoid multiple DOM reflows
var $clone = $article.clone();
//create a regex that matches all glossary terms (not case-sensitive), sorted by length
var rx = new RegExp('\\b(' + $terms.map(function() {
return $(this).text();
}).get().sort(function (term1, term2) {
return term2.length - term1.length;
}).join('|') + ')\\b', 'ig');
var entityMap = {
"&": "&",
"<": "<",
">": ">",
'"': '"',
"'": ''',
"/": '/'
};
function escapeHtml(string) {
return String(string).replace(/[&<>"'\/]/g, function (s) {
return entityMap[s];
});
}
//wrap any text string that corresponds with a definition term in a 'span' tag
//the title contains the connected definition.
function replacer(match){
var definition = $terms.filter(function() {
return $(this).text().toLowerCase() == match.toLowerCase();
}).next('dd').text();
definition = escapeHtml(definition);
return '<span class="tooltip" title="' + definition + '">' + match + '</span>';
}
//call the replace function for every regex match
$clone.html($clone.html().replace(rx , replacer));
//unwrap the terms in the glossary section (to avoid tooltips within the glossary itself)
//only needed if the #glossary is within the #article container, otherwise delete the next line.
$clone.find('#glossary .tooltip').contents().unwrap();
$article.replaceWith($clone);
下面的代碼顯示工具提示。
/*
This script displays a tooltip for every 'span' with class 'tooltip'.
The 'title' attribute will be displayed as the tooltip.
The tooltip is displayed directly above and in line with the left side of the element.
Any offsetting is done by manipulation the 'left' and 'top' attributes in the CSS.
*/
$("span.tooltip").hover(
function() {
var bubble = $("#bubble");
bubble.text($(this).attr('title'));
var ypos = $(this).offset().top - bubble.height();
var xpos = $(this).offset().left;
bubble.css({"left":xpos+"px","top":ypos+"px"});
bubble.show();
},
function() {
$("#bubble").hide();
}
);
我用下面的CSS格式化工具提示氣泡:
#bubble{
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 1px solid #888;
color: #ee6c31;
background-color: rgba(255, 255, 255, 0.85);
position:absolute;
z-index:200;
padding:5px 8px;
margin: -15px 5px 5px -10px;
display:none;
}
看一看http://stackoverflow.com/questions/15958020/variable-inside-一個字符串在一個字符串/ 15959797#15959797 – plalx
謝謝,試圖包裹我的頭,現在。 –
如果持有該文章內容的節點的父元素不包含具有直接附加到其中的行爲的任何其他元素,則可以使用answer中描述的easy regex替換解決方案。如果行爲是使用委託來附加的,則不應該由於替換文章容器的'innerHTML'值而引起問題。 – plalx