Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Почему метод .html() не работает так как .innerHTML()? (https://javascript.ru/forum/events/75135-pochemu-metod-html-ne-rabotaet-tak-kak-innerhtml.html)

drakulawz 05.09.2018 11:49

Почему метод .html() не работает так как .innerHTML()?
 
Здравствуйте!

Есть такой скрипт:

var num = $('.p'),
        btn = $('.btn');

    btn.on({
        'click': sum
    });

    function sum() {
        for (var i = 0; i < num.length; i++) {
            num[i].innerHTML = num[i].innerHTML + ' ' + (i + 1);
        }
    }


Он должен ставить в конце каждого параграфа его, соответствующий, номер. НО! Проковырялся с jQuery минут 20 в итоге его метод .html() так и не вывел нумерацию в браузере (хотя через console.log(num) нумерация присваивается). В отличии от его аналога в нативном js - .innerHTML() - этим всё выводится (console.log(num) выводит всё то же, что и с html).
Буду очень благодарен если мне объяснит знающий человек в чём тут дело, так как во всех источниках указано, что эти методы являются аналогами друг друга.

laimas 05.09.2018 12:08

Цитата:

Сообщение от drakulawz
в чём тут дело

Не правильное использование.

Dilettante_Pro 05.09.2018 12:15

<div class="p">Первый</div>
<div class="p">Второй</div>
<div class="p">Третий</div>
<div class="p">Четвертый</div>
<button class="btn">Sum</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script>
var num = $('.p'),
        btn = $('.btn');

    btn.on({
        'click': sum
    });

    function sum() {
        for (var i = 0; i < num.length; i++) {
            $(num[i]).html( $(num[i]).html() + ' ' + (i + 1));
        }
    }
</script>

drakulawz 05.09.2018 12:25

Цитата:

Сообщение от Dilettante_Pro
Dilettante_Pro

Благодарю! :D

Aetae 05.09.2018 12:31

<div class="p">Первый</div>
<div class="p">Второй</div>
<div class="p">Третий</div>
<div class="p">Четвертый</div>
<button class="btn">Sum</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script>
var $num = $('.p'),
        btn = $('.btn');

    btn.on({
        'click': sum
    });

    function sum() {
        $num.append(function(i){return ' ' + ++i});
    }
</script>

drakulawz 05.09.2018 12:48

Цитата:

Сообщение от Aetae
Aetae

разве так будет работать, без цикла?
У меня не работает...

Цитата:

Сообщение от Dilettante_Pro
Dilettante_Pro

кстати, а как записать вот такое через html:

function sum() {
        var arr = [];
        for (var i = 0; i < num.length; i++) {
            arr[i] = +num[i].innerHTML;
            inp.val(arr.sort(srt));
        }
    }


Функция сортирует номера в параграфах и выводит в инпут, по возрастанию. Но когда ставлю вместо innerHTML html то выводит NaN. :cray:

Dilettante_Pro 05.09.2018 12:56

Цитата:

Сообщение от drakulawz
Но когда ставлю вместо innerHTML html то выводит NaN.

Вместо нельзя.
innerHTML - это свойство элемента DOM
.html() - это метод объекта jQuery
Смотрите внимательно пример в пост 3

laimas 05.09.2018 13:06

Цитата:

Сообщение от drakulawz
как записать вот такое через html

Если уж "гибрид", то:

num.each(function(n, e) {
    e.innerHTML += ' ' + ++n
})

drakulawz 05.09.2018 13:06

Цитата:

Сообщение от Dilettante_Pro
Вместо нельзя.

ОК. Тогда почему их называют аналогами друг друга?
https://x-twig.ru/blog/239/

Цитата:

Сообщение от Dilettante_Pro
Смотрите внимательно пример в пост 3

Я увидел, рассмотрел, понял и, даже, запомнил. Метод html записывает в массив параграфов тот же параграф но с добавлением нумерации - это понятно. Вся проблема была не в понимании а в синтаксисе - мне, почему-то, сложно запомнить эти нюансы.

drakulawz 05.09.2018 13:16

Цитата:

Сообщение от laimas
Если уж "гибрид"

ещё не совсем понимаю значение слова гибрид в js.
Вот полноценный скрипт:
var   num = $('.p'),
        btn = $('.btn'),
        inp = $('input');

    btn.on({
        'click': sum
    });

    function sum() {
        var arr = [];
        for (var i = 0; i < num.length; i++) {
            arr[i] = +num[i].innerHTML;
            inp.val(arr.sort(srt));
        }
        
    }

    function srt(a, b) {
        if (a > b) {
            return -1;
        }
        if (a < b) {
            return -1;
        }
        if (a == b) {
            return 0;
        }
    }


Всё работает, я же говорил. Просто думал писать всё на jQuery, но теперь выходит, что так нельзя и innerHTML не заменится тут...

Dilettante_Pro 05.09.2018 13:17

Цитата:

Сообщение от drakulawz
Метод html записывает в массив параграфов тот же параграф но с добавлением нумерации

В примере пост 3 не так.
Метод .html() применяется к объекту jQuery, полученному по конкретному элементу DOM
num - объект jQuery со всеми элементами ".p"
num[i] - конкретный элемент DOM
$(num[i]) - объект jQuery конкретного элемента DOM

laimas 05.09.2018 13:28

Цитата:

Сообщение от drakulawz
не совсем понимаю значение слова гибрид в js

Это не термин JS :)
У вас часть кода работает с JQ объектами, а часть с DOM (вот и назвал гибридом). Если на чистом JQ используя его методы, то

