【问题标题】:Add or Append HTML inside of a Polymer Element's template from Javascript从 Javascript 在 Polymer Element 的模板中添加或附加 HTML
【发布时间】:2014-04-08 19:53:20
【问题描述】:

为了让轮播功能在 Polymer 元素中工作,我以编程方式在元素脚本中创建 Slick 轮播所需的标记。假设在这段代码 sn-p 中 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>");
});

上面的“append*”方法都不起作用,生成的 DOM 不包含 div#carousel 元素。将 HTML 添加到 Polymer 元素的模板的正确方法是什么?

Here is a previous SO question 我问这解释了为什么我必须尝试这种从 javascript 将标记注入元素的方法。它与标记中挥之不去的模板标签有关 > 在 UPDATE 2 下查看完整的故障。

【问题讨论】:

    标签: polymer


    【解决方案1】:

    没有理由编写代码 :) 最好的方法是使用 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 被填充时,模板引擎会自动为您标记标记。

    【讨论】:

      【解决方案2】:

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

      生成的标记中的模板标签会干扰 Slick 的工作能力,因为它需要在 div#carousel 下方有一系列干净的 div,它可以在其中操作以变成幻灯片。 @ebdel:如果你能解释一下 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 元素上创建轮播,然后使用 slick API 函数 slickAdd() 添加每个在 this.videos 内滑动到模板。

      【讨论】:

        【解决方案3】:

        我没有适当的时间阅读其他答案,但总而言之,我会告诉你:第一件事是:jquery 不喜欢 polyfill,所以为了让它到达 shadow 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 解决方案会起作用(他真是太棒了)但是,我不确定您的图书馆是否愿意使用它。

        我正在编写一个选择器组件,但我不确定它是否可以工作,如果可以,我会提出某种拉取请求。

        【讨论】:

          【解决方案4】:

          我有一个非常相似的用例。我所做的是为幻灯片创建一个模板,为滑块创建一个模板,然后在我的基本页面中初始化 slick。在 Slider 模板的构造函数中,我使用 factoryImpl 函数将各个幻灯片添加到

          幻灯片模板

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-04-04
            • 1970-01-01
            • 1970-01-01
            • 2017-11-06
            • 2020-06-14
            • 1970-01-01
            • 2013-10-29
            • 2018-02-02
            相关资源
            最近更新 更多