HTML 带有 Java 和 Vaadin 的元素选择器

HTML Element Selector with Java & Vaadin

我目前正在构建一个 Vaadin Webapp,用于从网站获取某些 HTML-Elements 的路径。因此,我想

  1. 在 Vaadin 页面的 IFrame / BrowserFrame 中加载网页
  2. 让用户直观地点击突出显示的 HTML-元素(类似于 http://selectorgadget.com/
  3. 生成路径(XPath 似乎是最好的选择)和
  4. 在 Vaadin 页面的公式中显示它(在同一站点上,以检查选择)

我的问题:

  1. 从 iFrame 内的网站到 Vaadin App 的路径数据真的可以传输吗?
  2. 是否可以使用 Vaadin 应用程序提供的技术选择 html 元素(这样我就不需要 IFrame 中的任何 Javascript)?
  3. 是否有 iFrame 以外的技术可以更好地实现我的目标?

提前致谢!

我已经找到了解决办法: iframe 内的 Javascript 和 VaadinUI 之间的完全交互(因为要构建的组件必须集成到现有的 VaadinUI 中)可以通过以下方式实现:

1. 将脚本、css 和其他需要的 Html 内容注入加载的网页。解决方案的选择脚本取自 here

var elements = {
  top: $('#selector-top'),
  left: $('#selector-left'),
  right: $('#selector-right'),
  bottom: $('#selector-bottom')
};

function registerMouseMove() {
  $(document).mousemove(function(event) {
    if (event.target.id.indexOf('selector') !== -1 || event.target.tagName === 'BODY' || event.target.tagName === 'HTML') return;

    var $target = $(event.target);
    targetOffset = $target[0].getBoundingClientRect(),
      targetHeight = targetOffset.height,
      targetWidth = targetOffset.width;
    //console.log(targetOffset);

    elements.top.css({
      left: (targetOffset.left - 4),
      top: (targetOffset.top - 4),
      width: (targetWidth + 5)
    });
    elements.bottom.css({
      top: (targetOffset.top + targetHeight + 1),
      left: (targetOffset.left - 3),
      width: (targetWidth + 4)
    });
    elements.left.css({
      left: (targetOffset.left - 5),
      top: (targetOffset.top - 4),
      height: (targetHeight + 8)
    });
    elements.right.css({
      left: (targetOffset.left + targetWidth + 1),
      top: (targetOffset.top - 4),
      height: (targetHeight + 8)
    });

  });
};

function unregisterMouseMove() {
  $(document).unbind();
  elements.top.css({
    left: 0,
    top: 0,
    width: 0
  });
  elements.bottom.css({
    top: 0,
    left: 0,
    width: 0
  });
  elements.left.css({
    left: 0,
    top: 0,
    height: 0
  });
  elements.right.css({
    left: 0,
    top: 0,
    height: 0
  });
};

function registerClickListener() {

  $(document).click(function(event) {
    if (event.target.id.indexOf('selector') !== -1 || event.target.tagName === 'BODY' || event.target.tagName === 'HTML')
      return;

    var target = event.target;

    var xpath = Xpath.getElementXPath(target);

    $.ajax({
      type: "POST",
      url: "/rest?text=" + xpath //,
    });

    console.log(xpath);

  });
};

function unregisterClickListener() {
  $(document).off("click");
}

function disableLinks() {
  $('a').click(function(event) {
    event.preventDefault();
  });
}

function enableLinks() {
  $('a').unbind('click');
}

function startSelecting() {
  registerMouseMove();
  registerClickListener();
  disableLinks();
}

function stopSelecting() {
  unregisterClickListener();
  unregisterMouseMove();
  enableLinks();
}

<!-- only for demonstration, delete! for use in programm call startSelecting by a Javascript call from the UI -->
window.onload = function(event) {
  startSelecting();
};
#selector-top,
#selector-bottom {
  background: blue;
  height: 3px;
  position: fixed;
  transition: all 300ms ease;
}
#selector-left,
#selector-right {
  background: blue;
  width: 3px;
  position: fixed;
  transition: all 300ms ease;
}
<div id="selector">
  <div id="selector-top"></div>
  <div id="selector-left"></div>
  <div id="selector-right"></div>
  <div id="selector-bottom"></div>
</div>

<html>

<head>
  <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js " /></script>
  <script type="text/javascript" src="link/to/xpath.js"></script>
</head>

<body>
  <span><b>Test</b></span>
  <p>trallalalala</p>
</body>

</html>

2. 使用 Vaadins Javascript 调用(参见 here)和一些 Javascript 在 iframe 中调用定义的 Javascripts ] 路径魔法: Page.getCurrent().getJavaScript().execute("window.frames[1].frameElement.contentWindow.startSelecting();");

3. 使用 Firebugs xpath.js 脚本在单击项目时获取 XPath(注意 license):

var xpath = Xpath.getElementXPath(event.target);

4. 使用 ajax rest 调用 post 数据到您的 Vaadin 应用程序:

$.ajax({
   type: "POST",
   url: "/rest?text="+xpath
});

5. 创建一个 rest 接口,即使用 Vaadin Broadcaster 将 xpath 值广播到 UI。有关如何使用 Broadcaster 和 Push for VaadinUI 的详细信息,请参阅 Eric G。 post

@RequestMapping("/rest")
public String sayHello(@RequestParam(value = "text", required = true) String text) {
    Broadcaster.broadcast(text);
}

6. 最后:VaadinUI 接收广播并打印 xpath,例如到 TextField 并进一步处理它

唯一的缺点是,它只能用于单用户应用程序,因为我无法区分同一 UI 的不同实例,即一个休息调用将开始向 UI 的所有实例广播,并将相同的数据传输给它们。

希望这对未来的访客有所帮助。 :)