fe-hunter icon indicating copy to clipboard operation
fe-hunter copied to clipboard

实现两个Li标签的交换

Open BetaSu opened this issue 2 years ago • 9 comments

要回答的问题

将如下DOM片段中的第一个li标签和第三个li标签交换位置。请按照如下顺序作答:

  1. 使用JS实现
  2. 不使用JS,只使用CSS实现
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

最佳答案评选标准

  1. 多种实现方式并简要阐明它们的优劣是加分项
  2. 不过度设计,代码简洁优雅是加分项

最佳答案

悬赏中,欢迎作答...

答题同学须知

  • 答题规范:请在一次评论中完成作答,后续修改也请编辑该评论,而不是追加新的评论

  • 评选标准:最佳答案由围观同学的 👍 和卡颂共同决定

  • 评选时间:一般是问题发布24小时后评选,如果问题发布当天回答数较少,问题悬赏金额可能增加,同时悬赏时间也会增加

围观同学须知

  • 对于你满意的答案,请不要吝惜你的 👍,这是评选最佳答案的依据

  • 非答题的评论会被删除,问题相关讨论请在赏金猎人群中进行

BetaSu avatar Apr 12 '22 02:04 BetaSu

const swap = (
  i,
  j,
  a = $$("li")[i],
  b = $$("li")[j],
  t = document.createElement("div"),
  t2 = document.createElement("div")
) =>
  a.replaceWith(t) ||
  b.replaceWith(t2) ||
  t.replaceWith(b) ||
  t2.replaceWith(a);

swap(0, 2)
  <style>
  ul{
    display: flex;
    flex-direction: column;
  }
  </style>
  <ul>
    <li style="order: 3">1</li>
    <li style="order: 2">2</li>
    <li style="order: 1">3</li>
    <li style="order: 4">4</li>
    <li style="order: 5">5</li>
  </ul>

NoBey avatar Apr 12 '22 02:04 NoBey

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- <style>
    // css 想到的是直接利用定位, 缺点就是在dom树中dom的位置是没有变化的, 只是改变了样式位置
    li {
      height: 20px;
      line-height: 20px;
    }

    li:nth-child(1) {
      position: relative;
      top: 40px;
      left: 0;
    }

    li:nth-child(3) {
      position: relative;
      top: -40px;
      left: 0;
    }
  </style> -->
</head>

<body>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
  </ul>
</body>
<script>

  const li = document.getElementsByTagName('li');

  function swapDom() {
    const parent = li[0].parentNode;

    // 利用insertBefore()方法只会对dom节点进行移动不会创建新的节点
    parent.insertBefore(li[2], li[0]);
    parent.insertBefore(li[2], li[1]);
  }

  swapDom();

</script>

</html>

Y-J-H avatar Apr 12 '22 10:04 Y-J-H

js方法insertBefore 只改变位置,不新增节点

function swap(a, b) {
	const min = Math.min(a, b);
	const max = Math.max(a, b);
	const ul = document.querySelector('ul');
	const li = ul.children;

	ul.insertBefore(li[max - 1], li[min - 1]);
	ul.insertBefore(li[min], li[max]);
}
swap(a, b);

css

ul {
  display: flex;
  flex-direction: column;
}
ul li:nth-child(1) {
  order: 3;
}
ul li:nth-child(2) {
  order: 2;
}
ul li:nth-child(3) {
  order: 1;
}
ul li:nth-child(4) {
  order: 4;
}
ul li:nth-child(5) {
  order: 5;
}

注:JS实现中,请考虑头、尾两个节点的边界情况,这时候适用appendChild

minjs1cn avatar Apr 12 '22 10:04 minjs1cn

const liArr = $('ul').innerHTML.trim().split(/\s+/);

[liArr[0], liArr[2]] = [liArr[2], liArr[0]];

$('ul').innerHTML = liArr.join('');




linrunzheng avatar Apr 14 '22 03:04 linrunzheng

使用JS实现:

// 获取ul元素节点
const ul = document.querySelector('ul');
// 获取li元素子节点
const li1 = ul.children[0];
const li3 = ul.children[2];
// 将li3插入到li1之前,实现两个元素的位置交换
ul.insertBefore(li3, li1);

insertBefore() 是DOM API中的一个方法,用于将一个节点插入到指定节点之前。它接受两个参数:要插入的节点和参照节点。

如果参照节点是 null,则相当于 appendChild() 方法,将节点插入到父节点的最后一项。需要注意的是,一旦在 DOM 中移动了一个节点,它的所有事件监听器和数据都将被保留。

不使用JS,只使用CSS实现:

ul {
  display: flex;
  flex-direction: column;
}

li:nth-child(1) {
  order: 3;
}

li:nth-child(3) {
  order: 1;
}

order 是 CSS 中 flex 布局的一个属性,用于指定弹性子元素的排列顺序。它可以接受一个整数值,默认为 0。

order 的工作原理是将所有弹性子元素按照它们的 order 属性进行排序(从小到大)。如果两个元素的 order 属性相等,则按照它们在文档流中出现的顺序进行排序。需要注意的是,order 只改变元素的显示顺序,不影响 DOM 结构。

yvonneit avatar Mar 31 '23 08:03 yvonneit

这是来自QQ邮箱的假期自动回复邮件。   您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。

imondo avatar Mar 31 '23 08:03 imondo

使用JS实现:

const ul = document.querySelector('ul');
const first = ul.firstChild;
const third = first.nextElementSibling.nextElementSibling;
ul.insertBefore(third, first);

不使用JS,只使用CSS实现:

ul li:first-child {
  order: 3;
}
ul li:nth-child(3) {
  order: 1;
}

需要注意的是,这种方式只会改变元素在视觉上的位置,不会对DOM结构产生任何影响。另外,order属性只在flex布局下生效。``

jacksmas avatar Apr 28 '23 07:04 jacksmas

gpt搜的吧

jacksmas @.***> 于2023年4月28日周五 15:05写道:

使用JS实现:

const ul = document.querySelector('ul'); const first = ul.firstChild; const third = first.nextElementSibling.nextElementSibling; ul.insertBefore(third, first);

不使用JS,只使用CSS实现:

ul li:first-child { order: 3; } ul li:nth-child(3) { order: 1; }

需要注意的是,这种方式只会改变元素在视觉上的位置,不会对DOM结构产生任何影响。另外,order属性只在flex布局下生效。``

— Reply to this email directly, view it on GitHub https://github.com/BetaSu/fe-hunter/issues/55#issuecomment-1527090526, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGVHFFKZE2FVEOABEFK4QX3XDNTZZANCNFSM5TFAPAJQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

xingbaoliang avatar May 26 '23 01:05 xingbaoliang

这是来自QQ邮箱的假期自动回复邮件。   您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。

imondo avatar May 26 '23 01:05 imondo