num.each(function(n, e) {
    $(e).html($(e).html() += ' ' + ++n)
})


где .each() метод выполняющий тоже самое что for(...), n - это индекс текущего элемента, e - текуший элемент как DOM. А если доступен DOM имеющий innerHTML, то зачем же $(e).html($(e).html() += ' ' + ++n), если проще выполнить e.innerHTML += ' ' + ++n. Здесь $(e), это лишняя трата энергии. ;)

Aetae 05.09.2018 13:29

Цитата:

Сообщение от drakulawz (Сообщение 494007)
разве так будет работать, без цикла?
У меня не работает...

Что значит не работает, если вот прям тут работает? 0_о
Разве что древнюю какую версию jq используешь...

Dilettante_Pro 05.09.2018 13:30

Цитата:

Сообщение от drakulawz
Вот полноценный скрипт:

function srt(a, b) {
if (a > b) {
return -1;
}
if (a < b) {
return -1;
}
if (a == b) {
return 0;
}
}

drakulawz 05.09.2018 13:34

Цитата:

Сообщение от Dilettante_Pro
объект jQuery конкретного элемента DOM

ага, т.е. этот метод не применим напрямую к элементам DOM, понял... Благодарю за разъяснение.

drakulawz 05.09.2018 14:07

Цитата:

Сообщение от laimas
num.each(function(n, e) {
    $(e).html($(e).html() += ' ' + ++n)
})

На это брекетс ругается и выполнять отказывается вообще.

Цитата:

Сообщение от Aetae
Что значит не работает

значит, что ничего не происходит когда я жму по кнопке кроме ошибки $num is not defined. Начинает работать только так:
function sum() {
        $(num).append(function(i){return ' ' + ++i});
    }


В целом - так конечно короче и проще. Благодарю за подсказку.

laimas 05.09.2018 14:28

Цитата:

Сообщение от drakulawz
На это брекетс ругается и выполнять отказывается вообще.

Это от лени, скопировал не удалив лишнего. Должно быть $(e).html($(e).html() + ' ' + ++n). Но еще раз - не оправдано для простых операций получать JQ объект из доступного DOM объекта.

Dilettante_Pro 05.09.2018 14:41

Цитата:

Сообщение от drakulawz
$num is not defined

Невнимательно смотрите примеры.
У Aetae объявление переменных
var $num = $('.p'),


В вашем варианте при
var num = $('.p'),

