【问题标题】:Tool tip in htmlhtml中的工具提示
【发布时间】:2021-02-11 00:53:38
【问题描述】:

我有一个 div 需要使用线条和框(将包含一条消息)来识别,如下面的模型图像所示。2 和 3(线条和矩形框)相互固定并可拖动,1 (线)可以向任何方向拉伸。我已经创建了这个盒子,但我无法弄清楚如何在它上面附加一条线。这是我尝试过的。

JSFIDDLE

js

const $b1 = $("#box1");
const $b2 = $("#box2");
const $line = $("#line");

const coordinates = function() {
debugger;
  const x1 = $b1.offset().left;
  const y1 = $b1.offset().top + $b1.height()/2;
  const x2 = $b2.offset().left + $b1.width()/2;
  const y2 = $b2.offset().top + $b1.height()/2;

  moveLine(x1, y1, x2, y2);  
}

coordinates();

function moveLine(x1, y1, x2, y2) {
    var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
    var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
    var transform = 'rotate(' + angle + 'deg)';

    offsetX = (x1 > x2) ? x2 : x1;
    offsetY = (y1 > y2) ? y2 : y1;
    
    $line.css({
        'position': 'absolute',
        '-webkit-transform': transform,
        '-moz-transform': transform,
        'transform': transform
      })
      .width(length)
      .offset({
        left: offsetX,
        top: offsetY
      });
}

$('#box1').draggable({
  drag: coordinates
});

HTML

<div class="box" id="box1">10%</div>
<p id="box2">www.google.com</p>

<div class="line" id="line"></div>

css

.box {
  border: 1px solid black;
  background-color: #ffffff;
  width: 100px;
  height: 40px;
  position: absolute;
}

#line1 {
  top: 100px;
  left: 50px;
  /*transform: rotate(222deg);
    -webkit-transform: rotate(222deg);
    -ms-transform: rotate(222deg);*/
}

.line {
  width: 1px;
  height: 1px;
  background-color: black;
  position: absolute;
  z-index: -1; /* put line behind the boxes */
}


#box1 {
  top: 150px;
  left: 150px;
}

#box2 {
  top: 200px;
  left: 200px;
  position:relative;
}

【问题讨论】:

  • 工具提示在哪里?
  • 一二三的盒子

标签: javascript html jquery plugins


【解决方案1】:

我使用 SVG 来定义线条。

很抱歉它不在 jQuery 中。

// Thanks to: https://developer.mozilla.org/en-US/docs/Web/API/Document/drag_event
// Thanks to: https://stackoverflow.com/a/6239882/2182349

// This is demo code - obviously it could be refined

let tooltip = document.getElementById("tooltip");

