我怎样才能让一个元素失去它的盒子模型?

哈克

我正在使用VueJS并具有像这样动态创建的嵌套元素:

<container>
  <outerElement class="outer" v-for="obj in objects">
    <innerElement class="inner" v-for="element in obj"/>
  </outerElement>
</container>

现在,谈到CSS时,我遇到了一个小问题。由于innerElements旨在可移动,因此它们需要外部元素具有与容器相同的大小/位置。

CSS中是否有某种方法可以在保留在容器中的同时从“外部”类中删除框模型?

这是我要实现的目标的草图。 草图


编辑:

为了解决提到的XY问题,这是简化版本的模板,使用与我的应用程序相同的实现方法。

<template>
  <div class="home">
    <h1>This is the main Page.</h1>

    <h2>Testing area:</h2>
    <br />Simple Data Example:
    <br />
    <div class="container">
      <button @click="simpleXOR()">XOR</button>
      {{ data }}
      <vue-draggable-resizable
        class="simple"
        v-for="(bit,index) in simpleData"
        :key="index"
        :w="50"
        :h="50"
        :parent="true"
        :resizable="false"
      >
        {{`Bit-${index} => `}}
        <status-indicator :status="bit ? 'positive' : 'negative'" />
      </vue-draggable-resizable>
    </div>
    <br />Nested Data Example
    <div class="container">
      <div class="outer" v-for="obj in nestedObj.data" :key="obj.name">
        <div class="label">
          <button @click="nestedXOR(obj.name)">XOR -> {{ obj.name }}</button>
          {{ obj.states }}
        </div>
        <vue-draggable-resizable
          class="inner"
          v-for="(state, index) in obj.states"
          :key="index"
          :resizable="false"
          :w="100"
          :h="50"
          :parent="true"
        >
          <div v-if="obj.contentType === 'TypeA'">
            <b>{{ `Bit-${index} of ${obj.name}` }}</b>
            <br />
            <status-indicator :status="state ? 'positive' : 'negative'" />
          </div>
          <div v-else>
            <b>{{ `Bit-${index} of ${obj.name}` }}</b>
            <br />
            <status-indicator :status="state ? 'active' : 'intermediary'" />
          </div>
        </vue-draggable-resizable>
      </div>
    </div>
  </div>
</template>

<script>
// @ is an alias to /src

export default {
  name: "home",
  components: {},
  data() {
    return {
      simpleData: [0, 1, 0, 1],
      nestedObj: {
        data: [
          {
            states: [0, 1, 0, 1],
            name: "a",
            contentType: "TypeA"
          },
          {
            states: [0, 1, 0, 1],
            name: "b",
            contentType: "TypeB"
          }
        ]
      }
    };
  },
  computed: {
    data() {
      return this.simpleData;
    }
  },
  methods: {
    simpleXOR() {
      var x = [];
      for (var i = 0; i < this.simpleData.length; i++) {
        x.push(this.simpleData[i] ^ 1);
      }
      this.simpleData = x;
      console.debug(this.simpleData);
    },
    nestedXOR(name) {
      var index = this.nestedObj.data.findIndex(obj => {
        return obj.name === name;
      });
      var x = [];
      for (var i = 0; i < this.nestedObj.data[index].states.length; i++) {
        x.push(this.nestedObj.data[index].states[i] ^ 1);
      }
      this.nestedObj.data[index].states = x;
    }
  }
};
</script>

<style scoped>
.container {
  margin: auto;
  height: 200px;
  width: 1000px;
  border: 2px solid black;
  position: relative;
}
.simple {
  top: 0px;
  left: 0px;
}
.outer {
  display: contents; /* as suggested */
}
.inner {
  /* ??? */
}
.label {
  border: 1px dashed green;
  padding: 10px;
  height: 20%;
  width: 20%;
}
/* // This is the css for vue-draggable-resizable */
/* // DON'T EDIT unless customization is needed */
.vdr {
  touch-action: none;
  position: absolute;
  box-sizing: border-box;
  border: 1px dashed black;
}
.handle {
  box-sizing: border-box;
  position: absolute;
  width: 10px;
  height: 10px;
  background: #eee;
  border: 1px solid #333;
}
.handle-tl {
  top: -10px;
  left: -10px;
  cursor: nw-resize;
}
.handle-tm {
  top: -10px;
  left: 50%;
  margin-left: -5px;
  cursor: n-resize;
}
.handle-tr {
  top: -10px;
  right: -10px;
  cursor: ne-resize;
}
.handle-ml {
  top: 50%;
  margin-top: -5px;
  left: -10px;
  cursor: w-resize;
}
.handle-mr {
  top: 50%;
  margin-top: -5px;
  right: -10px;
  cursor: e-resize;
}
.handle-bl {
  bottom: -10px;
  left: -10px;
  cursor: sw-resize;
}
.handle-bm {
  bottom: -10px;
  left: 50%;
  margin-left: -5px;
  cursor: s-resize;
}
.handle-br {
  bottom: -10px;
  right: -10px;
  cursor: se-resize;
}
@media only screen and (max-width: 768px) {
  [class*="handle-"]:before {
    content: "";
    left: -10px;
    right: -10px;
    bottom: -10px;
    top: -10px;
    position: absolute;
  }
}
</style>

Currently the problem in this code is that the innerElements can't be moved inside the container, because the outerElement is their container.

Since I can't change the parent selector to use the container instead of the outerElement this is hard to change.

Thus I wanted to make the outerElements borders non-existant so that the innerElement uses the container as parent.

But I suppose my thought is a bit weird, considering that the vue-draggable-resizable component will use the outerElement as parent anyways.

Here's a screenshot of the problem: 屏幕截图

The moveable boxes can't be moved inside the container because the outerElement doesn't inherit the position and size of the container.

