jquery“position()。top”和css3“transform:scale()”之间的冲突

时间:2017-09-02 23:19:31

标签: javascript jquery html css3 css-transforms

我正在编辑工具中构建字体大小调整器,对于这个工具,我将文本元素的原点更改为左下角。一切都适用于普通版本,但我正在尝试使用我使用transform:scale(...)的缩放功能:

所以这是正常的版本,看到文本总是符合行的字体大小:

$(document).on('change', '#fontsize', function() {
  var element = $(".element");
  var fontsize = $(this).val();
  var current_top = element.position().top;
  var height = element[0].getBoundingClientRect().height;
  var bottom = current_top + height;

  console.log('font-size=' + fontsize + ' top=' + current_top + ' height=' + height);

  element.css({
    "font-size": fontsize + 'px',
  }).css({
    top: (current_top - ((current_top + element[0].getBoundingClientRect().height) - bottom)) + 'px'
  })

});
.absolute {
  position: absolute;
  left: 0px;
  width: 100%;
  border-bottom: 1px solid green;
}

.elements {
  background: #eaeaea;
  border: 1px solid red;
  position: relative;
  width: 300px;
  height: 140px;
}

.element {
  position: absolute;
  text-align: left;
  transform: rotate(0deg);
  left: 70px;
  top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="fontsize" type="text" placeholder="Type : '21', '23' or '28'">
<span>Press enter !</span>

<div class="elements">
  <span class="absolute" style="top: 65px; z-index:999;"></span>
  <div class="element" style="">Lindow</div>
</div>

以下是使用transform:scale(...)的版本,正如您在此处所看到的element.position().top做了一些奇怪的事情,文本不会停留在行的顶部,并在每次输入更改时移动到其他地方。 / p>

$(document).on('change', '#fontsize', function() {
  var element = $(".element");
  var fontsize = $(this).val();
  var current_top = element.position().top;
  var height = element[0].getBoundingClientRect().height;
  var bottom = current_top + height;

  console.log('font-size=' + fontsize + ' top=' + current_top + ' height=' + height);

  element.css({
    "font-size": fontsize + 'px',
  }).css({
    top: (current_top - ((current_top + element[0].getBoundingClientRect().height) - bottom)) + 'px'
  })

});
.elements {
  transform:scale(1.5); 
  transform-origin:top left;
}

.absolute {
  position: absolute;
  left: 0px;
  width: 100%;
  border-bottom: 1px solid green;
}

.elements {
  background: #eaeaea;
  border: 1px solid red;
  position: relative;
  width: 300px;
  height: 140px;
}

.element {
  position: absolute;
  text-align: left;
  transform: rotate(0deg);
  left: 70px;
  top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="fontsize" type="text" placeholder="Type : '21', '23' or '28'">
<span>Press enter !</span>

<div class="elements">
  <span class="absolute" style="top: 65px; z-index:999;"></span>
  <div class="element" style="">Lindow</div>
</div>

我想解决这个问题,出了什么问题,应该用什么?

1 个答案:

答案 0 :(得分:1)

当您更改元素的字体大小时,它会增加其高度,并且通过绝对定位,您最好从其bottom位置开始工作,而不是top

我简化了脚本并更改为bottom: 72px规则中的.element

注意,文本底部和绿线之间的间隙属于字体,并随字体大小增加。这是正常的,它基于字体的内部指标,它们也可以/将在字体类型之间有所不同。如果您还需要对此进行补偿,则需要测量使用的字体值并将其添加到计算中(请注意,浏览器和操作系统之间也可能有所不同)。

非缩放版

$(document).on('change', '#fontsize', function() {
  var element = $(".element");
  var fontsize = $(this).val();
  
  console.log('font-size=' + fontsize);

  element.css({
    "font-size": fontsize + 'px',
  })

});
.absolute {
  position: absolute;
  left: 0px;
  width: 100%;
  border-bottom: 1px solid green;
}

.elements {
  background: #eaeaea;
  border: 1px solid red;
  position: relative;
  width: 300px;
  height: 140px;
}

.element {
  position: absolute;
  text-align: left;
  transform: rotate(0deg);
  left: 70px;
  bottom: 72px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="fontsize" type="text" placeholder="Type : '21', '23' or '28'">
<span>Press enter !</span>

<div class="elements">
  <span class="absolute" style="top: 65px; z-index:999;"></span>
  <div class="element" style="">Lindow</div>
</div>

缩放版

$(document).on('change', '#fontsize', function() {
  var element = $(".element");
  var fontsize = $(this).val();
  
  console.log('font-size=' + fontsize);

  element.css({
    "font-size": fontsize + 'px',
  })

});
.elements {
  transform:scale(1.5); 
  transform-origin:top left;
}

.absolute {
  position: absolute;
  left: 0px;
  width: 100%;
  border-bottom: 1px solid green;
}

.elements {
  background: #eaeaea;
  border: 1px solid red;
  position: relative;
  width: 300px;
  height: 140px;
}

.element {
  position: absolute;
  text-align: left;
  transform: rotate(0deg);
  left: 70px;
  bottom: 72px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="fontsize" type="text" placeholder="Type : '21', '23' or '28'">
<span>Press enter !</span>

<div class="elements">
  <span class="absolute" style="top: 65px; z-index:999;"></span>
  <div class="element" style="">Lindow</div>
</div>

<强>更新

如果您仍希望将其基于top值,则需要获取scale()值,然后使用旧height之间的差异来调整top 1}}值

$(document).on('change', '#fontsize', function() {
  var element = $(".element");
  var scale = (element[0].getBoundingClientRect().width / element[0].offsetWidth);  
  var fontsize = $(this).val();
  var top = element.position().top / scale;
  var height = element[0].getBoundingClientRect().height / scale;

  element.css({
    "font-size": fontsize + 'px',
  }).css({
    top: top - ((element[0].getBoundingClientRect().height / scale) - height) + 'px'
  })

});
.elements {
  transform:scale(1.5); 
  transform-origin:top left;
}

.absolute {
  position: absolute;
  left: 0px;
  width: 100%;
  border-bottom: 1px solid green;
}

.elements {
  background: #eaeaea;
  border: 1px solid red;
  position: relative;
  width: 300px;
  height: 140px;
}

.element {
  position: absolute;
  text-align: left;
  transform: rotate(0deg);
  left: 70px;
  top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="fontsize" type="text" placeholder="Type : '21', '23' or '28'">
<span>Press enter !</span>

<div class="elements">
  <span class="absolute" style="top: 65px; z-index:999;"></span>
  <div class="element" style="">Lindow</div>
</div>