достаточно
function sum() {
        num.append(function(i){return ' ' + ++i});
    }

Dilettante_Pro 05.09.2018 14:46

Еще вариант - для разнообразия
<div class="p">Первый</div>
<div class="p">Второй</div>
<div class="p">Третий</div>
<div class="p">Четвертый</div>
<button class="btn">Sum</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script>
var num = $('.p'),
        btn = $('.btn');

    btn.on({
        'click': sum
    });

    function sum() {
        num.html(function(i){return $(this).html() + ' ' + ++i});
    }
</script>

Вместо $(this).html() можно использовать this.innerHTML

drakulawz 05.09.2018 15:36

Цитата:

Сообщение от laimas
не оправдано для простых операций получать JQ объект из доступного DOM объекта.

Имеете в виду, что лучше делать нативными методами js?

Цитата:

Сообщение от Dilettante_Pro
Невнимательно смотрите примеры.
У Aetae объявление переменных
var $num = $('.p'),

Понял, я скопипастил только функцию... буду повнимательней.

Цитата:

Сообщение от Dilettante_Pro
Еще вариант - для разнообразия

А как функция понимает, что в num записаны цифры? Это в библиотеке jQuery всё приобразовывается?

laimas 05.09.2018 16:02

Цитата:

Сообщение от drakulawz
Имеете в виду, что лучше делать нативными методами js?

Для простых операций да. jQuery, это не новый язык, это js библиотека и в недрах ее все выполняется на нативном JS, то есть JQ берет на себя все "тяготы" кроссбраузерности или позволяет написать "желаемое" простым выражением, которое на нативном JS будет более объемным.

Но если к примеру в цикле, используя jq метод, или в обработчике событий, когда в методе доступен DOM элемент как this, который имеет свойство value, получать этот элемент как jq объект ради получения его значения - $(this).val(), это и глупо, и не оправдано, ибо это получить проще как this.value.

drakulawz 05.09.2018 16:25

Цитата:

Сообщение от laimas
Но если к примеру в цикле, используя jq метод, или в обработчике событий, когда в методе доступен DOM элемент как this, который имеет свойство value, получать этот элемент как jq объект ради получения его значения - $(this).val(), это и глупо, и не оправдано, ибо это получить проще как this.value.

Понятно, но это изначально задания на js. Я же пытаюсь зделать их на jq. Не спрашивайте зачем я это делаю, просто мне jq практичнее...

Dilettante_Pro 05.09.2018 16:48

Цитата:

Сообщение от drakulawz
А как функция понимает, что в num записаны цифры?

Какие цифры?

laimas 05.09.2018 17:09

Цитата:

Сообщение от drakulawz
просто мне jq практичнее...

Использование JQ там где нет необходимости, это не есть практичность, это есть расточительство. Если это единичный случай, ладно, но если правило, то весьма плохо.

Допустим есть поле ввода и нужно что-то сделать на странице при вводе некоторого значения в него. При этом все эти операции не касаются самого поля.

$('input').on('input', function() {
    if(this.value=='x') {
        //что-то делаем используя методы JQ
    }    
})


Здесь ради проверки условия поступать как if($(this).val()=='x') просто расточительство не имеющее ни пользы ни практичности.

А если при этом значении поле должно переливаться цветами аки хамелеон и мы будем "хамелеонить" на JQ, то нам потребуется поле как jq объект, вот тут все оправдано:

$('input').on('input', function() {
     $this = $(this); //input как объект jq
     if($this.val()=='x') { //все ОК
        //хамелеоним с $this
    } else {
        //иначе $this сидит и не отсвечивает
    }   
})

drakulawz 05.09.2018 20:07

Цитата:

Сообщение от laimas
laimas

понял... буду иметь в виду. Я везде jq совал так как думал, что он облегчает и сокращает функции и на нативном js вообще никто сейчас не программирует.

Цитата:

Сообщение от Dilettante_Pro
Какие цифры?

у Вас числа прописаны словами, вот и интересуюсь, как оно понимает, что это цифры, а не строки с буквами...