document.addEventListener("dragstart", function(event) {
  // store a ref. on the tooltip elem
  tooltip = event.target;
  // make it half transparent
  event.target.style.opacity = .5;
  let style = window.getComputedStyle(event.target, null);
  event.dataTransfer.setData("text/plain",
    (parseInt(style.getPropertyValue("left"), 10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"), 10) - event.clientY));
}, false);

document.addEventListener("dragend", function(event) {
  // reset the transparency
  event.target.style.opacity = "";
}, false);

/* events fired on the drop targets */
document.addEventListener("dragover", function(event) {
  // prevent default to allow drop
  event.preventDefault();
}, false);

document.addEventListener("drop", function(event) {
  // prevent default action (open as link for some elements)
  event.preventDefault();
  let offset = event.dataTransfer.getData("text/plain").split(',');
  tooltip.style.left = (event.clientX + parseInt(offset[0], 10)) + 'px';
  tooltip.style.top = (event.clientY + parseInt(offset[1], 10)) + 'px';
  drawLine(tooltip);
}, false);

let clientRect = document.getElementById("anchor").getBoundingClientRect();
let line = document.getElementById("line");
let points = line.points;
let first = points.getItem(0);
first.x = clientRect.x + clientRect.width / 2;
first.y = clientRect.y + clientRect.height / 2;

drawLine(tooltip);

function drawLine(endElement) {
  let clientRect = endElement.getBoundingClientRect();
  let line = document.getElementById("line");
  let points = line.points;
  let last = points.getItem(2);
  last.x = clientRect.x + clientRect.width / 2;
  last.y = clientRect.y + clientRect.height / 2;
  let length = Math.sqrt(Math.pow(first.x - last.x, 2) + Math.pow(first.y - last.y, 2));
  let middle = points.getItem(1);
  if (first.x > last.x) length = -length;
  middle.x = first.x + length / 2;
  middle.y = (first.y > last.y) ? last.y : first.y;
}
body {
  margin: 0;
  padding: 0;
}

.box {
  position: relative;
  background: #fff;
  display: inline-block;
  border: 1px solid #000;
  width: auto;
  padding: 3px;
  text-align: center;
}

#anchor {
  top: 150px;
  left: 100px;
}

#tooltip {
  top: 10px;
  left: 400px;
}

svg {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -100;
  width: 100%;
  height: 100%;
}
<svg height="200" width="500">
        <polyline id="line" points="0,0 0,0 0,0" style="fill:none;stroke:black;" />
        </svg>
<div id="tooltip" class="box" draggable="true">
  Tool tip
</div>
<div id="anchor" class="box">www.google.com</div>

【讨论】:

  • jquery有没有可能,我有这个从jsfiddle.net/saurabh97/q0yn6j2t/1开始
  • 我修好了。 jsfiddle.net/saurabh97/pu3hrqc1/28 。但是当我将盒子左侧移动时,盒子在右侧时的行为是不一样的
  • jsfiddle.net/06pnzk32 - 如果你使用盒子的中心作为锚点,而不是边缘,效果会更好。显然,这可以改进,但使用 的一般方法似乎还可以。
  • 我在此处发布的代码(在 stackoverflow 中)比我的小提琴要好。
  • 现在看起来不错,但是在您的示例中,您可以划一条线将其指向框的开头而不是框的中间jsfiddle.net/saurabh97/uzmt0865/14
【解决方案2】:

如果段 2 不应该响应,您可以使用 :before 元素并调整段 1 的左侧偏移:

const $b1 = $("#box1");
const $b2 = $("#box2");
const $line = $("#line");

const coordinates = function() {
  const x1 = $b1.offset().left;
  const y1 = $b1.offset().top + $b1.height() / 2;
  const x2 = $b2.offset().left + $b1.width() / 2;
  const y2 = $b2.offset().top + $b1.height() / 2;

  moveLine(x1, y1, x2, y2);
}

coordinates();

function moveLine(x1, y1, x2, y2) {
  var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
  var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
  var transform = 'rotate(' + angle + 'deg)';

  offsetX = (x1 > x2) ? x2 : x1;
  offsetY = (y1 > y2) ? y2 : y1;

  $line.css({
      'position': 'absolute',
      '-webkit-transform': transform,
      '-moz-transform': transform,
      'transform': transform
    })
    .width(length)
    .offset({
      left: offsetX - 20, // remove segment 2's width
      top: offsetY
    });
}

$('#box1').draggable({
  drag: coordinates
});
.box {
  border: 1px solid black;
  background-color: #ffffff;
  width: 100px;
  height: 40px;
  right: 0;
  position: absolute;
}

.box:before {
  position: absolute;
  transform: translate(-100%, -50%);
  top: 50%;
  content: '';
  width: 20px;
  height: 1px;
  background: black;
}

#line1 {
  top: 100px;
  left: 50px;
  /*transform: rotate(222deg);
    -webkit-transform: rotate(222deg);
    -ms-transform: rotate(222deg);*/
}

.line {
  width: 1px;
  height: 1px;
  background-color: black;
  position: absolute;
  z-index: -1;
  /* put line behind the boxes */
}

#box1 {
  top: 150px;
  left: 150px;
}

#box2 {
  top: 200px;
  left: 200px;
  position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>


<div class="box" id="box1">10%</div>
<p id="box2">www.google.com</p>

<div class="line" id="line"></div>

【讨论】:

  • 当我们拖拽框的时候,连接处有缝隙,是否可以去掉。
  • @user3690061 遗憾的是,这种延迟来自库 jquery-ui 本身,因此很难修复它。一种解决方法是添加一个圆形连接器以在拖动时隐藏此间隙。这是一个例子:jsfiddle.net/zpx7vueo/13
  • 不错的尝试,或者是否可以仅将 1 和 2 作为单行
  • 嗯,你这是什么意思?
  • 您能否使用 svg 看到以下答案,如果它可以帮助您消除延迟?我也在努力
【解决方案3】:

我建议您使用 png 图像作为线条部分或 svg。这会容易得多。

简短回答,因为上面其他人已经给出了代码。

【讨论】:

    【解决方案4】:

    这里有一些 CSS。对于工具提示容器,使用class="tooltip",对于工具提示文本的&lt;span&gt;,使用class="tooltiptext"

    .tooltip{position:relative;display:inline-block;
    border-bottom: 1px dotted black; /* if you want dots under the hoverable text */
    }
    .tooltip .tooltiptext{visibility:hidden;width:120px;
    background: #555; /* or whatever color you want the tool tip background to be */
    color: #fff; /* or whatever color you want the tool tip text to be */
    text-align:center;padding:5px 0;border-radius:6px;position:absolute;
    z-index:1;bottom:125%;left:50%;margin-left:-60px;opacity:0;transition:opacity 0.3s;}
    .tooltip .tooltiptext::after{content:"";
    position:absolute;top:100%;left:50%;margin-left:-5px;border-width:5px;
    border-style:solid;border-color:#555 transparent transparent transparent;}
    .tooltip:hover .tooltiptext{visibility:visible;opacity:1;}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 1970-01-01
      • 2015-12-26
      • 2014-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多