在Mithril中获取HTML标签的结节性

发布于 2025-01-28 20:17:37 字数 374 浏览 3 评论 0 原文

有没有一种方法可以在Mithril中拥有HTML标签的结节性?我需要获得块的宽度。在香草JS上这样的东西:

const blocks = Array.from(document.querySelectorAll('.blocks'));

const styles = blocks
  .map((item) => item.getBoundingClientRect())
  .map((item) => item.width);

const widthOfTheBlocks = styles.reduce((acc, curr) => acc + curr, 0) + 'px';

Is there a way of having a NodeList of the HTML tags in Mithril? I need to get the width of the blocks. Something like that on vanilla js:

const blocks = Array.from(document.querySelectorAll('.blocks'));

const styles = blocks
  .map((item) => item.getBoundingClientRect())
  .map((item) => item.width);

const widthOfTheBlocks = styles.reduce((acc, curr) => acc + curr, 0) + 'px';

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄离 2025-02-04 20:17:37

对于典型的DOM脚本,DOM元素是预先存在的,您需要确保它们具有可识别的选择器(在这种情况下为 blocks 类),然后在其他地方使用该选择器获得Javascript用 document.queryselectorall 引用它们。

但是使用Mithril,您正在声明并引用同一位置的DOM元素,因此您不需要以下任何一种方法:而是附加

生命周期方法公开a vnode 实体:这包含一个 dom 属性,该属性暴露了渲染的dom元素。

在组件中保存参考的基本机制如下:

function MyComponent(){   // The component to contain the logic
  let dom                 // The variable to store our DOM reference

  return {
    view : () => 
      m('.MyElement', {   // The virtual DOM element
        oncreate(vnode){  // The `oncreate` lifecycle method to access the `vnode`
          dom = vnode.dom // Save the dom reference to our variable
        }
      })
  }
}

下面,我写了一个小的沙盒演示,该演示使用您的宽度计算脚本在稍微复杂的情况下:这里有一个可变数量的块,这些块已添加到和随着时间的流逝而删除;我们声明A 要存储它们,对于每个项目,我们将 ongreate 方法添加将其添加到集合中,然后将 onremove 添加到 >删除 it。我已经使用 dom 参考;后来,我们使用 array.from 提取 width

function Blocks(){
  const blocks = new Set

  return {
    view: ({attrs: {count}}) => [
      m('.container',
        Array.from({length: count}, (_, index) => 
          m('.block', {
            oncreate({dom}){
              blocks.add(dom)
            },

            onremove({dom}){
              blocks.delete(dom)
            },
          }, index + 1)
        ),
      ),

      m('button', {
        onclick(){
          const styles = Array.from(
            blocks,
            (item) => item.getBoundingClientRect().width
          )

          const widthOfTheBlocks = styles.reduce((acc, curr) => acc + curr, 0) + 'px';

          alert(widthOfTheBlocks)
        }
      }, 'Alert width'),
    ]
  }
}

m.mount(document.body, function App(){
  let count = 1

  return {
    view: () => [
      m('h1', 'Width reader'),

      m('label', 
        'Number of blocks: ',

        m('input[type=number][min=0][max=9][size=4]', {
          value: count,
          oninput(e){
            count = e.target.value
          },
        }),
      ),

      m(Blocks, {count}),
    ]
  }
})
.container {
  display: flex;
  margin: 1em 0;
}

.block {
  flex: 0 0 25%;
  padding: 1em;
  border: 1px solid;
}
<script src="https://unpkg.com/mithril/mithril.js"></script>

With typical DOM scripting, the DOM elements are pre-existing, and you would need to make sure they had identifiable selector (in this case the blocks class), and then elsewhere use that selector to get a Javascript reference to them, with document.querySelectorAll.

But with Mithril, you're declaring and referencing the DOM elements in the same place, so you don't need either of these methods: instead you attach a lifecycle method on the appropriate node and save the reference to a local variable.

The lifecycle methods expose a vnode argument representing the virtual DOM entity: this contains a dom property which exposes the rendered DOM element.

The essential mechanism to save a reference inside a component is as follows:

function MyComponent(){   // The component to contain the logic
  let dom                 // The variable to store our DOM reference

  return {
    view : () => 
      m('.MyElement', {   // The virtual DOM element
        oncreate(vnode){  // The `oncreate` lifecycle method to access the `vnode`
          dom = vnode.dom // Save the dom reference to our variable
        }
      })
  }
}

Below, I've written a little sandbox demo that uses your width calculation script in a slightly more complex scenario: Here there's a variable number of blocks, which are added to and removed over time; we declare a Set to store them, and for each item we declare an oncreate method to add it to the set, and an onremove to delete it. I've used destructuring to extract the dom reference straight from the methods; later, we use a slightly tweaked version of your width accumulation code, using the 2nd argument of Array.from to extract the width.

function Blocks(){
  const blocks = new Set

  return {
    view: ({attrs: {count}}) => [
      m('.container',
        Array.from({length: count}, (_, index) => 
          m('.block', {
            oncreate({dom}){
              blocks.add(dom)
            },

            onremove({dom}){
              blocks.delete(dom)
            },
          }, index + 1)
        ),
      ),

      m('button', {
        onclick(){
          const styles = Array.from(
            blocks,
            (item) => item.getBoundingClientRect().width
          )

          const widthOfTheBlocks = styles.reduce((acc, curr) => acc + curr, 0) + 'px';

          alert(widthOfTheBlocks)
        }
      }, 'Alert width'),
    ]
  }
}

m.mount(document.body, function App(){
  let count = 1

  return {
    view: () => [
      m('h1', 'Width reader'),

      m('label', 
        'Number of blocks: ',

        m('input[type=number][min=0][max=9][size=4]', {
          value: count,
          oninput(e){
            count = e.target.value
          },
        }),
      ),

      m(Blocks, {count}),
    ]
  }
})
.container {
  display: flex;
  margin: 1em 0;
}

.block {
  flex: 0 0 25%;
  padding: 1em;
  border: 1px solid;
}
<script src="https://unpkg.com/mithril/mithril.js"></script>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文