拖拽排序、添加、移除

根据dom元素位置

<!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>
    * {
      padding: 0;
      margin: 0;
    }

    li {
      list-style: none;
    }

    .drag-wrap {
      position: relative;
      width: 300px;
    }

    .drag-wrap .drag-item {
      transition: unset;
      z-index: 2;
    }

    .drag-wrap li {
      box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);

      position: absolute;
      width: 180px;
      /* margin: 10px; */
      height: 90px;
      user-select: none;
      background-color: blueviolet;
      transition: left 0.3s ease-in-out,
        top 0.3s ease-in-out;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  </style>
</head>

<body>
  <div id="drag-wrap" style="margin: 200px;">
    <ul class="drag-wrap" id="drag-wrap-top">
      <li>
        <h1>1</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>2</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>3</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>4</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>5</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>6</h1>
        <p>888888</p>
      </li>

    </ul>
    <p style="height: 50px;">——————————————</p>
    <ul class="drag-wrap" id="drag-wrap-bottom">
      <li>
        <h1>1</h1>
        <p>------</p>
      </li>
      <li>
        <h1>2</h1>
        <p>------</p>
      </li>
      <li>
        <h1>3</h1>
        <p>------</p>
      </li>
      <li>
        <h1>4</h1>
        <p>------</p>
      </li>
      <li>
        <h1>5</h1>
        <p>------</p>
      </li>
      <li>
        <h1>6</h1>
        <p>------</p>
      </li>
      <li>
        <h1>7</h1>
        <p>------</p>
      </li>
      <li>
        <h1>8</h1>
        <p>------</p>
      </li>
      <li>
        <h1>9</h1>
        <p>------</p>
      </li>
      <li>
        <h1>10</h1>
        <p>------</p>
      </li>
      <li>
        <h1>11</h1>
        <p>------</p>
      </li>
      <li>
        <h1>12</h1>
        <p>------</p>
      </li>
    </ul>
  </div>
  <script>
    var dragObj = {
      setGroupHeight() {
        this.el.style.height = this.nodeHeight * Math.ceil(this.nodeList.length / this.nodeNumber) + 'px'
        this.enterEl.style.height = this.nodeHeight * Math.ceil(this.enternodeList.length / this.nodeNumber) + 'px'
      },

      /**
       * 给每个节点进行一次排序
       * @param {Array} 元素节点数组
       */
      sortNodePosition(nodeList) {
        nodeList.forEach(node => {
          node.style.left = node.sort % this.nodeNumber * this.nodeWidth + 'px';
          node.style.top = Math.floor(node.sort / this.nodeNumber) * this.nodeHeight + 'px';
        })
      },

      /**
       * 获取父标签
       */
      getParentNode(node, tagName = 'LI') {
        let liNode = null;
        function getLiNode(node) {
          if (node.tagName.toUpperCase() === 'HTML') {
            liNode = null;
          }
          else if (node.tagName.toUpperCase() === tagName) {
            liNode = node;
          } else {
            getLiNode(node.parentNode)
          }
        }
        getLiNode(node)
        return liNode;
      },

      el: null,
      enterEl: null,
      // 节点宽度
      nodeWidth: 200,
      // 节点高度
      nodeHeight: 100,
      // 每行节点个数
      nodeNumber: 3,
      // 容器下所有卡片的节点
      nodeList: [],
      enternodeList: [],

      init() {
        this.el = document.getElementById('drag-wrap-top');
        this.enterEl = document.getElementById('drag-wrap-bottom');

        this.nodeList = [...this.el.children];
        this.nodeList.forEach((node, index) => {
          node.setAttribute('draggable', true)
          node.sort = index;
        });
        this.sortNodePosition(this.nodeList)

        this.enternodeList = [...this.enterEl.children];
        this.enternodeList.forEach((node, index) => {
          node.setAttribute('draggable', true)
          node.sort = index;
        });
        this.sortNodePosition(this.enternodeList)
        this.el.addEventListener('dragstart', (e) => {
          this.target = this.getParentNode(e.target);
          this.target.classList.add('drag-item')
        })
        this.el.addEventListener('dragenter', (e) => {
          let toTarget = this.getParentNode(e.target);

          // 拖到li上面,排除自己上面
          if (toTarget && toTarget !== this.target) {
            // 不同的父标签(ul)
            if (toTarget.parentNode.id !== this.target.parentNode.id) {
              toTarget.parentNode.appendChild(this.target);
              this.removeNodeSort(this.target.sort, this.enternodeList);
              this.appendNodeSort(this.target, toTarget.sort, this.nodeList)
              this.setGroupHeight();
            }
            // 相同的父标签(ul)
            else {
              this.changeNodeSort(toTarget.sort, this.nodeList);
            }
          }
          // 如果直接拖动ul空白处
          else if (e.target.id === this.el.id && this.target.parentNode.id !== e.target.id) {
            e.target.appendChild(this.target);
            this.removeNodeSort(this.target.sort, this.enternodeList);
            this.appendNodeSort(this.target, this.nodeList.length, this.nodeList)
            this.setGroupHeight();
          }
        })
        this.el.addEventListener('dragend', (e) => {
          this.target.classList.remove('drag-item')
        })

        this.enterEl.addEventListener('dragstart', (e) => {
          this.target = this.getParentNode(e.target);
          this.target.classList.add('drag-item')
        })

        this.enterEl.addEventListener('dragenter', (e) => {
          let toTarget = this.getParentNode(e.target);
          // 拖到li上面,排除自己上面
          if (toTarget && toTarget !== this.target) {
            // 不同的父标签(ul)
            if (toTarget.parentNode.id !== this.target.parentNode.id) {
              toTarget.parentNode.appendChild(this.target);
              this.removeNodeSort(this.target.sort, this.nodeList);
              this.appendNodeSort(this.target, toTarget.sort, this.enternodeList)
              this.setGroupHeight();
            }
            // 相同的父标签(ul)
            else {
              this.changeNodeSort(toTarget.sort, this.enternodeList);
            }
          }
          // 如果直接拖动ul空白处
          else if (e.target.id === this.enterEl.id && this.target.parentNode.id !== e.target.id) {
            e.target.appendChild(this.target);
            this.removeNodeSort(this.target.sort, this.nodeList);
            this.appendNodeSort(this.target, this.enternodeList.length, this.enternodeList)
            this.setGroupHeight();
          }
        })
        this.enterEl.addEventListener('dragend', (e) => {
          this.target.classList.remove('drag-item')
        })

        this.setGroupHeight();
      },


      removeNodeSort(oldSort, nodeList) {
        let nodeIndex = nodeList.findIndex(node => node.sort === oldSort);
        nodeList.splice(nodeIndex, 1)
        nodeList.forEach((node, index) => {
          if (node.sort > oldSort) node.sort--;
        })
        // 把除了当前节点的,所有节点都重新排序下位置
        this.sortNodePosition(nodeList);
      },

      appendNodeSort(dragNode, newSort, nodeList) {
        nodeList.forEach(node => {
          if (node.sort >= newSort) node.sort++;
        })
        // 给当前节点排序重新赋值,不要漏了这个
        nodeList.push(dragNode);
        dragNode.sort = newSort

        // 把除了当前节点的,所有节点都重新排序下位置
        this.sortNodePosition(nodeList);
      },

      /**
       * 计算出需要排序变化的节点,改变节点sort属性
       */
      changeNodeSort(newSort, nodeList) {
        // 在移动过程中,当前节点sort没有改变,不需要重复计算排序。
        var oldSort = this.target.sort;
        if (newSort !== oldSort) {
          nodeList.forEach(node => {
            // 往前移动,老位置 - 新位置(包含)之间的所有节点,排序都加1
            if (newSort < oldSort) {
              if (node.sort >= newSort && node.sort < oldSort) node.sort++;
            }
            // 往后移动,老位置 - 新位置(包含)之间的所有节点,排序都减1
            else {
              if (node.sort <= newSort && node.sort > oldSort) node.sort--;
            }
          })
          // 给当前节点排序重新赋值,不要漏了这个
          this.target.sort = newSort
          // 把除了当前节点的,所有节点都重新排序下位置
          this.sortNodePosition(nodeList);
        }
      },
    }

    dragObj.init();
  </script>