Dilettante_Pro 05.09.2018 21:58

drakulawz,
Метод html вызывает функцию столько раз, сколько элементов находится в обьекте num.
Внутренний параметр i работает в качестве счетчика элементов. Слова в html не имеют никакого значения - если бы там были Яблоко , Слон и т.п., то элементы пронумеровались бы точно так же

drakulawz 07.09.2018 10:23

Цитата:

Сообщение от Dilettante_Pro
Dilettante_Pro

Ага, оно просто пересчитало параграфы. Я просто сам уже запутался, я ведь в одной теме два разных задания впихнул. :stop:
Первое:
Даны N абзацев и кнопка. По нажатию на кнопку запишите в конец каждого абзаца его порядковый номер.
Второе:
Даны N абзацев с числами. По нажатию на кнопку выведите эти числа в инпут через запятую в порядке возрастания.
Выходит, что этот метод не подходит к второму заданию? Он ведь считает сами параграфы, а не то что в них?

рони 07.09.2018 12:08

drakulawz,
цикл each и для первого и для второго

рони 07.09.2018 12:12

drakulawz,
любой цикл html или each или text можно использовать

Dilettante_Pro 07.09.2018 12:24

Второе задание без явного цикла
<div class="p">5</div>
<div class="p">3</div>
<div class="p">1</div>
<div class="p">4</div>
<button class="btn">Sum</button>
<input type="text">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script>
var num = $('.p'),
     btn = $('.btn'),
     inp = $('input');

    btn.on({
        'click': sum
    });

    function sum() {
        var arr = [];
        num.html(function(){ arr.push(+this.innerHTML)});
        inp.val(arr.sort(srt));
    }
    function srt(a, b) {
        if (a > b) {
            return 1;
        }
        if (a < b) {
            return -1;
        }
        if (a == b) {
            return 0;
        }
    }
</script>

drakulawz 07.09.2018 12:28

Цитата:

Сообщение от рони
цикл each и для первого и для второго

Дайте разобраться с предыдущими функциями и методами!)) :help:

Мне понравился вариант Aetae, хоть сначала я его и не понял.:p
Вот, попробовал применить на ещё одном задании:
var a = $('a');

    /*первый вариант функции вывода ссылок;*/
    //    function sum() {
    //        for (var i = 0; i < a.length; i++) {
    //            $(a[i]).html($(a[i]).html() + '(' + a[i].href + ')');
    //        }
    //    }
    //    sum();

    /*второй вариант функции вывода ссылок;*/
    function sum() {
        $a = a;
        $a.append(function (i) {
            return '(' + a[i].href + ')'
        })
    }
    sum();


Скинул два варианта, первый явно бредовый какой-то вышел, с append по-красивее выходит.:)
Как сказал laimas, нефиг совать jq всюду и делать "гибриды"... Если уж делать на jq то правильно.

Благодарю всех участвующих за терпение и (особенно) примеры функций:write: . Только проблема в том, что из ваших ответов я задаюсь всё большим количеством вопросов:help: . Надеюсь, что в дальнейшем смогу получить на них ответы;).
Так то, я уже два месяца как мучаю этот javascript, толком так и не продвинулся. Всякие мелочи делаю, даже калькулятор нормальный сварганить немогу.:cray:

рони 07.09.2018 12:30

:)
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
    var $num = $(".p"),
        btn = $(".btn"),
    inp = $("input");
    btn.on({
        "click": sort
    });

    function sort() {
        var val = $.map($num, function(el) {
            return +el.textContent
        }).sort(function(a, b) {
            return a - b
        });
        inp.val(val)
    }
});
  </script>
</head>

<body>
<input type="text">
<div class="p">10</div>
<div class="p">0</div>
<div class="p">5</div>
<div class="p">-1</div>
<button class="btn">Sort</button>

<script>

</script>


</body>
</html>

Dilettante_Pro 07.09.2018 12:39

