Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use external scripts inside a Polymer element

Tags:

polymer

What is the recommended way to "require" external javascript inside of a Polymer element? For instance, I'm building a video group component that I want to display inside of a Slick carousel.

For instance, my code might look like this for the custom element:

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/polymer-jsonp/polymer-jsonp.html">

<polymer-element name="polymer-video-group"  constructor="VideoGroupElement" attributes="">
  <template>
    <style>
      /* styles for the custom element itself - lowest specificity */
      :host {
          display: block;
          position: relative;
      }
      /* 
      style if an ancestor has the different class
      :host(.different) { } 
      */
    </style>

    <!-- Load Data with JSONP Endpoint (in this case Google Spreadsheets)
        Source: https://docs.google.com/spreadsheet/ccc?key=0AqZBbhllhMtHdFhFYnRlZk1zMzVZZU5WRnpLbzFYVFE&usp=sharing
        https://docs.google.com/spreadsheets/d/1CpXbJHeFrzPpg58lWAsT1N3-QExbX9T5OPVeMfyBqYs/pubhtml
    -->
    <polymer-jsonp id="jsonp" url="https://spreadsheets.google.com/feeds/list/1CpXbJHeFrzPpg58lWAsT1N3-QExbX9T5OPVeMfyBqYs/od6/public/values?alt=json-in-script&callback=" response="{{response}}"></polymer-jsonp>

    <template repeat="{{entry in response.feed.entry}}">
      <iframe width="420" height="315" src="//www.youtube.com/embed/{{entry.gsx$id.$t}}" frameborder="0" allowfullscreen></iframe>
    </template>

  </template>
  <script>
    Polymer('polymer-video-group', {

        // element is fully prepared
        ready: function(){
            this.$.jsonp.go();
        },

        // instance of the element is created
        created: function() {
          this.videos = [];
          this.response = {};
        },

        // instance was inserted into the document
        enteredView: function() { },

        // instance was removed from the document
        leftView: function() { },

        // attribute added, removed or updated
        attributeChanged: function(attrName, oldVal, newVal) { },

        // Response from JSONP Data Changed Event Handler
        responseChanged: function() {

            // Get the Entry Point for the JSON Feed
            var entries = this.response.feed.entry;

            // Create an empty variable to store the video group
            var videos = [];

            // Push entries from the JSON feed onto the videos array
            for (var i = 0, entry; entry = entries[i]; ++i) {
                videos.push({
                    name: entry.gsx$name.$t,
                    id: entry.gsx$id.$t
                });
            }

            // Set the video group object's array to this newly supplied video array
            this.videos = videos;
        }
    });
  </script>
</polymer-element>

But, rather than just displaying each video inside an iframe, I want those to appear in a carousel, powered by Slick, so I'm envisioning doing something vis-a-vis the following:

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/polymer-jsonp/polymer-jsonp.html">
<script src="../bower_components/slick-carousel/slick/slick.js"></script>

Do I have to create a custom element that wraps the functionality of slick or can I directly use the assets like the above example?

UPDATE: I created an "elements/slick-import.html" file that includes the 3 things Slick needs:

<link rel="stylesheet" href="../bower_components/slick-carousel/slick/slick.css"/>
<script src="../bower_components/jquery/dist/jquery.js"></script>
<script src="../bower_components/slick-carousel/slick/slick.js"></script>

In my elements/video-group.html element, I reference it as such: ... ...

I notice that the of the page contains the slick.css file, but the other 2 js files Slick requires are not being attached to the DOM when the page loads. Am I referencing the included scripts correctly in slick-import.html?

UPDATE 2: Here's my real issue: I have this repeating template that prints out the video list that I construct from my jsonp response:

<div id="carousel">
  <template repeat="{{video in videos}}">
    <div>
      <iframe width="420" height="315" src="//www.youtube.com/embed/{{video.id}}" frameborder="0" allowfullscreen></iframe>
    </div>
  </template>
</div>

But what is tripping up is that the resultant DOM in Chrome DevTools shows the markup as such:

<video-group>
  <div id="carousel" class="slick-initialized slick-slider">
    <template repeat="{{video in videos}}"></template>

    <div>
      <iframe width="420" height="315" src="//www.youtube.com/embed/Fp1wPwszF9M" frameborder="0" allowfullscreen=""></iframe>
    </div>

    <div>
      <iframe width="420" height="315" src="//www.youtube.com/embed/H-l2cq-MXUs" frameborder="0" allowfullscreen=""></iframe>
    </div>

    <div class="slick-list draggable" tabindex="0" style="padding: 0px 50px;">
      <div class="slick-track" style="width: 0px; -webkit-transform: translate3d(-832px, 0px, 0px); opacity: 1;"></div>
    </div>
  </div>

  <!-- Load Data with JSONP Endpoint (in this case Google Spreadsheets)
       Source: https://docs.google.com/spreadsheet/ccc?key=0AqZBbhllhMtHdFhFYnRlZk1zMzVZZU5WRnpLbzFYVFE&usp=sharing
       https://docs.google.com/spreadsheets/d/1CpXbJHeFrzPpg58lWAsT1N3-QExbX9T5OPVeMfyBqYs/pubhtml
  -->
  <polymer-jsonp id="jsonp" url="https://spreadsheets.google.com/feeds/list/1CpXbJHeFrzPpg58lWAsT1N3-QExbX9T5OPVeMfyBqYs/od6/public/values?alt=json-in-script&amp;callback=" response="{{response}}"></polymer-jsonp>
</video-group>

Notice how the div#carousel has a class of "slick-initialized" and "slick-slider". This means that my Slick Carousel is properly acting on my div#carousel DOM element, but because of the lingering template tag nested underneath, that is tripping up Slick from having some nice clean simple DIVs to act upon, like the example in the Slick docs demonstrates:

<div class="your-class">
  <div>your content</div>
  <div>your content</div>
  <div>your content</div>
</div>

Is there anyway I can workaround this, either through a Polymer-specific method or modify Slick somehow to target only child divs underneath div#carousel?

like image 783
eriklharper Avatar asked Apr 07 '14 22:04

eriklharper


People also ask

How to add external JavaScript inside an HTML page?

The HTML <script> tag is used for declaring a script within your HTML document. Through this, you can define client-side JavaScript. But, what if you want to add external JavaScript inside an HTML Page? Well, you can easily do that too using the src attribute of the <script> tag. The following are the attributes of the <script> tag −

How to use JavaScript from an external file source?

To use JavaScript from an external file source, you need to write all your JavaScript source code in a simple text file with the extension ".js" and then include that file as in the above structure i.e. <script src="myscript.js"></script> Keep the following content in myscript.js file − function sayHello () { alert ("Hello World") }

Do I need an external JavaScript library for the whole page?

Sometimes (and probably most often) you might want to have an external JavaScript library for the whole page. Yet the resource might not be used by the whole page (might be that only a specific function of the page uses it).

How do I inject a script into a component?

A quick way how you inject the script is to do this directly in a component by using mounted function. In case you are not familiar with mounted, the function executes the code before the page is loaded. So in our case, the script will be added before the page will be loaded.


1 Answers

I don't know the specifics of how slick works but if you want your element to ensure that a third party library gets loaded it's probably best to create an import for that script file. Similar question was asked over here.

like image 185
robdodson Avatar answered Nov 22 '22 04:11

robdodson