在Javascript中的Polymer Element模板中添加或附加HTML

时间:2014-04-08 19:53:21

标签: polymer

为了在聚合物元素内部使用轮播功能,我以编程方式在我的元素脚本中创建Slick轮播所需的标记。假设在此代码段中,this.videos已作为包含youtube视频信息的对象数组加载,特别是id和name属性:

// Create Carousel Container
var carousel = $('<div id="carousel"></div>');

// Add Slides
this.videos.forEach(function(element, index, array){

    // Create a template for each slide
    var slideTemplate = $('<div><iframe width="420" height="315" src="//www.youtube.com/embed/' + element.id + '" frameborder="0" allowfullscreen></iframe></div>');

    // Append Each Slide to the Carousel
    slideTemplate.appendTo(carousel);

    // jQuery Method
    $('#carousel').appendChild("<div></div>");
});

&#34;追加*&#34;上面的方法正在工作,结果DOM不包含div#carousel元素。将HTML添加到Polymer元素模板的正确方法是什么?

Here is a previous SO question我问这解释了为什么我必须尝试这种从javascript中在元素中注入标记的方法。它与标记中的延迟模板标签有关&gt;在UPDATE 2下查看完全失败。

4 个答案:

答案 0 :(得分:3)

没有理由编写代码:)最好的方法是使用Polymer的数据绑定功能,并提前设置DOM模板。一般来说,你永远不需要像这样触摸DOM。这是基本的想法:

<div id="carousel">
  <template repeat="{{v in videos}}">
    <div><iframe src="//www.youtube.com/embed/{{v.id}}"></iframe></div>
  </template>
</div>

填充this.videos时,模板引擎会自动为您标记标记。

答案 1 :(得分:0)

感谢Eric的回复。我的第一次尝试使用了使用模板重复功能的方法来填充this.videos数组中的标记。我用一些额外的上下文更新了原始问题,以帮助解释为什么我必须采用不同的方法来完成这项工作。

生成的标记中的模板标记会干扰Slick的工作能力,因为它需要在div#carousel下面有一系列干净的div,它可以在其中操作变成幻灯片。 @ebidel:如果你可以解释Polymer可以或将要解决这个挥之不去的模板问题的方法,那么这将有助于理解新的HTML5模板元素应该如何工作。

无论如何,我想出了如何使用我的编程方法来完成这项工作,我将在这里解释:

我剥离了创建div#carousel的jquery行,而是将其恢复到模板中:

<template>
    ...
    <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>

    <div id="carousel"><div>

</template>

接下来,以下是Polymer构造函数中的代码:

<script>
    Polymer('video-group', {

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

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

        ...

        // 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;

            // Create the Carousel
            this.slick();
        },

        // Run the Slick Carousel Command
        slick: function() {

          // Slick it up!
          $('#carousel').slick({
            arrows: true,
              centerPadding: '50',
              dots: true,
              infinite: 'true'
          });

          // Add Slides
          this.videos.forEach(function(element, index, array){              

              // Create a template for each slide
              var slideTemplate = $('<div><iframe width="420" height="315" src="//www.youtube.com/embed/' + array[index].id + '" frameborder="0" allowfullscreen></iframe></div>');

              // Append Each Slide to the Carousel
              $('#carousel').slickAdd(slideTemplate);

          });

        }
    });
  </script>

responseChanged使用jsonp响应中的视频填充this.videos数组,然后调用slick()函数,该函数首先在div#carousel元素上创建轮播,然后使用光滑的API函数slickAdd()添加每个在里面滑动。视频到模板。

答案 2 :(得分:0)

我没有适当的时间阅读其他答案,但总而言之,我会告诉你:首先是:jquery不喜欢polyfill,所以为了让它到达阴影dom你应该使用

var foo = document.querySelector('bodyOrhtmlOrWhatever /deep/ id-inside-the-shadow');

var foo = document.querySelector('moreSpecificSelectorinTheLightDOM ::shadow id-inside-this-shadow-dom');

或者我在聚合物元素或文档中找到的第三种方式(不记得,抱歉)

