Изменение html элемента с помощью JS
Всё тот же код из задания про удаление элемента, но теперь требуется заменить элемент с плохой картинкой спаном, в котором будет текст Now here is a ‘span’ element. внутри этого самого спана.
<!DOCTYPE html> <head> </head> <body> <p style="color: navy"> There's only picture here... <br> <img src="http://ipic.su/img/img7/fs/burger.1537205489.jpg" width="100px" height="100px" /> </p> <br> <p> This one cannot be displayed. We have to replace it. <img alt="bad picture"> </p> <script type="text/javascript"> var pElement=document.getElementsByTagName('p')[1]; var imgElement=document.getElementsByTagName('img')[1]; var sElement = document.createElement('span'); var txt = "Now here is a ‘span’ element."; sElement.innerHTML = txt; pElement.replaceChild(sElement,imgElement); </script> </body> </html> Вот что получилось, в HTML текст отображается, но значение спана все ещё не соответствует тексту, даже не знаю как это поправить |
Цитата:
<!DOCTYPE html> <html> <head> <meta http-equiv='Content-Type' content='text/html; charset=windows-1251' /> <!-- <script src='https://code.jquery.com/jquery-latest.js'></script> <script src="https://code.angularjs.org/1.3.9/angular.min.js"></script> <script src="https://code.angularjs.org/1.3.9/angular-route.js"></script> --> <style type='text/css'> </style> <script type='text/javascript'> </script> </head> <body> <p style="color: navy"> There's only picture here... <br> <img src="http://ipic.su/img/img7/fs/burger.1537205489.jpg" width="100px" height="100px" /> </p> <br> <p> This one cannot be displayed. We have to replace it. <img alt="bad picture"> </p> <script type="text/javascript"> var imgElement=document.getElementsByTagName('img')[1]; var pElement=imgElement.parentNode; var sElement = document.createElement('span'); sElement.innerHTML = "Now here is a ‘span’ element."; pElement.removeChild(sElement,imgElement); pElement.appendChild(sElement); </script> </body> </html> |
Цитата:
pElement.appendChild(sElement); pElement.replaceChild(sElement,imgElement); Т.е. на момент выполнения replaceChild() оба дитя должны существовать в родителе... ;) |
ksa, 🌚
crabkilla, вот правильное решение... Вариант №1 Одноразовое замещение ломанных картинок после загрузки... <!DOCTYPE html> <head></head> <body> <p style="color: navy"> There's only picture here... <br> <img src="http://ipic.su/img/img7/fs/burger.1537205489.jpg" width="100px" height="100px" /> </p> <br> <p id="pic"> This one cannot be displayed. We have to delete it. <img alt="bad picture"> </p> <script> addEventListener("load", function() { for(const image of document.images) { if(image.naturalWidth === 0) { const node = document.createElement("span"); node.textContent = "Now here is a ❄️."; image.replaceWith(node); } } }); </script> </body> </html> Вариант №2 Живое замещение ломанных картинок ... <!DOCTYPE html> <head></head> <body> <script> const observer = new MutationObserver(mutationRecords => { for(const mutationRecord of mutationRecords) { if(mutationRecord.type === "childList") { for(const node of mutationRecord.addedNodes) { if(node instanceof HTMLImageElement) { if(!node.hasAttribute("src")) replaceBrokenImage(node); else node.addEventListener("error", ()=> replaceBrokenImage(node)); } } } } }); observer.observe(document.body, { childList: true, subtree: true }); function replaceBrokenImage(image) { const node = document.createElement("span"); node.textContent = "Now here is a ❄️."; image.replaceWith(node); } </script> <p style="color: navy"> There's only picture here... <br> <img src="http://ipic.su/img/img7/fs/burger.1537205489.jpg" width="100px" height="100px" /> </p> <br> <p id="pic"> This one cannot be displayed. We have to delete it. <img alt="bad picture"> </p> </body> </html> |
Malleys,
создание элементов в цикле дорогая операция для этого есть клонирование, фрагмент, insertAdjacentHTML ... кроме того сам подход замены битых картинок средствами js напоминает (........) вы правильно прочитали для этого достаточно пару строк в nginx или htaсcess, обработать сервером |
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
|
https://learn.javascript.ru/multi-insert
читаем учебник |
img.onload = function() { // the image is ready }; img.onerror = function() { // the image has failed }; Это для Цитата:
|
Цитата:
Однако, всё это так и так это знаю! И я обычно не использую innerHTML+=, insertAdjacentHTML поскольку это ломает объекты или является не ООП подходом! Я так понимаю, вы хотели доказать какую-то, как вам кажется, мою ошибочность... однако статья, на которую вы дали ссылку, как раз таки подтверждает все мои взгляды! Вот...
Я прочитал статью и запустил тесты, не знаю, что именно вы хотели мне сказать... Посмотрел с телефона (результаты такие же, т. е. вставка через фрагмент незначительно медленней) Т. е. разумная точка зрения такая, что можно использовать оба варианта! 🎉 На компьютере был Chrome 75 и телефоне Chrome 74! Цитата:
Цитата:
Это способ подходит только если вы работаете с конкретным изображением... А если вы вставляете HTML-код в DOM и в коде есть картинки, то правильней использовать именно Service Worker. И Service Worker предоставляет централизованный способ обработки запрашиваемых ресурсов, будь то шрифты, картинки интерфейса, данные приложения, шаблоны, всё, что нужно для работы приложения. 😎 |
1. не стоит перекручивать задачи
2. в автономных приложениях битую картинку должен видеть разработчик и править 3. единственно где проверяют картинки это контент редактируемый пользователями на сервере. сервера настраивают всегда. Не стоит считать конфигурацию сервера вредом. Это наоборот полезно и нужно. 4. когда вы утверждаете в правильности вашего решения, вы думаете что можете ошибаться? Зачем эта замена (надо заменять сервером). И если уж так горит js то по событию image onerror заменять src на base64 одно пиксельной картинкой onload и onerror для image здесь отлично работают 5. исходя из ваших убеждений разработчики языка написали много ненужных вещей clone, onerror ... ох уж эти разработчики |
document.addEventListener("DOMContentLoaded", function () { var len = document.images.length; while (len) document.images[--len].onerror = function (e) { e.target.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" } }); вариант :) |
Цитата:
Это действительно полезные вещи, я ничего не имею против! Просто вы всё тянете в 2005 год... а веб-программирование в 2005 году было по другому. Как я понимаю, вы не поняли, почему я написал так... node.addEventListener("error", ()=> replaceBrokenImage(node));Это было сделано для того, чтобы не был перезаписан обработчик, который возможно, объявлен через атрибут onerror. Цитата:
Т. е. то, что я показываю оно реально работает! Это не какие-то воображаемые псевдокоды... Оно работает во всех современных браузерах на компьютере и на мобильных телефонах... Также возможно покрытие Electron, node-webkit, cordova... Да, оно не работает в супер старинных браузерах, и это никого не волнует, поскольку кто будет работать в браузере, в котором большая часть сайтов не работает... У людей есть выбор и если по их субъективному мнению им такое как раз, то кто сможет их заставить установить новый браузер, который сам обновляется! Цитата:
|
Poznakomlus, содержательные имена переменных упрощают понимание и изменение кода. Например, вы можете сказать, что делает следующий метод?
function getThem() { const list1 = new Array(); for(const x of this.theList) if(x[0] === 4) list1.push(x); return list1; } Вы можете сказать, что делает этот код? Почему это трудно, хотя в нём нет сложных выражении, отступы расставлены грамотно и задействовано мало констант? Всё дело в неочевидности, в том, что контекст не следует явно из самого кода! Такой код подразумевает, что вы знаете...
Ответы не следуют из кода, который приведён выше, хотя могли бы! Предположим, что вы работаете над игрой Сапёр. Игровое поле представлено при помощи массива ячеек theList. Переименуем его в gameBoard. Каждая ячейка игрового поля представлена при помощи массива, в нулевом элементе которого код состояния, а код 4 означает, что флажок установлен. Даже простое грамотное присваивание имён всем этим концепциям сильно улучшает вышеприведённый код... function getFlaggedCells() { const flaggedCells = new Array(); for(const cell of this.gameBoard) if(cell[this.STATUS_VALUE] === this.FLAGGED) flaggedCells.push(cell); return flaggedCells; } Код стал существенно понятным, хотя тут такое же кол-во операторов и констант, с таким же уровнем вложенности. Можно ещё улучшить читаемость кода, и написать простой класс Cell для представления ячеек вместо использования массива. В класс включён геттер isFlagged, который скрывает магические числа. Не изменилось ничего, кроме имён, но теперь легко понять, что тут происходит... function getFlaggedCells() { const flaggedCells = new Array(); for(const cell of this.gameBoard) if(cell.isFlagged) flaggedCells.push(cell); return flaggedCells; } |
Часовой пояс GMT +3, время: 04:44. |