</body>

</html>

根据鼠标位置

image.png
<!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>拖拽排序</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    li {
      list-style: none;
    }

    .drag-wrap {
      position: relative;
      width: 500px;
    }

    .drag-wrap .drag-item {
      transition: unset;
      z-index: 2;
    }

    .drag-wrap li {
      box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);

      position: absolute;
      width: 90px;
      margin: 5px;
      height: 60px;
      user-select: none;
      background-color: blueviolet;
      transition: left 0.3s ease-in-out,
        top 0.3s ease-in-out;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  </style>
</head>

<body>
  <div id="drag-wrap" style="margin: 200px;">

    <ul class="drag-wrap" id="drag-wrap-top">
      <li>
        <h1>1</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>2</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>3</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>4</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>5</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>6</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>7</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>8</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>9</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>10</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>11</h1>
        <p>888888</p>
      </li>
      <li>
        <h1>12</h1>
        <p>888888</p>
      </li>
    </ul>
    <p draggable="true" style="height: 100px;">123</p>
    <ul class="drag-wrap" id="drag-wrap-bottom">
      <li>
        <h1>1</h1>
        <p>------</p>
      </li>
      <li>
        <h1>2</h1>
        <p>------</p>
      </li>
      <li>
        <h1>3</h1>
        <p>------</p>
      </li>
      <li>
        <h1>4</h1>
        <p>------</p>
      </li>
      <li>
        <h1>5</h1>
        <p>------</p>
      </li>
      <li>
        <h1>6</h1>
        <p>------</p>
      </li>
      <li>
        <h1>7</h1>
        <p>------</p>
      </li>
      <!-- <li>
        <h1>8</h1>
        <p>------</p>
      </li>
      <li>
        <h1>9</h1>
        <p>------</p>
      </li>
      <li>
        <h1>10</h1>
        <p>------</p>
      </li>
      <li>
        <h1>11</h1>
        <p>------</p>
      </li>
      <li>
        <h1>12</h1>
        <p>------</p>
      </li> -->
    </ul>
  </div>
  <script>
    var bian = false
    function dragSort() {
      return {
        // 容器元素
        el: null,
        enterEl: null,
        // 节点宽度
        nodeWidth: 100,
        // 节点高度
        nodeHeight: 70,
        // 每行节点个数
        nodeNumber: 5,
        // 容器下所有卡片的节点
        nodeList: [],
        // 记录拖拽中,被拖拽节点的序号;防止重复排序
        index: 0,

        /**
         * 获取父标签
         */
         getParentNode(node, tagName = 'LI') {
          let liNode = null;
          function getLiNode(node) {
            if (node.tagName.toUpperCase() === 'HTML') {
              liNode = null;
            }
            else if (node.tagName.toUpperCase() === tagName) {
              liNode = node;
            } else {
              getLiNode(node.parentNode)
            }
          }
          getLiNode(node)
          return liNode;
        },

        /**
         * 给每个节点进行一次排序
         * @param {Array} 元素节点数组
         */
        sortNodePosition(nodeList) {
          nodeList.forEach(node => {
            node.style.left = node.sort % this.nodeNumber * this.nodeWidth + 'px';
            node.style.top = Math.floor(node.sort / this.nodeNumber) * this.nodeHeight + 'px';
          })
        },

        getChild() {
          // 获取容器下所有卡片的节点
          this.nodeList = [...this.el.children];
          this.el.style.height = this.nodeHeight * Math.ceil(this.nodeList.length / this.nodeNumber) + 'px'
          // 给所有节点初始化序号,绑定事件
          this.nodeList.forEach((node, index) => {
            node.setAttribute('draggable', true)
            node.sort = index;
          });
          this.enternodeList = [...this.enterEl.children];
          this.enterEl.style.height = this.nodeHeight * Math.ceil(this.enternodeList.length / this.nodeNumber) + 'px'
          // 给所有节点初始化序号,绑定事件
          this.enternodeList.forEach((node, index) => {
            node.setAttribute('draggable', true)
            node.sort = index;
          });
        },

        init(el, enterEl) {
          this.el = el;
          this.enterEl = enterEl;
          document.getElementById('drag-wrap').addEventListener('dragstart', this.addDragEvent.bind(this));
          this.getChild()
          // 进行第一次排序
          this.sortNodePosition(this.nodeList);
          this.sortNodePosition(this.enternodeList);
          this.el.addEventListener('dragover', (e)  => {
            if (this.el.id !== this.target.parentNode.id) {
              let rect = this.el.getBoundingClientRect()

              let xNumer = Math.round((e.clientX - rect.left) / this.nodeWidth) - 1;
              this.styleLeft = xNumer * this.nodeWidth;
              this.styleTop = 0;

              this.startLeft = this.styleLeft + this.relativeX + rect.left;
              this.startTop = rect.top + this.relativeY;

              bian = 'drag-wrap-top'
              
              this.el.appendChild(this.target);

            }
          }, true)
          this.enterEl.addEventListener('dragover', (e)  => {
            console.log('-----------------')
            if (this.enterEl.id !== this.target.parentNode.id) {
              let rect = this.enterEl.getBoundingClientRect()

              

              let xNumer = Math.round((e.clientX - rect.left) / this.nodeWidth) - 1;
              this.styleLeft = xNumer * this.nodeWidth;
              this.styleTop = 0;
              // console.log(xNumer, '------')
              
              this.startLeft = this.styleLeft + this.relativeX + rect.left;
              this.startTop = rect.top + this.relativeY;
              console.log(this.startTop)

              bian = 'drag-wrap-bottom'
              
              this.enterEl.insertBefore(this.target, this.enterEl.firstChild);
            }
          }, true)
        },

        

        /**
         * 绑定拖拽事件
         * @param {Object} e  事件对象
         */
        addDragEvent(e) {
          // 当前拖拽的节点
          let { target } = e;
          this.target = target = this.getParentNode(target);

          // 增加class,取消动效,防止拖拽掩饰;增加zIndex层级
          target.className = 'drag-item';
          this.styleLeft = parseInt(target.style.left);
          this.styleTop = parseInt(target.style.top);
          this.startLeft = e.clientX;
          this.startTop = e.clientY;
          // 鼠标按下坐标,相对于target元素 左上角的位置差
          this.relativeX = e.clientX - target.getBoundingClientRect().x;
          this.relativeY = e.clientY - target.getBoundingClientRect().y;
          console.log(this.relativeX, this.relativeY)

          // 拖动节点
          const mousemoveFn = (moveEvent) => {
            // console.log(this.startLeft)
            let endLeft = this.styleLeft + (moveEvent.clientX - this.startLeft),
              endTop = this.styleTop + (moveEvent.clientY - this.startTop);
            if (bian === 'drag-wrap-top') {
              this.removeNodeSort(this.target.sort, this.enternodeList) 
              this.appendNodeSort(this.target, endLeft, endTop, this.nodeList);
            } else if (bian === 'drag-wrap-bottom') {
              this.removeNodeSort(this.target.sort, this.nodeList) 
              this.appendNodeSort(this.target, endLeft, endTop, this.enternodeList);

            } 
              this.changeNodeSort(target, endLeft, endTop, target.parentNode.id === 'drag-wrap-top' ? this.nodeList:this.enternodeList);
            
            bian = '';
            
          }
          document.getElementById('drag-wrap').addEventListener('dragover', mousemoveFn);

          // 释放拖动的节点
          const mouseupFn = () => {
            // 因为移动的时候要保证移动位置,不能对当前节点排序,所有鼠标释放,进行下排序
            // this.sortNodePosition([target]);
            setTimeout(() => { target.removeAttribute('class') });
            // 这步可以不做,为了和谷歌一样,把dom也进行排序
            this.sortDom(this.el, this.nodeList);
            this.sortDom(this.enterEl, this.enternodeList);
            document.getElementById('drag-wrap').removeEventListener('dragover', mousemoveFn);
            document.getElementById('drag-wrap').removeEventListener('dragend', mouseupFn);
          }
          document.getElementById('drag-wrap').addEventListener('dragend', mouseupFn);


          

        },


        /**
         * 计算出需要排序变化的节点,改变节点sort属性
         */
        changeNodeSort(dragNode, x, y, nodeList) {
          // 元素移动:水平方向超过 nodeWidth 一半,算sort+1;垂直方向超过 nodeHeight 一半,算进入到下一排(sort + nodeNumber)
          var newSort = Math.max(Math.round(y / this.nodeHeight), 0) * this.nodeNumber + Math.round(x / this.nodeWidth);
          newSort = newSort > nodeList.length - 1 ? nodeList.length - 1 : newSort;
          newSort = newSort < 0 ? 0 : newSort;
          // 在移动过程中,当前节点sort没有改变,不需要重复计算排序。
          if (newSort !== this.index) {
            this.index = newSort;
            var oldSort = dragNode.sort;
            nodeList.forEach(node => {
              // 往前移动,老位置 - 新位置(包含)之间的所有节点,排序都加1
              if (newSort < oldSort) {
                if (node.sort >= newSort && node.sort < oldSort) node.sort++;
              }
              // 往后移动,老位置 - 新位置(包含)之间的所有节点,排序都减1
              else {
                if (node.sort <= newSort && node.sort > oldSort) node.sort--;
              }
            })
            // 给当前节点排序重新赋值,不要漏了这个
            dragNode.sort = newSort
            // 把除了当前节点的,所有节点都重新排序下位置
            this.sortNodePosition(nodeList);
          }
        },

        removeNodeSort(oldSort, nodeList) {
          console.log(oldSort)
          let nodeIndex = nodeList.findIndex(node => node.sort === oldSort);
          // console.log(nodeIndex)
          nodeList.splice(nodeIndex, 1)
          nodeList.forEach((node,index) => {
            if (node.sort > oldSort) node.sort--;
          })
          // 把除了当前节点的,所有节点都重新排序下位置
          this.sortNodePosition(nodeList);
        },

        appendNodeSort(dragNode, x, y, nodeList) {
          nodeList.push(dragNode);
          // 元素移动:水平方向超过 nodeWidth 一半,算sort+1;垂直方向超过 nodeHeight 一半,算进入到下一排(sort + nodeNumber)
          var newSort = Math.max(Math.round(y / this.nodeHeight), 0) * this.nodeNumber + Math.round(x / this.nodeWidth);
          newSort = newSort > nodeList.length - 1 ? nodeList.length - 1 : newSort;
          newSort = newSort < 0 ? 0 : newSort;
          console.log(newSort, 'newSort')
          // 给当前节点排序重新赋值,不要漏了这个
          dragNode.sort = newSort
          nodeList.forEach(node => {
            if (node.sort >= newSort) node.sort++;
          })
          
          // 把除了当前节点的,所有节点都重新排序下位置
          this.sortNodePosition(nodeList);
        },

        /**
         * 对DOM排序
         */
        sortDom(dom, nodeList) {
          let newSortWrap = document.createDocumentFragment();
          nodeList = [...dom.children].sort((a, b) => a.sort - b.sort);
          nodeList.forEach(node => {
            newSortWrap.appendChild(node);
          });
          dom.appendChild(newSortWrap);
        },
      }
    }

      dragSort().init(document.querySelector('#drag-wrap-top'), document.querySelector('#drag-wrap-bottom'));
      // dragSort().init(document.querySelector('#drag-wrap-bottom'), document.querySelector('#drag-wrap-top'));

  </script>
</body>

</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容