15.12.2014, 09:25
|
Интересующийся
|
|
Регистрация: 15.12.2014
Сообщений: 13
|
|
замена текста на картинки
здравствуйте вам!
хочу сделать букмарклет для перевода китайского портала
перевод решено сделать картинками, т.к. иероглифы все стандартной длины, а наши слова очень разные, поэтому при замене текста очень ломается верстка.
пример:
<div id="replace_me">高於</div>
должно стать:
<div id="replace_me"><img src="myhost.ru/高於.jpeg"></div>
скорее всего, из иероглифа нужно вычислить хеш, чтобы мой сервер мог нормально отдать статичную картинку..
сделал так:
javascript:document.body.innerHTML = document.body.innerHTML.replace(/高於/g, '<img src="myhost.ru/高於.jpeg">');
но таким образом вся страница перерисовывается, причем без css. а еще не учел id.. возможно и не придется..
знания мои ниже базовых.. задача срочная.. по серверу впринципе, разберусь сам (если картинки нет, выдам заглушку).
что непонятно - уточню. прошу не пинать в сторону учебников, ибо некогда. форум перекопал.. если слеп, ткните носом.
основной затык - как сделать чтобы страничка перерисовывалась нормально или не вся страничка, а только заменяемый текст.
спасибо
Последний раз редактировалось нуб-нубом, 15.12.2014 в 09:27.
Причина: уточнил
|
|
15.12.2014, 10:10
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,577
|
|
Чтобы перерисовывался заменяемый текст, а не страница, надо заменять текст, а не страницу. Ваш капитан.
Вот функция обхода всех элементов, с заменой любого текста на картинки:
(function(){
var elems = document.getElementsByTagName('*'), i = elems.length;
while(i--) {
var childs = elems[i].childNodes, j = childs.length;
while(j--) if( childs[j].nodeType === 3 && /\S/.test( childs[j].data ) ){ //перебираем детей и если нода текстовая и не пустая
var img = document.createElement('img'); //создаём картинку
img.src = 'http://myhost.ru/' + childs[j].data + '.jpeg'; //добавляем в картинки адрес текст
elems[i].replaceChild(img, childs[j]); //меняем текстовую ноду на картинку
}
}
}())
Но разумнее заменять только тот текст, для которого есть перевод, заранее сделав список. А ещё разумнее(если кол-во перевода не велико) - обращаться напрямую к каждому элементу по id:
var el = document.getElementById('replace_me');
el.innerHTML = el.innerHTML.replace(/高於/g, '<img src="myhost.ru/高於.jpeg">')
__________________
29375, 35
Последний раз редактировалось Aetae, 15.12.2014 в 10:17.
|
|
15.12.2014, 10:17
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,105
|
|
нуб-нубом,
собрать коллекцию textNode и appendChild часть текста или replaceChild весь текст ноды
|
|
15.12.2014, 10:35
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,577
|
|
рони, что то я сейчас заморочился , универсальный вариант:
(function(){
var locale = function(re, arr){ //сразу преобразуем массив в регулярное выражение
var i = arr.length;
while(i--) arr[i] = arr[i].replace(re, '\\$&')
return new RegExp(arr.join('|'), 'g')
}(/[.*+?^${}()|\[\]\/\\]/g, [ //массив переведённых фраз
'高於',
'foo',
'bar'
]);
function replace(node){
var frag = document.createDocumentFragment(),
div = document.createElement('div');
div.appendChild(node.cloneNode());
div.innerHTML = div.innerHTML.replace(locale, '<img src="http://myhost.ru/$&.jpeg">');
while(div.hasChildNodes()) frag.appendChild(div.firstChild);
return frag
}
var elems = document.getElementsByTagName('*'), i = elems.length;
while(i--) {
var childs = elems[i].childNodes, j = childs.length;
while(j--) if( childs[j].nodeType === 3 && locale.test( childs[j].data ) ){ //перебираем детей и если нода текстовая и в ней есть переведённый текст
elems[i].replaceChild(replace(childs[j]), childs[j]); //меняем текстовую ноду на фрагмент докумета из текста и картинки
}
}
}())
__________________
29375, 35
|
|
15.12.2014, 11:11
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,105
|
|
Aetae,
|
|
15.12.2014, 14:18
|
Интересующийся
|
|
Регистрация: 15.12.2014
Сообщений: 13
|
|
может, это слишком круто?
по моему нику ведь понятно, что мне ничего непонятно
на самом деле, понятно, что это универсальное решение, и оно сработает во многих случаях.. кроме моего
я хотел простенький букмарклет, а выходит, нужно писать нехилый скрипт.. нет времени это делать..
1. как упаковать функцию в букмарклет (нашел здесь-же на сайте)
2. не каждый элемент имеет id (каюсь)
соответственно, логика вырисовывается такая:
делаем список (массив?) id элементов внутри которых есть вложенные элементы без id, вот в этих вложенных элементах и будем менять текст.
<div id="rep1"><p>text1</p></div>
<div id="no_rep"><p>text2</p></div>
<div id="rep2"><p>text3</p></div>
список будет такой:
'rep1','rep2'
вот результат после работы букмарклета:
<div id="rep1"><p><img src="mysite.ru/text1.jpeg"></p></div>
<div id="no_rep"><p>text2</p></div>
<div id="rep2"><p><img src="mysite.ru/text3.jpeg"></p></div>
так я буду видеть на сервере на какие запросы я выдаю заглушку, соответственно эти слова мне надо доперевести.
и еще.. как все-таки сделать хеш, а не непонятные \x65\x22?
а еще.. *размечтался* воткнуть бы кусочек с моего сайта сразу после тега <body>..
Последний раз редактировалось нуб-нубом, 15.12.2014 в 14:53.
Причина: очепятка
|
|
15.12.2014, 16:11
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,577
|
|
нуб-нубом, используй первый вариант тогда, только замени
document.getElementsByTagName('*')
на
document.querySelectorAll('#rep1 *, #rep2 *, #repx *')
Чтоб текст был кодированным - замени
childs[j].data + '.jpeg'
на
encodeURIComponent(childs[j].data) + '.jpeg'
__________________
29375, 35
|
|
15.12.2014, 17:03
|
Интересующийся
|
|
Регистрация: 15.12.2014
Сообщений: 13
|
|
крутяяк
только на сервер всеравно приходят кракозябры:
\xe9\xab\x98\xe6\x96\xbc что странно - в отладчике в хроме все кодируется, а на сервер летят такие странности.. тут дело явно не в скрипте
а еще цифры, символы, пробелы и \n
значит, нужно их отрезать? и не заменять строки, в которых есть что-то кроме иероглифов.. или в которых нет иероглифов.. капеец..
Последний раз редактировалось нуб-нубом, 15.12.2014 в 17:51.
Причина: уточнил
|
|
15.12.2014, 17:14
|
Интересующийся
|
|
Регистрация: 15.12.2014
Сообщений: 13
|
|
получается, что нужно удалить из строки всё специальное (цифры, символы, пробелы), и заменять ее только если она не пуста..
а еще строку нужно преобразовать в набор букво-цифр..
в итоге получилось так:
(function(){
var elems = document.querySelectorAll('#rep1, #repx *'), i = elems.length;
while(i--) {
var childs = elems[i].childNodes, j = childs.length;
while(j--) if( childs[j].nodeType === 3 && /\S/.test( childs[j].data ) ){
var str = childs[j].data;
var reg = /\s|\d|\.|%|\[|\]|\(|\)/gi;
var res = str.replace( reg, '' );
if( res.length ){
var img = document.createElement('img');
img.src = 'http://mysite.ru/' + encodeURIComponent( res ) + '.jpeg';
elems[i].replaceChild(img, childs[j]);
}
}
}
}())
и это работает.. но на самом деле, все неправильно
значит, надо так:
1. тянем с сервера массив переведенных иероглифов и линков на картинки выходит, каждый раз, когда я переведу очередную порцию, пользователь должен обновить скрипт? ааа.. так вот, что такое XSS.. блин..
2. с помощью querySelectorAll и childNodes выбираем что будем менять
3. меняем то, что есть на линки из массива..
Последний раз редактировалось нуб-нубом, 15.12.2014 в 22:23.
|
|
17.12.2014, 01:22
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,577
|
|
Букмарклет:
javascript:(function(script,body,src){script.src=src;body.appendChild(script)}(document.createElement('script'),document.body,'http://site/script.js'));;
Скрипт который отдаёт сервер:
(function(){
var dict = { //массив переведенных иероглифов и линков на картинки
'高於' : 'http://site.ru/img1.jpg',
'меняем' : 'http://site.ru/img2.jpg'
}
var locale = function(re, arr){ //сразу преобразуем список в регулярное выражение
var i = arr.length;
while(i--) arr[i] = arr[i].replace(re, '\\$&')
return new RegExp(Object.keys(dict).join('|'), 'g')
}(/[.*+?^${}()|\[\]\/\\]/g, dict);
function replace(node){
var frag = document.createDocumentFragment(),
div = document.createElement('div');
div.appendChild(node.cloneNode());
div.innerHTML = div.innerHTML.replace(locale, function(word) { return '<img src="' + dict[word] + '">' });
while(div.hasChildNodes()) frag.appendChild(div.firstChild);
return frag
}
var elems = document.getElementsByTagName('*'), i = elems.length;
while(i--) {
var childs = elems[i].childNodes, j = childs.length;
while(j--) if( childs[j].nodeType === 3 && locale.test( childs[j].data ) ){ //перебираем детей и если нода текстовая и в ней есть переведённый текст
elems[i].replaceChild(replace(childs[j]), childs[j]); //меняем текстовую ноду на фрагмент докумета из текста и картинки
}
}
}())
__________________
29375, 35
|
|
|
|