замена текста на картинки
здравствуйте вам!
хочу сделать букмарклет для перевода китайского портала перевод решено сделать картинками, т.к. иероглифы все стандартной длины, а наши слова очень разные, поэтому при замене текста очень ломается верстка. пример: <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.. возможно и не придется.. знания мои ниже базовых.. задача срочная.. по серверу впринципе, разберусь сам (если картинки нет, выдам заглушку). что непонятно - уточню. прошу не пинать в сторону учебников, ибо некогда. форум перекопал.. если слеп, ткните носом. основной затык - как сделать чтобы страничка перерисовывалась нормально или не вся страничка, а только заменяемый текст. спасибо |
Чтобы перерисовывался заменяемый текст, а не страница, надо заменять текст, а не страницу. Ваш капитан.
Вот функция обхода всех элементов, с заменой любого текста на картинки: (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">') |
нуб-нубом,
собрать коллекцию textNode и appendChild часть текста или replaceChild весь текст ноды |
рони, что то я сейчас заморочился:), универсальный вариант:
(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]); //меняем текстовую ноду на фрагмент докумета из текста и картинки } } }()) |
Aetae,
:victory: |
может, это слишком круто?
по моему нику ведь понятно, что мне ничего непонятно :blink: на самом деле, понятно, что это универсальное решение, и оно сработает во многих случаях.. кроме моего :) я хотел простенький букмарклет, а выходит, нужно писать нехилый скрипт.. нет времени это делать.. :( 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>..:-? |
нуб-нубом, используй первый вариант тогда, только замени
document.getElementsByTagName('*') на document.querySelectorAll('#rep1 *, #rep2 *, #repx *') Чтоб текст был кодированным - замени childs[j].data + '.jpeg' на encodeURIComponent(childs[j].data) + '.jpeg' |
крутяяк :dance:
только на сервер всеравно приходят кракозябры: а еще цифры, символы, пробелы и \n :blink: значит, нужно их отрезать? и не заменять строки, в которых есть что-то кроме иероглифов.. или в которых нет иероглифов.. капеец.. |
а еще строку нужно преобразовать в набор букво-цифр.. в итоге получилось так: (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]); } } } }()) и это работает.. но на самом деле, все неправильно :blink: значит, надо так: 1. тянем с сервера массив переведенных иероглифов и линков на картинки :( :( :( выходит, каждый раз, когда я переведу очередную порцию, пользователь должен обновить скрипт? ааа.. так вот, что такое XSS.. блин.. 2. с помощью querySelectorAll и childNodes выбираем что будем менять 3. меняем то, что есть на линки из массива.. |
Букмарклет:
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]); //меняем текстовую ноду на фрагмент докумета из текста и картинки } } }()) |
Часовой пояс GMT +3, время: 18:19. |