Gridstack在iframe内没有正确更新高度

时间:2016-02-26 11:51:14

标签: iframe knockout.js knockout-2.0 knockout-3.0 gridstack

这里我使用iframe显示一个页面页面,其中包含一个Gridstack基于网格的编辑器来重新定位其元素。内部页面应包含纯HTML和CSS。所有与gridstack相关的CSS和任何与ko相关的JS调用都应该从外部页面进行。我在一个页面上工作。

现在的问题是,只要我将 Gridstack 网格转换为 iframe 并将其绑定到viewmodel。它的大小不合适。小部件存在于HTML 中,但不可见(由于零高度

在这种情况下,执行Knockout绑定,但 CSS高度属性垂直Y位置无法动态计算。

注意:正确分配宽度水平X位置,因为它们是从静态CSS类加载的。

更新:可能需要修复此问题,需要覆盖Gridstack中的此功能。它在外部页面而不是内部动态创建CSS。这可能是问题的原因:

createStylesheet: function(id) {
            var style = document.createElement('style');
            style.setAttribute('type', 'text/css');
            style.setAttribute('data-gs-style-id', id);
            if (style.styleSheet) {
                style.styleSheet.cssText = '';
            } else {
                style.appendChild(document.createTextNode(''));
            }
            document.getElementsByTagName('head')[0].appendChild(style);//POSSIBLE CAUSE OF THE PROBLEM
            return style.sheet;
        },

The snippet bellow still won't execute, I recommend looking at my JSFiddle

//WORKAROUND TO SKIP THE SAME-ORIGIN POLICY
$('#editor-iframe').load(function() {
  $(function() {
    $('#editor-iframe').contents().find('html').html('<head><title></title><style type="text/css">.grid-stack { background: lightgoldenrodyellow; } .grid-stack-item-content { color: #2c3e50; text-align: center; background-color: #18bc9c; } </style><link rel="stylesheet" href="https://rawgit.com/troolee/gridstack.js/master/dist/gridstack.css" /></head><body><div class="grid-stack" data-bind="gridstack: widgets"><div class="grid-stack-item" data-bind="attr: {\'data-gs-x\': $data.x, \'data-gs-y\': $data.y, \'data-gs-width\': $data.width, \'data-gs-height\': $data.height, \'data-gs-auto-position\': $data.auto_position}"><div class="grid-stack-item-content"><button data-bind="click: $parent.deleteWidget">Delete me</button></div></div></div></body>');
    
    //THE ACTUAL CODE
    ko.bindingHandlers.gridstack = {
      init: function(element, valueAccessor, allBindingsAccessor, data, context) {
        ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, data, context);

        return {
          controlsDescendantBindings: true
        };
      },
      update: function(element, valueAccessor, allBindingsAccessor, data, context) {
        var widgets = valueAccessor(),
          grid = $(element).gridstack().data('gridstack'),
          afterAddWidget = function(items) {
            var item = _.find(items, function(i) {
              return i.nodeType === 1;
            });
            grid.addWidget(item);
            ko.utils.domNodeDisposal.addDisposeCallback(item, function() {
              grid.removeWidget(item);
            });

            //RESIZE IFRAME TO FIT NEW CONTENT
            var iframeWin = document.getElementById('editor-iframe').contentWindow;
            $('#editor-iframe')
              .height(Math
                .max(
                  iframeWin.document.body.scrollHeight, iframeWin.document.body.offsetHeight,
                  iframeWin.document.documentElement.clientHeight,
                  iframeWin.document.documentElement.scrollHeight,
                  iframeWin.document.documentElement.offsetHeight) + 'px');
          },
          newVA = function() {
            return {
              data: widgets,
              afterRender: afterAddWidget
            };
          };
        ko.bindingHandlers.foreach.update(element, newVA, allBindingsAccessor, data, context);
      }
    };

    var Controller = function(widgets) {
      var self = this;

      this.widgets = ko.observableArray(widgets);

      this.addNewWidget = function() {
        this.widgets.push({
          x: 0,
          y: 0,
          width: Math.floor(1 + 3 * Math.random()),
          height: Math.floor(1 + 3 * Math.random()),
          auto_position: true
        });
        return false;
      };

      this.deleteWidget = function(item) {
        self.widgets.remove(item);
        return false;
      };
    };

    var widgets = [{
      x: 0,
      y: 0,
      width: 2,
      height: 2
    }, {
      x: 2,
      y: 0,
      width: 4,
      height: 2
    }, {
      x: 6,
      y: 0,
      width: 2,
      height: 4
    }, {
      x: 1,
      y: 2,
      width: 4,
      height: 2
    }];

    var controller = new Controller(widgets);
    ko
      .applyBindings(
        controller,
        document
        .getElementById('editor-iframe').contentWindow.document.body);
  });
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js" type="text/javascript"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-debug.js" type="text/javascript"></script>
<script type="text/javascript" src="https://rawgit.com/troolee/gridstack.js/master/dist/gridstack.js"></script>

<iframe id="editor-iframe" src="http://stacksnippets.net" sandbox="allow-same-origin" style="width:100%"></iframe>

0 个答案:

没有答案