Ilmari Karonen

For your simple example, you could just flatten the nested array before iterating over it:

<container>
  <innerElement class="inner" v-for="element in objects.flat(1)" />
</container>

您发布的更复杂的示例有点棘手,因为内部循环也需要访问obj尽管如此,您仍然可以通过编写一个自定义方法来实现此目的,该方法将每个状态包装在一个包装器中,该包装器既包含状态又包含对其所属对象的引用,如下所示:

<div class="container">
  <div class="label" v-for="obj in nestedObj.data" :key="obj.name">
    <button @click="nestedXOR(obj.name)">XOR -> {{ obj.name }}</button>
    {{ obj.states }}
  </div>

  <vue-draggable-resizable
    class="inner"
    v-for="wrapper in flattenStates(nestedObj.data)"
    :key="wrapper.key"
    :resizable="false"
    :w="100"
    :h="50"
    :parent="true"
  >
    <div v-if="wrapper.obj.contentType === 'TypeA'">
      <b>{{ `Bit-${wrapper.index} of ${wrapper.obj.name}` }}</b>
      <br />
      <status-indicator :status="wrapper.state ? 'positive' : 'negative'" />
    </div>
    <div v-else>
      <b>{{ `Bit-${wrapper.index} of ${wrapper.obj.name}` }}</b>
      <br />
      <status-indicator :status="wrapper.state ? 'active' : 'intermediary'" />
    </div>
  </vue-draggable-resizable>
</div>

flattenStates方法看起来像这样:

flattenStates: function (objects) {
  return objects.flatMap( obj => {
    return obj.states.map( (state, index) => {
      return {
        obj: obj,
        state: state,
        index: index,
        key: obj.name + " state " + index
      };
    } );
  } );
}

兼容性说明:.flat()并且.flatMap()在IE或Edge的当前稳定版本上不可用。要使这些代码在那些浏览器上运行,您需要一个polyfill。但是,基于Chromium的基于Chromium的新版本在撰写本文时仍处于beta版,但两者都支持。

另外,您可以通过将一些逻辑移入flattenStates方法来简化模板

<div class="container">
  <!-- label divs omitted for brevity -->

  <vue-draggable-resizable
    class="inner"
    v-for="wrapper in flattenStates(nestedObj.data)"
    :key="wrapper.title"
    :resizable="false"
    :w="100"
    :h="50"
    :parent="true"
  >
    <div>
      <b>{{ wrapper.title }}</b>
      <br />
      <status-indicator :status="wrapper.status" />
    </div>
  </vue-draggable-resizable>
</div>
flattenStates: function (objects) {
  return objects.flatMap( obj => {
    return obj.states.map( (state, index) => {
      const wrapper = {
        title: `Bit-${index} of ${obj.name}`  // also used as :key
      };

      if (obj.contentType === 'TypeA') {
        wrapper.status = (state ? 'positive' : 'negative');
      } else {
        wrapper.status = (state ? 'active' : 'intermediary');
      }

      return wrapper;
    } );
  } );
}

...甚至:

<div class="container">
  <!-- label divs omitted for brevity -->

  <vue-draggable-resizable
    class="inner"
    v-for="(status, title) in flattenStates(nestedObj.data)"
    :key="title"
    :resizable="false"
    :w="100"
    :h="50"
    :parent="true"
  >
    <div>
      <b>{{ title }}</b>
      <br />
      <status-indicator :status="status" />
    </div>
  </vue-draggable-resizable>
</div>
flattenStates: function (objects) {
  const objStates = {};
  for (const obj of objects) {
    obj.states.forEach( (state, index) => {
      const title = `Bit-${index} of ${obj.name}`;

      if (obj.contentType === 'TypeA') {
        objStates[title] = (state ? 'positive' : 'negative');
      } else {
        objStates[title] = (state ? 'active' : 'intermediary');
      }
    } );
  }
  return objStates;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从数组中删除一个值。我怎样才能让它工作

我怎样才能让它移动到一个新目录?

我有一个有效的代码,但我怎样才能让它更优雅

如果处理错误,While 循环会跳过一个循环。我怎样才能让它运行剩余的周期?

Unity - 我怎样才能让一个函数在玩家点击它 3 次时触发?

脚本影响所有 div,我怎样才能让它只影响一个?

我怎样才能让一个 for 语句有一个 else

我怎样才能让一个类实现一个接口...(C ++)

我怎样才能让一个用户表单完成另一个?

我怎样才能让Selenium使用我的firefox(而不是创建一个新的)

我怎样才能让我的Ubuntu从给定的源中寻找一个库

我怎样才能让我的 CNN 输出一个特征向量

我怎样才能让一个函数等到代码前一行完成

我怎样才能让iAd飞来阻止白盒子?

我怎样才能让一个for循环,将显示在JavaFX 8周的TextField

我怎样才能让一个for循环与双打的阵列?

iText的7:我怎样才能让溢出一个div?

我怎样才能让jQuery用fadeToggle切换一个类?

我怎样才能让“图像”键成为第一个?

我怎样才能让 clojure 写一个对套接字的响应?

我怎样才能让你每次回答一个问题时不断重复?

我怎样才能让 Neovim 的“e”地图增加一个位置?

当我做一个二维数组随机图像时,有重复,我怎样才能让它独一无二?

我怎样才能让盒子的每一面都有不同的颜色?

我怎样才能让我的应用程序获得的WebView点击一个链接的URL,就可以进行操作,然后加载它?

我怎样才能让一个有界类型参数的方法排除一个子类?

我怎样才能让一个块跟随 pygame 中的另一个块

我怎样才能让模型从它停止的时代开始恢复训练?

我怎样才能通过地图迭代,并使用递归增加它的元素到一个ArrayList?