var foo = `document.querySelector('moreSpecificSelectorinTheLightDOM').shadowRoot
        .querySelector('first-id-or-tag-inside-this-specific-shadow-dom').shadowRoot
        .querySelector('tag-inside-the-shadow-dom'); (...)

然后用jquery消耗它(哪种方法更容易),如此

$(foo).each(function( index ) {
  console.log( 'do your magic here, "this" means the element being iterated' );
});

好吧,总结“为什么”:0.5.1上的Polyfill查找javascript vanilla选择器并相应地更改它们以使用非支持shadow-dom的浏览器。 真的希望它有所帮助。它确实帮助了我。任何进一步的问题都打动了我。

@ebidel解决方案将起作用(他真是太棒了)但是我不确定你的图书馆会不会喜欢它。

我正在编写一个选择器组件,但我不确定它是否能够正常工作,如果它确实会提出某种类型的拉取请求。

答案 3 :(得分:0)

我有一个非常相似的用例。我所做的是为幻灯片创建一个模板,滑块的模板,然后在我的基页中初始化光滑。在Slider模板的构造函数中,我使用<dom-module id="slide"> <template> <div> <!-- slide content goes here --> </div> </template> <script> Slide = Polymer({ is: 'slide', factoryImpl: function(slide) { //Assume slide is a JS object that I use to set any {{properties}} I'll need this.property = slide.analagousProperty; this.otherProperty = someFunction(slide.analagousProperty); }, properties: { //Properties defined here } }); </script> </dom-module> 函数添加单个幻灯片

幻灯片模板

<dom-module id="slider">
    <template>
        <div id="slider">
        </div>
        <div class="controlHolder">
        </div>
    </template>
    <script>
        Slider = Polymer({
            is: 'slider',
            factoryImpl: function(slides) {
                var destination = Polymer.dom(this.$.slider);
                for (i = 0; i < slides.length; i++) {
                    var slide = new Slide(slides[i]).querySelector('div');
                    destination.appendChild(slide);
                }
                Polymer.dom.flush();
            },
            ready: function() {
                $('#slider').on('afterChange', 
                    function(event, slick, currentSlide) {
                        $('.slick-center .play-button').click(function() {
                        });
                });
            }
        });
    </script>
</dom-module>

滑块模板

<head>
    <script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
    <script src="../bower_components/jquery/dist/jquery.min.js"></script>
    <script src="../bower_components/slick-carousel/slick/slick.min.js"></script>
    <link rel="import" href="../bower_components/polymer/polymer.html">
    <link rel="import" href="../base_slide.html">
    <link rel="import" href="../base_slider.html">
    <link rel="stylesheet" type="text/css" href="../bower_components/slick-carousel/slick/slick.css" />
    <link rel="stylesheet" type="text/css" href="../bower_components/slick-carousel/slick/slick-theme.css" />
    <link rel="stylesheet" type="text/css" href="../myCustomStyleSheet.css">
</head>
<body>
    <div class="mainContent"> 
        <h1>Some heading</h1>
    </div>
    <div id="slideContent">
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            var slides = [
                {
                    sourceImage: '1.jpg',
                    caption: 'A kindly person'
                },
                {
                    sourceImage: '2.jpg',
                    caption: 'A kindly person'
                },
                {
                    sourceImage: '3.jpg',
                    caption: 'A kindly person'
                },
                {
                    sourceImage: '4.jpg',
                    caption: 'A kindly person'
                },
                {
                    sourceImage: '5.jpg',
                    caption: 'A kindly person'
                },
                {
                    sourceImage: '6.jpg',
                    caption: 'A kindly person'
                },
                {
                    sourceImage: '7.jpg',
                    caption: 'A kindly person'
                }
            ];
            var slider = new Slider(slides);
            document.getElementById('slideContent').appendChild(slider);
            $('#slider').slick({
                arrows: true,
                initialSlide: 4,
                dots: true,
                infinite: true,
                cssEase: 'ease',
                accessibility: true,
                swipeToSlide: true,
                focusOnSelect: true,
                centerMode: true, //Requires odd number of slides to show
                slidesToShow: 5,
                centerPadding: '60px',
                adaptiveHeight: true
            });
        });
    </script>
</body>

实际页面

namespace MyProject
{
    public abstract class MyAbstractThing
    {
        protected const uint Percentage = 42;
    }

    public sealed class MyThing : MyAbstractThing
    {
        public new const uint Percentage = base.Percentage;
    }
}

这绝不是我的最终实现,但它显示了另一种完成工作的方法:使用querySelector()方法从自定义项中删除所需的div,然后在滑块中使用appendChild()&# 39; s构造函数可以放入你想要的东西。