Примените лигатуру с помощью jquery только к тексту ссылки, а не к ссылке href
-
13-12-2019 - |
Вопрос
Я использую ligatures.js для замены текста на моем сайте лигатурой некоторых комбинаций символов.Например, «фи» в слове «пять».
Вот мой пример: http://jsfiddle.net/vinmassaro/GquVy/
Запустив его, вы можете выбрать выходной текст и увидеть, что «фи» в «пяти» стало одним символом, как и предполагалось.Если вы скопируете адрес ссылки и вставите его, вы увидите, что часть href также была заменена:
/news/here-is-a-url-with-%EF%AC%81ve-ligature
Это непреднамеренно и разрывает ссылку.Как я могу заменить ТОЛЬКО текст ссылки, но не часть href?Я пробовал использовать .text() и .not(), но безуспешно.Заранее спасибо.
Решение
Я думаю, вы можете решить эту проблему, используя соответствующие селекторы jQuery.
$('h3 a, h3:not(:has(a))')
.ligature('ffi', 'ffi')
.ligature('ffl', 'ffl')
.ligature('ff', 'ff')
.ligature('fi', 'fi')
.ligature('fl', 'fl');
Видеть http://jsfiddle.net/GquVy/7/
Другие советы
Вы применяете функцию ко всему заголовку innerHTML
, который включает в себя якорь href
атрибут.Это должно работать для вашего примера скрипки:
$('h1 a, h2 a, h3 a, h4 a').ligature( //...
Однако он будет работать только со ссылками внутри заголовков, и я не уверен, что это то, что вам нужно.Если вы хотите что-то, что работает для любой содержимое внутри определенного элемента (с любой уровень вложенности тегов), то вам понадобится рекурсивный подход.Вот идея, которая по сути представляет собой простой JavaScript, поскольку jQuery не предоставляет возможности нацеливаться на текстовые узлы DOM:
$.fn.ligature = function(str, lig) {
return this.each(function() {
recursiveLigatures(this, lig);
});
function recursiveLigatures(el, lig) {
if(el.childNodes.length) {
for(var i=0, len=el.childNodes.length; i<len; i++) {
if(el.childNodes[i].childNodes.length > 0) {
recursiveLigatures(el.childNodes[i], lig);
} else {
el.childNodes[i].nodeValue = htmlDecode(el.childNodes[i].nodeValue.replace(new RegExp(str, 'g'), lig));
}
}
} else {
el.nodeValue = htmlDecode(el.nodeValue.replace(new RegExp(str, 'g'), lig));
}
}
// http://stackoverflow.com/a/1912522/825789
function htmlDecode(input){
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
};
// call this from the document.ready handler
$(function(){
$('h3').ligature('ffi', 'ffi')
.ligature('ffl', 'ffl')
.ligature('ff', 'ff')
.ligature('fi', 'fi')
.ligature('fl', 'fl');
});
Это должно работать с таким содержимым:
<h3>
mixed ffi content
<span>this is another tag ffi <span>(and this is nested ffi</span></span>
<a href="/news/here-is-a-url-with-ffi-ligature">Here is a ffi ligature</a>
</h3>