29.07.2019, 15:07
|
Новичок на форуме
|
|
Регистрация: 19.07.2019
Сообщений: 5
|
|
Изменение 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 текст отображается, но значение спана все ещё не соответствует тексту, даже не знаю как это поправить
|
|
29.07.2019, 15:19
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,228
|
|
Сообщение от crabkilla
|
даже не знаю как это поправить
|
Его нужно добавить на страницу в нужное место...
<!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>
|
|
29.07.2019, 15:25
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,228
|
|
Сообщение от crabkilla
|
даже не знаю как это поправить
|
Или так...
pElement.appendChild(sElement);
pElement.replaceChild(sElement,imgElement);
Т.е. на момент выполнения replaceChild() оба дитя должны существовать в родителе...
|
|
29.07.2019, 15:56
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
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>
|
|
29.07.2019, 16:20
|
|
Профессор
|
|
Регистрация: 13.03.2013
Сообщений: 1,572
|
|
Malleys,
создание элементов в цикле дорогая операция
для этого есть клонирование, фрагмент, insertAdjacentHTML ...
кроме того сам подход замены битых картинок средствами js напоминает (........)
вы правильно прочитали
для этого достаточно пару строк в nginx или htaсcess, обработать сервером
Последний раз редактировалось Vlasenko Fedor, 29.07.2019 в 16:23.
|
|
29.07.2019, 16:35
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от Poznakomlus
|
для этого достаточно пару строк в nginx или htaсcess, обработать сервером
|
Для этого есть Service Worker.
Сообщение от Poznakomlus
|
кроме того сам подход замены битых картинок средствами js напоминает (........)
|
Пока вы не придумали, что же оно означает... JavaScript является языком программирования общего назначения. Сеть является не единственным источником данных! Это может быть и файловая система и локальный кеш...
Сообщение от Poznakomlus
|
создание элементов в цикле дорогая операция
|
Однако программирование работает именно так! Циклы используют и при манипуляции узлов DOM и при разработке игр... А вы предлагаете unroll делать? (надеюсь не руками!)
Сообщение от Poznakomlus
|
пару строк в nginx или htaсces
|
и в итоге логика приложения будет размазана уже по 2-ум местам
Сообщение от Poznakomlus
|
создание элементов в цикле дорогая операция
|
Кто-то где-то это пукнул (я так понимаю в контексте JS) и вы повторяете как мантру! А если вы вычисляли какие-то тесты с 10 000 000 итерациями цикла с созданием элементов, то вот когда будет в приложении именно такое кол-во итерации, тогда вы и говорите, что это дорогая операция!
Последний раз редактировалось Malleys, 29.07.2019 в 16:46.
|
|
29.07.2019, 16:46
|
|
Профессор
|
|
Регистрация: 13.03.2013
Сообщений: 1,572
|
|
|
|
29.07.2019, 16:55
|
|
Профессор
|
|
Регистрация: 13.03.2013
Сообщений: 1,572
|
|
img.onload = function() {
// the image is ready
};
img.onerror = function() {
// the image has failed
};
Это для
Сообщение от Malleys
|
Для этого есть Service Worker
|
|
|
29.07.2019, 17:31
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от Poznakomlus
|
https://learn.javascript.ru/multi-insert
читаем учебник
|
Читаю...
Однако, всё это так и так это знаю! И я обычно не использую innerHTML+=, insertAdjacentHTML поскольку это ломает объекты или является не ООП подходом!
Я так понимаю, вы хотели доказать какую-то, как вам кажется, мою ошибочность... однако статья, на которую вы дали ссылку, как раз таки подтверждает все мои взгляды!
Вот...
- https://learn.javascript.ru/multi-in...rt-bench-tbody Бенчмарк
Потыкал 8 раз на каждый тест, вот циферки, которые выскакивали в alert...- TBODY сразу DOM: 84 109 99 79 90 94 81 95
- Отложенная вставка TBODY в DOM: 90 87 96 94 110 90 76 75
Я считаю, что оба способа хороши!
- https://learn.javascript.ru/multi-in...cumentfragment DocumentFragment
Цитата:
|
Важно для старых браузеров
Оптимизация, о которой здесь идёт речь, важна в первую очередь для старых браузеров, включая IE9-. В современных браузерах эффект от нее, как правило, небольшой, а иногда может быть и отрицательным.
|
Как видите, то что вы предлагаете, является сильно не популярным и крайним взглядам, характерным для микроскопически малого кол-ва пользователей IE9- 📉
Цитата:
|
Понять текущее положение вещей вы можете, запустив следующий небольшой бенчмарк.
|
с фрагментом работает примерно в 0,9...1,5 раз медленней... В общем думаю оба варианта хороши! (Без фрагмента было 10 15 13, с фрагментом 14 22 12)
И там делается вывод в конце
Цитата:
|
DocumentFragment позволяет минимизировать количество вставок в большой живой DOM. Эта оптимизация особо эффективна в старых браузерах, в новых эффект от неё меньше или наоборот отрицательный.
|
Да, оно так и есть! 😜
Я прочитал статью и запустил тесты, не знаю, что именно вы хотели мне сказать...
Посмотрел с телефона (результаты такие же, т. е. вставка через фрагмент незначительно медленней)
Т. е. разумная точка зрения такая, что можно использовать оба варианта! 🎉
На компьютере был Chrome 75 и телефоне Chrome 74!
Сообщение от Poznakomlus
|
https://learn.javascript.ru/multi-insert
читаем учебник
|
А вы прочитали?
Сообщение от Poznakomlus
|
img.onload = function() {
// the image is ready
};
img.onerror = function() {
// the image has failed
};
Это для
Сообщение от Malleys
|
Для этого есть Service Worker
|
|
Вы воспринимаете всё как-то фанатично... Типо есть единственно истинный способ вставки, единственный истинный способ обработки ошибки загрузки картинки...
Это способ подходит только если вы работаете с конкретным изображением... А если вы вставляете HTML-код в DOM и в коде есть картинки, то правильней использовать именно Service Worker.
И Service Worker предоставляет централизованный способ обработки запрашиваемых ресурсов, будь то шрифты, картинки интерфейса, данные приложения, шаблоны, всё, что нужно для работы приложения. 😎
Последний раз редактировалось Malleys, 29.07.2019 в 17:55.
|
|
29.07.2019, 18:12
|
|
Профессор
|
|
Регистрация: 13.03.2013
Сообщений: 1,572
|
|
1. не стоит перекручивать задачи
2. в автономных приложениях битую картинку должен видеть разработчик и править
3. единственно где проверяют картинки это контент редактируемый пользователями на сервере. сервера настраивают всегда. Не стоит считать конфигурацию сервера вредом. Это наоборот полезно и нужно.
4. когда вы утверждаете в правильности вашего решения, вы думаете что можете ошибаться? Зачем эта замена (надо заменять сервером). И если уж так горит js то по событию image onerror заменять src на base64 одно пиксельной картинкой
onload и onerror для image здесь отлично работают
5. исходя из ваших убеждений разработчики языка написали много ненужных вещей clone, onerror ...
ох уж эти разработчики
|
|
|
|