За последние 24 часа нас посетили 22549 программистов и 1009 роботов. Сейчас ищут 692 программиста ...

Как на php можно кликнув по слову в тексте выполнить его замену?

Тема в разделе "PHP для профи", создана пользователем Medvedoc, 18 мар 2018.

Метки:
  1. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    Доброй ночи! Суть вопроса в следующем: есть текст в блоке или . Как щелкнув например на любое слово в тексте передать именно его в переменную, через которую потом в базе текстового файла найти его синоним и подставить обратно в тоже самое место?
     
  2. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Например, таким образом:
    Код (Javascript):
    1. document.querySelector('div').addEventListener('click', function(e) {
    2.     let txt = this.textContent,
    3.         sel = window.getSelection(),
    4.         range = sel.getRangeAt(0),
    5.         startPos = txt.lastIndexOf(' ', range.startOffset),
    6.         endPos = txt.indexOf(' ', range.startOffset);
    7.     startPos = startPos !== -1 ? startPos + 1 : 0;
    8.     endPos = endPos !== -1 ? endPos : txt.length;
    9.  
    10.     alert(txt.substring(startPos, endPos));
    11. });
    Что нужно учесть при обработке:
    1. При клике на пробельном символе - получаем пробел
    2. Вместе со словом, будут захватываться знаки препинания
    2.1. При очистке от знаков препинания, не забывайте, что могут быть слова, разделенные дефисом: как-то, где-то и т.д. Кстати, подобные сокращения ("т.д.", "т.п.") тоже нужно учитывать.
     
    AlexandrS, karmay, maksivlev и ещё 1-му нравится это.
  3. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    Отличное решение =))) а подскажите тогда еще одно. Например в переменной лежит другое слово, как мне его подставить взамен изначально полученного?
     
  4. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    У вас есть индекс первого и последнего символа в слове. Конкатенируем: подстрока от 0 до startPos + "НовоеСлово" + подстрока от endPos до длина текста. Получаем на выходе такой результат:
    Код (Javascript):
    1. /* ... */
    2. this.textContent = txt.substring(0, startPos) + newWord + txt.substring(endPos, txt.length);
    3. /* ... */
    --- Добавлено ---
    Раздел "PHP для профи" плавно переквалифицировался в раздел "JavaScript" :)
     
    Medvedoc нравится это.
  5. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    А пробелы можно как-нибудь экранировать? А так все просто чудесно получается
     
  6. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    с пробелами думаю можно справиться. А как все это дело перенести в textarea? Попробовал исправить блок на текстареа, меняется только первое слово и это понятно. А как сделать переклюючение между блоком и teatarea, чтобы можно было подредактировать текст если что?
     
  7. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    И еще такой вопросик, а каким образом все это можно переделать на jquery?
     
  8. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @Medvedoc нафиг jquery, используй нативный
     
  9. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    это как? объясните пожалуйста. Мне по хорошему нужно было вообще на php в связке ajax сделать, но и предложенный вариант мне понравился.
     
  10. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @Medvedoc ajax это javascript, jquery это javascript
     
  11. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Тут особо нечего переделывать. Разве что установка обработчика события и получение/запись текстового содержимого элемента:
    Код (Javascript):
    1. $('div').on('click', function(e) {
    2.     let txt = $(this).text(),
    3.     //... остальное без изменений
    4. });
    jQuery - это библиотека, написанная на нативном (чистом) JS. Если еще проще, то jQuery - это набор методов (функций), которые написаны обычным языком JavaScript. Например, в jQuery можно добавить метод "getClickWord", в которой будет код типа такого, как я показал выше, а вы, как пользователь, будуте только применять этот метод к определенному элементу: $('div').getClickWord();
    Этих функций огромное количество, но в реальности, вы используете только какой-то маленький их процент. При этом, библиотека, которая весит очень не мало, всё равно вся грузится в клиенте, что утяжеляет страницы сайта.
    В чем проблема? Вы можете Ajax-ом передавать только позицию клика "range.startOffset", а все действия с текстом производить на сервере.
     
  12. maksivlev

    maksivlev Новичок

    С нами с:
    2 мар 2018
    Сообщения:
    20
    Симпатии:
    0
    Зачем тут php то?
    Когда ты увидел страницу в браузере , то php уже отработал на сервере(именно на сервер) и завершил работу.
    В браузере его нет(если только ввиде обычного текста , с целью чтения глазами) и не должно быть.
    Чтобы заставить работать php, нужно отправить get, post, put, delete к серверу. (т.е. перейти по ссылке , отправить форму, отправить запрос к php из ajax/js и т.д.).

    В браузере может работать js и отправлять запросы к php и получать данные от сервера и выводить на страницу.
    И задача твоя решается на js.
     
  13. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    @Deonis а как сделать так, чтобы при повторном клике еще раз добавлялось тоже самое слово?
    Немного доработал скрипт https://jsfiddle.net/Medvedoc/sa26uwxt/38/

    Но как сделать, чтобы при первом запуске срабатывала замена? На данный момент начинает работать как только два раза нажать на кнопку.
     
    #13 Medvedoc, 18 мар 2018
    Последнее редактирование: 18 мар 2018
  14. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    @Medvedoc, вы словами опишите последовательность действий и что должно при этом происходить, тогда будет над чем подумать. А пока у вас в коде какая-то несуразица
     
  15. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    1. Если нажать на слово, то оно меняется на заданное
    2. Если нажать еще раз на добавленное слово, то к нему повторно добавляется слово через символ, например |
    3. Если нажать кнопку, то div преобразуется в textarea, где можно подправить текст, но при этом при нажатиина слова не должны происходить замены
    4. Перевести вновь textarea в div с сохранением сделанных изменений

    Как-то так
     
  16. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Исходя из вашего кода, там не пахнет никаким textarea, но не важно. Меня больше смущает второй пункт:
    То же самое слово из переменной?
     
  17. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    да, именно тоже самое слово
     
  18. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    @Medvedoc, пробуйте такой вариант
    Код (Javascript):
    1. const newWord = 'Medvedoc',
    2.     mydiv = document.getElementById('mydiv');
    3. document.getElementById('foo').addEventListener('click', () => {
    4.     mydiv.contentEditable = !mydiv.isContentEditable;
    5.     mydiv.focus();
    6. });
    7. mydiv.addEventListener('click', () => {
    8.     if (mydiv.isContentEditable) {
    9.         return false;
    10.     }
    11.     let txt = mydiv.textContent,
    12.         sel = window.getSelection(),
    13.         range = sel.getRangeAt(0),
    14.         startPos = txt.lastIndexOf(' ', range.startOffset),
    15.         endPos = txt.indexOf(' ', range.startOffset);
    16.     startPos = startPos !== -1 ? startPos + 1 : 0;
    17.     endPos = endPos !== -1 ? endPos : txt.length;
    18.  
    19.     let word = txt.substring(startPos, endPos),
    20.         insertion = word.split('|').filter(el => el !== newWord).length === 0 ? word + '|' + newWord : newWord;
    21.  
    22.     mydiv.textContent = txt.substring(0, startPos) + insertion + txt.substring(endPos, txt.length);
    23. });
     
    Medvedoc нравится это.
  19. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    @Deonis, Вы просто гений! А как можно если последовательно заменились два слова их окружить кавычками или скобками?
    То есть
    Код (Text):
    1. Medvedoc|Medvedoc|Medvedoc|Medvedoc
    преобразовать в
    Код (Text):
    1. (Medvedoc|Medvedoc|Medvedoc|Medvedoc)
    или
    Код (Text):
    1. "Medvedoc|Medvedoc|Medvedoc|Medvedoc"
    Или просто выделить область эту и чтобы автоматически обрамить в скобки или кавычки.

    А касаемо пробелов поступить немного иначе. Если щелкнуть по пробелу, то он заменится на другой знак пунктуации. например, на нижнее подчеркивание (_)
    --- Добавлено ---
    а также при наведении на слово, чтобы оно выделялось рамкой или применялся другой стиль, чтобы обозначить hover-эффект
     
  20. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Змените:
    Код (Javascript):
    1. // строка
    2. let word = txt.substring(startPos, endPos),
    3. // на эту
    4. let word = txt.substring(startPos, endPos).replace(/^\(?|\)?$/g,''),
    5.  
    6. // и участок кода
    7. word + '|' + newWord
    8. // на этот
    9. '(' + word + '|' + newWord + ')'
    Два остальных вопроса гораздо сложнее, чем вы себе можете представить. Во первых, заменяя пробельный символ на другой, мы как бы убираем границу между словами и для корректной работы остального кода, нужно вносить существенные правки. А что касается подсветки при наведении, то тут еще сложней задача, т.к. в работу с текстом вмешивается HTML-код.
    --- Добавлено ---
    На скорую руку набросал вам примерчик, без замены пробелов, но на доскональную проверку нет времени. Поэтому допиливать будете уже сами ;)
     
  21. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    со скобками все чудесно получилось =)))) а вот с нижним подчеркиванием что-то не совсем идеально =)
    --- Добавлено ---
    попробую объяснить =)
    (Medvedoc|Medvedoc|Medvedoc|Medvedoc) если выделить его как обычно выделяем текст, чтобы слева и справа проставились разные знаки
    например
    Код (Text):
    1. (Medvedoc|Medvedoc|Medvedoc|Medvedoc)
    на выходе
    Код (Text):
    1. [(Medvedoc|Medvedoc|Medvedoc|Medvedoc)]
    или как-то щелкнуть на пробел и замена на нужный знак. То есть щелкнули один раз - заменился на знак [, еще раз щелкнули - на знак ], еще раз - на { , еще раз - на }
    --- Добавлено ---
    заметил такую ошибку. Если делаю замену с несколькими словами, то после когда перехожу к тертьему слову и начинаю его заменять - замена происходит совсем другого слова
     
  22. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Я вам написал:
    Не объяснили, да и не имеет значения, т.к. я уже объяснил, что на решения таких задач, требуется совсем не 10-15 минут. А у меня, как и у многих других на форуме, есть своя работа, а в выходные еще и своими делами заняться хочется.
     
  23. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    Код (Text):
    1. insertion = word === ' ' ? '_' : (word.split('|').filter(el => el !== newWord).length === 0 ? '(' + word + '|' + newWord + ')' : newWord);
    а подскажите пожалуйста еще как ' ' ? '_' разместить в конце данной строчки
     
  24. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Код (Javascript):
    1. insertion = word === ' ' || word === '' ? '_' : (word.split('|').filter(el => el !== newWord).length === 0 ? '(' + word + '|' + newWord + ')' : newWord);
     
    Medvedoc нравится это.
  25. Medvedoc

    Medvedoc Активный пользователь

    С нами с:
    17 окт 2011
    Сообщения:
    65
    Симпатии:
    0
    а может можно как-то через
    а можно через условие проверить что слово для замены не пробел?
    например так
    Код (Text):
    1. if (word == ' ') {alert ('пробел')}
    если пробел, то меняем его на символы, если нет, то по обычной схеме