【问题标题】:Import var and resize windows导入 var 并调整窗口大小
【发布时间】:2021-05-13 04:11:30
【问题描述】:

我在导入变量时遇到了一些问题。 尽管有不同的事件,var 永远不会更新...

这是实用程序文件:

function sizes() {
    let contentWidth = [...document.body.children].reduce(
        (a, el) => Math.max(a, el.getBoundingClientRect().right), 0)
        - document.body.getBoundingClientRect().x;

    window.addEventListener('resize', sizes)

    return {
        windowWidth:  document.documentElement.clientWidth,
        windowHeight: document.documentElement.clientHeight,
        pageWidth:    Math.min(document.body.scrollWidth, contentWidth),
        pageHeight:   document.body.scrollHeight,
        screenWidth:  window.screen.width,
        screenHeight: window.screen.height,
        pageX:        document.body.getBoundingClientRect().x,
        pageY:        document.body.getBoundingClientRect().y,
        screenX:     -window.screenX,
        screenY:     -window.screenY - (window.outerHeight-window.innerHeight),
    }
}

export default sizes();

在这里,我导入我的 var

import size from "../../utilities/size";

window.addEventListener('resize', () => {
    console.log(size.windowWidth);
})

【问题讨论】:

  • 你不会在导出之前调用这个吗? window.addEventListener('resize', sizes)。为什么要在侦听器中添加侦听器?另外,utilities/size 在哪里?我只看到utilities/sizes

标签: javascript resize dom-events


【解决方案1】:

当您调用export default sizes(); 时,您实际上是在评估size 函数。您的实用程序文件实际上与此相同:

const size = {
        windowWidth:  document.documentElement.clientWidth,
        windowHeight: document.documentElement.clientHeight,
        pageWidth:    Math.min(document.body.scrollWidth, contentWidth),
        pageHeight:   document.body.scrollHeight,
        screenWidth:  window.screen.width,
        screenHeight: window.screen.height,
        pageX:        document.body.getBoundingClientRect().x,
        pageY:        document.body.getBoundingClientRect().y,
        screenX:     -window.screenX,
        screenY:     -window.screenY - (window.outerHeight-window.innerHeight),
    }
export default size;

现在,如果您希望该代码具有反应性,并在每次调用它们时计算变量,您可以使用一个简单的 Accessor Get Method (MDN),它会在您每次访问这些属性时为您评估这些变量:

const size = {
  get windowWidth() {
    return document.documentElement.clientWidth
  },
  get windowHeight() {
    return document.documentElement.clientHeight
  },
  get pageWidth() {
     let contentWidth = [...document.body.children].reduce(
        (a, el) => Math.max(a, el.getBoundingClientRect().right), 0)
        - document.body.getBoundingClientRect().x;
    return Math.min(document.body.scrollWidth, contentWidth)
  },
  get pageHeight() {
    return document.body.scrollHeight
  },
  get screenWidth() {
    return window.screen.width
  },
  get screenHeight() {
    return window.screen.height
  },
  get pageX() {
    return document.body.getBoundingClientRect().x
  },
  get pageY() {
    return document.body.getBoundingClientRect().y
  },
  get screenX() {
    return -window.screenX
  },
  get screenY() {
    return -window.screenY - (window.outerHeight - window.innerHeight)
  },
}
export default size;

通过这样做,您无需在 utils 文件中绑定任何事件处理程序,只需将它们插入您需要的位置即可。

现在您的用户文件将是:

import size from "../../utilities/size";

window.addEventListener('resize', () => {
    console.log(size.windowWidth);
})

每次调整窗口大小时,它都会记录一个更改的值!

进一步分析你的代码:

export default sizes();

// is actually the same as
const $tmp = sizes();
export default $tmp;

// Now take a look at what sizes does:
function sizes() {
    ...    
    
    // this evaluates instantly your object
    return { windowWidth, ... }
    
    // is the same as
    const result = { windowWidth, ... }
    return result
    // if you now console.log one of those properties, they are fixed numbers
    // and they will not be changed inside this function
    
}


// But, why the object is not changing when the window resizes?
// Every time you call the function, it returns a new instance of the object
function example() { return { } }
let A = size();
let B = size();
console.log(A == B) // false

// Now when you export the constant sizes() you actually
// referring (for example) to the object A
// When you bind the resize event to sizes, it will create another object B
// and change it:
window.addEventListener('resize', example);
// is the same as
window.addEventListener('resize', () => { return {} });

这个 sn-p 试图解释幕后发生的事情:

const btn = document.getElementById('resize');

let OBJECT_ID = 0;
let exportedObject = null;

// emulates sizes()
function makeMyObject() {
  OBJECT_ID += 1;
  const result = { id: OBJECT_ID };
  
  // first time just print the export value
  if (!exportedObject) {
    console.log('exported ID:', result.id);
  }
  // the other times print exported value and current returned value
  else {
    console.log('exported ID:', exportedObject.id, 'returned ID:', result.id)
  }
  
  return result;
}

// emulates window.addEventListener('resize', sizes);
btn.addEventListener('click', makeMyObject);

// emulates export default sizes()
exportedObject = makeMyObject();
<p>Click the button to emulate the <code>winow.resize Event</code></p>
<button id="resize">Emulate</button>

【讨论】:

    【解决方案2】:

    您不应在导出中调用该函数。将其留给导入函数的任何内容。

    另外,不要在函数内部声明 resize 事件监听器。

    此外,变量/函数“维度”比“大小/大小”稍微不那么神秘。

    定义

    /app/utilities/dimensions.js

    const dimensions = () => {
      let contentWidth = [...document.body.children].reduce(
          (a, el) => Math.max(a, el.getBoundingClientRect().right), 0) -
        document.body.getBoundingClientRect().x;
    
      return {
        windowWidth  : document.documentElement.clientWidth,
        windowHeight : document.documentElement.clientHeight,
        pageWidth    : Math.min(document.body.scrollWidth, contentWidth),
        pageHeight   : document.body.scrollHeight,
        screenWidth  : window.screen.width,
        screenHeight : window.screen.height,
        pageX        : document.body.getBoundingClientRect().x,
        pageY        : document.body.getBoundingClientRect().y,
        screenX      : -window.screenX,
        screenY      : -window.screenY - (window.outerHeight - window.innerHeight),
      }
    };
    
    export default dimensions; // Do not call as a function...
    

    用法

    /app/view/components/main.js

    import dimensions from '../../utilities/dimensions';
    
    window.addEventListener('resize', () => {
      const { windowWidth } = dimensions(); // Call as a function...
      console.log(windowWidth);
    })
    

    【讨论】:

      【解决方案3】:

      我认为你想要做的是

      function sizes() {
      let contentWidth = [...document.body.children].reduce(
          (a, el) => Math.max(a, el.getBoundingClientRect().right), 0)
          - document.body.getBoundingClientRect().x;
      
      return {
          windowWidth:  document.documentElement.clientWidth,
          windowHeight: document.documentElement.clientHeight,
          pageWidth:    Math.min(document.body.scrollWidth, contentWidth),
          pageHeight:   document.body.scrollHeight,
          screenWidth:  window.screen.width,
          screenHeight: window.screen.height,
          pageX:        document.body.getBoundingClientRect().x,
          pageY:        document.body.getBoundingClientRect().y,
          screenX:     -window.screenX,
          screenY:     -window.screenY - (window.outerHeight-window.innerHeight),
      }}
      
      window.addEventListener('resize', () => {
          console.log(sizes());
      });
      

      【讨论】:

        猜你喜欢
        • 2012-04-11
        • 1970-01-01
        • 2019-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多