【问题标题】:Conflict between jquery "position().top" and css3 "transform: scale()"jquery“position().top”和css3“transform:scale()”之间的冲突
【发布时间】:2017-09-04 01:33:50
【问题描述】:

我正在我的编辑工具中构建一个字体大小调整器,对于这个工具,我将我的文本元素的原点更改为位于左下角。一切都适用于普通版本,但我正在尝试使其与使用 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 做了一些奇怪的事情,文本不会停留在行首,而是在每次输入更改时移动到其他位置。

$(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>

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

【问题讨论】:

    标签: javascript jquery html css css-transforms


    【解决方案1】:

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

    我简化了脚本,在.element规则中改为bottom: 72px

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


    非缩放版本

    $(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

    $(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>

    【讨论】:

    • 我想使用计算还为时过早,因为我不想为跨浏览器兼容性而苦苦挣扎。我将使用底部值
    • @Lindow 我更新了一个版本以满足您启用拖动的需要。
    猜你喜欢
    • 1970-01-01
    • 2012-03-06
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 2012-01-15
    • 1970-01-01
    相关资源
    最近更新 更多