drakulawz,
А это что за танцы с бубнами?
var a = $('a');

        $a = a;
        $a.append(function (i) {

Зачем лишний мусор в программе? чтобы потом сложнее было разобраться?

рони 07.09.2018 12:40

Цитата:

Сообщение от drakulawz
По нажатию на кнопку запишите в конец каждого абзаца его порядковый номер.

:)
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  body {
      counter-reset: num;
  }
  .num:after {
      counter-increment: num;
      content: ' 'counter(num);
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
    var $num = $(".p"),
        btn = $(".btn");
    btn.on({
        "click": num
    });

    function num() {
        $num.addClass('num')
    }
});
  </script>
</head>

<body>
<div class="p">Первый</div>
<div class="p">Второй</div>
<div class="p">Третий</div>
<div class="p">Четвертый</div>

<button class="btn">num</button>

<script>

</script>


</body>
</html>

drakulawz 07.09.2018 12:50

Цитата:

Сообщение от Dilettante_Pro
num.html(function(){ arr.push(+this.innerHTML)});

Если я правильно понял, то num здесь взят как объект DOM, а не jq. И метод html к ней всё равно применим? А чтобы перебрать и добавить каждый из этих объектов, методом push, используется this.

Dilettante_Pro 07.09.2018 13:01

рони, так нечестно! Обман зрения! Ничего не дописывается!
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  body {
      counter-reset: num;
  }
  .num:after {
      counter-increment: num;
      content: ' 'counter(num);
  }


  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
    var $num = $(".p"),
        btn = $(".btn"),
        tst = $(".test"),
        inp = $("input");
    tst.hide();
    btn.on({
        "click": num
    });
    tst.on({
        "click": test
    });
    function num() {
        $num.addClass('num');
        tst.show();
    }
    function test() {
        var arr = [];
        $num.each(function() { arr.push(this.innerHTML); });
        inp.val(arr);
    }
});
  </script>
</head>

<body>
<div class="p">Первый</div>
<div class="p">Второй</div>
<div class="p">Третий</div>
<div class="p">Четвертый</div>

<button class="btn">num</button>
<button class="test">test</button>
<input type="text">

<script>

</script>


</body>
</html>

Dilettante_Pro 07.09.2018 13:03

Цитата:

Сообщение от drakulawz
num здесь взят как объект DOM

Неправильно. Объект jQuery.
var num = $('.p')


Цитата:

Сообщение от drakulawz
чтобы перебрать и добавить каждый из этих объектов, методом push, используется this

Тоже неправильно.
Перебор выполняет num.html()
this - это конкретный элемент DOM из набора элементов объекта num, получаемый при переборе.

drakulawz 07.09.2018 13:12

Цитата:

Сообщение от Dilettante_Pro
А это что за танцы с бубнами?

Я чё-то подумал, что если не переобъявить эту переменную как jq объект оно работать не будет. :-?

function sort() {
        var val = $.map($num, function(el) {
            return +el.textContent
        }).sort(function(a, b) {
            return a - b
        });
        inp.val(val)
    }

рони, с методом map мне ещё предстоит знакомство. Он создаёт новый масив в котором записаны функции по отношению к элементам массива num. В данном случаи оно создаёт массив цифр, так как в num у нас записаны цифры. Так? А такая запись не правильная была бы +el.text?

function num() {
        $num.addClass('num')
    }

Интересно:write:

drakulawz 07.09.2018 13:23

Цитата:

Сообщение от Dilettante_Pro
Перебор выполняет num.html()

понял. Я думал, что html указывает только на то, что нужно взять из элементов DOM текст, а функцией уже идёт перебор и именно this указывает на то, что там есть несколько элементов которые нужно записать в новый массив методом push.

Dilettante_Pro 07.09.2018 13:26

drakulawz,
$a = a;
ничего не переобъявляет. Это две переменные одинакового типа и одинакового содержания. $ здесь ничего не значит.
Просто программисты для удобства - чтобы лучше видеть в тексте программы переменные с объектами jq и применять к ним соответствующие методы - зачастую используют $ в имени переменных.


Часовой пояс GMT +3, время: 19:40.