聚合物 - 获得位于阴影dom中的div位置

时间:2014-09-05 11:00:32

标签: javascript polymer shadow-dom

我目前正在使用Polymer构建自定义元素。现在我想得到一个位于我的自定义元素中的div来执行某个函数onclick,在该函数中我需要获得它相对于视口的位置。

通常我会使用

var offsets = element.getBoundingClientRect();

现在在自定义元素中 - 假设我所说的div具有ID innerCard所以它将是

this.$.innerCard.onclick = function(){
alert("Test 1");
var offsets = this.$.innerCard.shadowRoot.getBoundingClientRect();
alert("Test 2");
....
} 

第一个警报正确触发,但第二个警报没有触发。 Javascript控制台给我一个类型错误:

Uncaught TypeError: Cannot read property 'innerCard' of undefined tile-story.html:37$.innerCard.onclick tile-story.html:37

有谁知道我怎么能访问div的位置,否则我在这里做错了什么?

3 个答案:

答案 0 :(得分:2)

未定义的错误是因为在onclick处理程序中,this与外部this不同,因此如果要使用this.$,则应首先绑定上下文:

 Polymer('tile-story', {
        ready: function() {
            this.$.innerCard.onclick = function() {
                var offsets = this.$.innerCard.getBoundingClientRect(); //ClientRect {height: 18, width: 1350, left: 8, bottom: 44, right: 1358…}
            }.bind(this);
        }
    });

答案 1 :(得分:1)

您可以使用Polymer的声明性事件绑定来让您的生活更轻松。 E.g:

<polymer-element name="x-foo">
  <template>
    <p on-tap="{{measureMe}}">Some Content</p>
  </template>
  <script>
    Polymer({
      measureMe: function(e) {
        var rect = e.currentTarget.getBoundingClientRect();
        alert(JSON.stringify(rect));
      }
    });
  </script>
</polymer-element>

这样,代码和视图对彼此的了解就越少,这将使您的项目更易于维护。 this周围没有问题,也无需查询特定节点。

如果您愿意,可以使用on-click代替on-taptap手势事件由Polymer生成,适用于触摸事件或鼠标事件。

http://jsbin.com/puqas/2/edit

答案 2 :(得分:0)

要获取有关组件的信息,您可以在组件本身上提供公共方法。根据您的用例,这将返回组件内div的clientRect:

<x-card></x-card>

<polymer-element name="x-card">
    <template>
        <div id="innerCard" class="card">Content_here</div>
    </template>
    <script>
        Polymer('x-card', {
            getBoundingClientRect: function () {
                return this.$.innerCard.getBoundingClientRect();
            }
        });
    </script>
</polymer-element>

<script>
    window.addEventListener('polymer-ready', function() {
        var card = document.querySelector('x-card');
        var rect = card.getBoundingClientRect();
        console.log(rect); // {height: 18, width: 336, left: 8, bottom: 26, right: 344…} 
    });
</script>

Working example here