为什么 jQuery 小部件的绝对定位是错误的?

Why is absolute positioning of a jQuery widget wrong?

我已经准备好 a complete example 演示我的问题:

我的上下文是:在 2 列中 table 我想在左侧显示一个玩家列表,在右侧显示一个有 2 个玩家的游戏。

为了显示播放器,我准备了一个基于 div 和 CSS position: relative; 的 jQuery UI 小部件,它在列表中运行良好左边的玩家。

但是在右侧,我试图将同一个小部件与 CSS position: absolute; 一起使用两次,由于某些原因,"Ms. Left" 和 "Mr. Right" 的位置就好像他们的 parent 将是 body 而不是 #gameTd.

为什么会发生这种情况以及如何相对于 #gameTd 定位 2 个 div?

HTML:

<table border="1" width="100%">
  <tr>
    <th>Lobby</th>
    <th>Game</th>
  </tr>
  <tr>
    <td id="lobbyTd"></td>
    <td id="gameTd">
      <div id="leftPlayer"></div>
      <div id="rightPlayer"></div>
    </td>
  </tr>
</table>

CSS:

#lobbyTd {
  width: 25%;
  overflow-y: scroll;
}

#gameTd {
  background: #6C6;
}

.my-player {
  position: relative;
  background: #FFF no-repeat center;
  background-size: contain;
  box-shadow: 0 0 32px rgba(0, 0, 0, 0.2);
  margin: 8px;
  width: 160px;
  height: 120px;
}

.my-player-name {
  position: absolute;
  font-size: 18px;
  background: #FFF;
  color: #000;
  left: 0;
  bottom: 0;
  padding: 2px;
  width: 154px;
  height: 20px;
}

Javascript:

jQuery(document).ready(function($) {
  var PHOTO_PATTERN = /^https?:\/\/\S+/i;

  $.widget('my.player', {
    // default options
    options: {
      name: '',
      photo: 'https://slova.de/raspasy/images/male_happy.png',
    },

    _create: function() {
      this._hoverable(this.element);

      this.element.addClass('my-player');

      this.nameDiv = $('<div/>', {
        'class': 'my-player-name'
      }).appendTo(this.element);

      this._refresh();
    },

    _destroy: function() {
      this.nameDiv.remove();
      this.element.removeClass('my-player');
    },

    _setOptions: function() {
      this._superApply(arguments);
      this._refresh();
    },

    _refresh: function() {
      var photo = (PHOTO_PATTERN.test(this.options.photo) ? this.options.photo : 'https://slova.de/raspasy/images/male_happy.png');
      this.element.css('background-image', 'url("' + photo + '")');
      this.nameDiv.text(this.options.name);
    }
  });


  var lobbyPlayer1 = $('<div/>').player({
    name: 'Player #1'
  }).appendTo($('#lobbyTd'));

  var lobbyPlayer1 = $('<div/>').player({
    name: 'Player #2',
    photo: 'https://slova.de/raspasy/images/female_sad.png'
  }).appendTo($('#lobbyTd'));

  var lobbyPlayer3 = $('<div/>').player({
    name: 'Alexander',
    photo: 'http://afarber.de/images/farber.jpg'
  }).appendTo($('#lobbyTd'));

  // Why is absolute positioning wrong below?
  var leftPlayer = $('#leftPlayer').player({
    name: 'Ms. Left',
    photo: 'https://slova.de/raspasy/images/female_happy.png'
  }).css({
    position: 'absolute',
    left: '30px',
    top: '20px'
  });
  var rightPlayer = $('#rightPlayer').player({
    name: 'Mr. Right',
    photo: 'https://slova.de/raspasy/images/male_sad.png'
  }).css({
    position: 'absolute',
    right: '30px',
    top: '20px'
  });
});

您需要为 #gameTd 添加 position: relative 以相对于此块进行定位。

您应该将 position : relative 添加到父级 <td>(其中包含 #gameTd),方法是将其分配给其中的所有绝对定位元素它的(父)块。

将代码中的行更改为

 <td id="gameTd" style="position:relative">