Search code examples
javascriptcss-selectorspolymershadow-dominteract.js

Polymer draggable with interact.js / shadowDOM selector


I am attempting to use the interact.js library to create a draggable Polymer event. I know there exists a core-drag-drop element, I would like to use interact.js. I am attempting to get the first example working by passing in a class to the interact object.

interact('.draggable').draggable({....

This doesn't work in Polymer as it has to access the elements shadowDOM. I have tried the following selectors:

"custom-elem::shadow .draggable"
":host-context(.draggable)"
":host(.draggable)"
"custom-elem /deep/ .draggable"
"drop::shadow .draggable"
"custom-elem::shadow .draggable"

All return null.

I also attempted to assign and pass a reference to a single object which has the .draggable class:

var x = this.shadowRoot.querySelector(".draggable");
interact(x).draggable({....

This does not work as well. Any advice?

EDIT:

<polymer-element name="custom-elem">
<template>
<div class="draggable"></div>
</template>
</polymer-element>

Solution

  • Since version 1.2.3 of interact.js you should be able to interact with elements Shadow DOMs. The implementation may change and there are some issues to be aware of:

    1. Element.matches seems to always fail with deep/shadow-piercing selectors. For example, try running this on https://polymer-project.org:

      var selector = 'paper-button::shadow *'; document.querySelector(selector).matches(selector); // false

      So such selectors won't work with interact.js.

    2. :host, ::shadow, ::content selectors cause errors if used with the Shadow DOM polyfill

    In your case, since the element you want to target is in the ShadowDOM and deep selectors don't work, you should add a more specific class to the element. For example:

    <polymer-element name="custom-elem">
    <template>
    <div class="custom-elem-draggable"></div>
    </template>
    </polymer-element>
    
    interact('.custom-elem-draggable').draggable(/* ... */);
    

    That should work with both the native and polyfilled Shadow DOM.