Сортировка неупорядоченного списка статей с использованием JavaScript - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть неупорядоченный список статей, каждая с заголовком и абзацем.Я хотел бы отсортировать эти статьи в алфавитном порядке, используя JavaScript, но я получил неожиданный результат.

Используемая мной функция сортировки JavaScript (изначально взята из: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sort_list), можно увидеть ниже:

function sort() {
  var list, i, switching, b, shouldSwitch;
  list = document.getElementById("courses");
  switching = true;
  /*Make a loop that will continue until
  no switching has been done:*/
  while (switching) {
    //start by saying: no switching is done:
    switching = false;
    b = list.getElementsByTagName("LI");
    //Loop through all list-items:
    for (i = 0; i < (b.length - 1); i++) {
      //start by saying there should be no switching:
      shouldSwitch = false;
      /*check if the next item should
      switch place with the current item:*/
      if (b[i].innerHTML.toLowerCase() > b[i + 1].innerHTML.toLowerCase()) {
        /*if next item is alphabetically
        lower than current item, mark as a switch
        and break the loop:*/
        shouldSwitch= true;
        break;
      }
    }
    if (shouldSwitch) {
      /*If a switch has been marked, make the switch
      and mark the switch as done:*/
      b[i].parentNode.insertBefore(b[i + 1], b[i]);
      switching = true;
    }
  }
}

Полный код можно найти по адресу: https://jsfiddle.net/MihkelPajunen/c37m0w1s/1/

Порядок сортировки должен быть следующим:

  1. CSS
  2. HTML
  3. Java
  4. JavaScript
  5. Python
  6. Ruby

У меня двоякий вопрос: почему мои предположительно отсортированные статьи выглядят так, как они выглядят, и что я должен изменить, чтобы получить алфавитный порядокчто я после?

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

При сравнении текста не следует использовать innerHTML.

Вместо этого используйте innerText MDN .Вот обновленная скрипка с внесенными изменениями:

if (b[i].innerText.toLowerCase() > b[i + 1].innerText.toLowerCase()) {

Хотя я могу понять, как вы ее использовали, так как это делает w3schools.Это одна из многих причин, почему вы должны полностью избегать этого сайта.Еще одна проблема, с которой они сталкиваются, - это использование document.write.Помимо этого, попробуйте использовать примеры более высокого качества в будущем и избегайте w3schools, если вы хотите избежать плохой практики.

Вот некоторые поставщики контента более высокого качества:

0 голосов
/ 26 апреля 2018

В дополнение к другим ответам, здесь представлена ​​значительно упрощенная версия вашего кода.Читаемость еще можно улучшить.Я добавил довольно много дополнительной информации со ссылками на документацию Mozilla Developer Network (MDN), чтобы показать, сколько информации не хватает на сайте W3Schools.


Код

function sort () {
  let container = document.getElementById('courses')
  Array.from(container.querySelectorAll('li > article > h2:first-child'))
    .sort((h2_a, h2_b) => h2_a.innerText.localeCompare(h2_b.innerText))
    .forEach(h2 => container.appendChild(h2.parentElement.parentElement))
}
article {
	border: 1px solid black;
	margin: 10px;
	padding: 10px;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Sorting Articles</title>
  </head>
  <body>
    
    <!-- Hit the button to sort items (at least something happens) -->
		<button onclick="sort()">Sort list items</button><br>
    
    <!-- This section contains six articles-->
    <section>
    	<h1>All courses:</h1>
    	<!-- The articles are structured in an unordered list-->
	    <ul id="courses">
	    	<li>
	    		<!-- Each list item is a complete article -->
	    		<article>
	    			<h2>HTML (1)</h2>
	    			<p>Some text about the HTML course.</p>
	    		</article>
	    	</li>
	    	<li>
	    		<article>
	    			<h2>CSS (2)</h2>
	    			<p>Some text about the css course.</p>
	    		</article>
	    	</li>
	    	<li>
	    		<article>
	    			<h2>JavaScript (3)</h2>
	    			<p>Some text about the JavaScript course.</p>
	    		</article>
	    	</li>
	    	<li>
	    		<article>
	    			<h2>Ruby (4)</h2>
	    			<p>Some text about the Ruby course.</p>
	    		</article>
	    	</li>
	    	<li>
	    		<article>
	    			<h2>Python (5)</h2>
	    			<p>Some text about the Python course.</p>
	    		</article>
	    	</li>
	    	<li>
	    		<article>
	    			<h2>Java (6)</h2>
	    			<p>Some text about the Java course.</p>
	    		</article>
	    	</li>
	    </ul>
    </section>
  </body>
</html>

Объяснение

  1. Получить ссылку на родительский элемент контейнера
    let container = document.getElementById('courses')

  2. Создание списка ссылок на все элементы заголовка.
    container.querySelectorAll('li > article > h2:first-child')

    Функция ParentNode.querySelectorAll()"> .querySelectorAll () используетСинтаксис селектора CSS.

    Возвращает экземпляр NodeList"> NodeList , функциональность которого ограничена по сравнению с экземпляром Array"> Array .Чтобы добавить функциональность, описанную в следующих двух шагах, вы просто применяете преобразование.Array.from(......)

  3. Сортировка списка элементов.
    .sort((h2_a, h2_b) => h2_a.innerText.localeCompare(h2_b.innerText))

    Функция Array.prototype.sort()"> .sort () получает пользовательскую функцию сравнения(здесь сокращено до Arrow Function"> функции стрелки ) в качестве аргумента, который говорит функции сортировки сравнивать .innerText каждой пары <h2> вместо объектов HTMLElement"> HTMLElement .См. ответ от Travis J для получения дополнительной информации о том, почему вы не должны использовать .innerHTML.

    Список содержит только ссылки на эти <h2> элементы, что означает, что их содержание нене копируется во время сортировки.Это было не так в вашем исходном сообщении, это просто на голову.

  4. Повторно вставьте <li> элементы, используя Node.appendChild()"> .appendChild () .
    .forEach(h2 => container.appendChild(h2.parentElement.parentElement))

    Сначала удаляется элемент <li> ( Node.parentElement"> parentElement ) из документа и повторно вставляется в конец его родительского элемента, <ul>, то есть никогда не будет двухиз тех же элементов в этом списке.

    Функция Array.prototype.forEach()"> .forEach () просто применяет это действие к каждому элементу массива.


TLDR

Array.from() // #courses li > article > h2 .sort() // h2.innerText -- error was here .forEach() // appendChild() reinserts it in the end

0 голосов
/ 26 апреля 2018

По иронии судьбы проблема с вашим HTML-комментарием, который рассматривается как часть .innerHTML.Поскольку первая буква комментария (<) считается символом ASCII «меньшего размера», чем C (&#60; против &#67;), статья HTML, содержащая комментарий, сортируется в верхней частисписок в алфавитном порядке.

Простое удаление этого комментария из вашей статьи HTML приводит к сортировке элементов в соответствии с ожиданиями:

//Script borrowed from: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sort_list

function sort() {
  var list, i, switching, b, shouldSwitch;
  list = document.getElementById("courses");
  switching = true;
  /*Make a loop that will continue until
  no switching has been done:*/
  while (switching) {
    //start by saying: no switching is done:
    switching = false;
    b = list.getElementsByTagName("LI");
    //Loop through all list-items:
    for (i = 0; i < (b.length - 1); i++) {
      //start by saying there should be no switching:
      shouldSwitch = false;
      /*check if the next item should
      switch place with the current item:*/
      if (b[i].innerHTML.toLowerCase() > b[i + 1].innerHTML.toLowerCase()) {
        /*if next item is alphabetically
        lower than current item, mark as a switch
        and break the loop:*/
        shouldSwitch = true;
        break;
      }
    }
    if (shouldSwitch) {
      /*If a switch has been marked, make the switch
      and mark the switch as done:*/
      b[i].parentNode.insertBefore(b[i + 1], b[i]);
      switching = true;
    }
  }
}
article {
  border: 1px solid black;
  margin: 10px;
  padding: 10px;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Sorting Articles</title>
</head>

<body>
  <button onclick="sort()">Sort list items</button>
  <section>
    <h1>All courses:</h1>
    <ul id="courses">
      <li>
        <article>
          <h2>HTML (1)</h2>
          <p>Some text about the HTML course.</p>
        </article>
      </li>
      <li>
        <article>
          <h2>CSS (2)</h2>
          <p>Some text about the css course.</p>
        </article>
      </li>
      <li>
        <article>
          <h2>JavaScript (3)</h2>
          <p>Some text about the JavaScript course.</p>
        </article>
      </li>
      <li>
        <article>
          <h2>Ruby (4)</h2>
          <p>Some text about the Ruby course.</p>
        </article>
      </li>
      <li>
        <article>
          <h2>Python (5)</h2>
          <p>Some text about the Python course.</p>
        </article>
      </li>
      <li>
        <article>
          <h2>Java (6)</h2>
          <p>Some text about the Java course.</p>
        </article>
      </li>
    </ul>
  </section>
</body>

</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...