【问题标题】:How to mutually link HTML element and its corresponding Javascript Class instance如何相互链接 HTML 元素及其对应的 Javascript 类实例
【发布时间】:2021-08-14 18:29:58
【问题描述】:

我想使用以下方法将 Javascript 类实例分配给 HTML 元素:https://stackoverflow.com/a/1402782/13107219

这允许我稍后使用以下方法访问类实例(这很好)

var class_instance = document.getElementById('my_element').my_class;

不过,我还希望能够从 Javascript 类实例中访问 HTML 元素

var class_instance=new MY_CLASS(); // class constructor creates corresponding HTML element and stores it in property 'html_element'

class_instance.html_element.innerHTML='I can access and update the HTML easily';

因此,理想情况下,我希望能够在类构造函数中包含以下两行:

this.html_element=this.create_html_element(); // create the html element for the box
this.html_element.my_obj=this; // reference this class instance with the HTML element

问题:
我提出的技术是否会造成循环引用、内存泄漏或导致问题?

是否有更好的技术(请不要使用 JQuery)来设置它,以便我可以: 1. 访问只有 HTML 元素 ID 的类实例和 2. 访问只有类实例可用的 HTML 元素?

完整示例

var BOX = class { //class to make a box
        
            constructor(my_prop, color) { // initialize the JS Object
                this.my_prop=my_prop; // define a property
                this.color=color;

                /* ******  My Question:  Are the following 2 lines OK to use? ****** */ 
                this.html_element=this.create_html_element(); // create the html element for the box
                this.html_element.my_obj=this;
  
            }

            create_html_element() { //generate the HTML for the box element and append it to the body
  
                var ele=document.createElement('DIV'); // create html element
                ele.style.border='1px solid #'+this.color; ele.className='box';// style the element border
                document.body.appendChild(ele); // put the element on the screen

                ele.onclick=this._onclick;  //make something happen when the box element is clicked

                return ele; // return the element so we can use 'this.html_element' to reference this element later
            }


            _onclick() { //Do this when the box is clicked
                /* 
                   Note: 'this' here refers to the event.target HTML element (not the JS object)
                   Could use bind to bind to the javascript object instead, but find it more intuitive to have the _onclick reference the html element that was clicked

                   Reference: https://stackoverflow.com/questions/41591250/html-element-attached-to-js-object
                */

                 console.log(this.my_obj.my_prop);
             }

         }


         function makeBoxes(){
             var box1=new BOX('Box 1','c00');
             var box2=new BOX('Box 2','0c0');
             var box3=new BOX('Box 3','00c');

             /* ****** I'd like to be able to use the lines below ****** */
             box1.html_element.innerHTML='Box 1';
             box1.my_prop="I've changed!";


             /* ******* Is it a problem that the following code can be used to access the same element?  Obviously, I wouldn't do the following line, but I didn't know if even being able to use it indicates a circular reference that might cause bloat, memory leaks, any other potential issues? ****** */
             var same_element = box1.html_element.my_obj.html_element.my_obj.html_element.my_obj.html_element;       

         }
.box{
width:15vw;
height:20vh;
margin:2vh;
display:inline-block;
vertical-align:middle;
}

.btn{
display:block;
}
<html>
  <body>
      <div class='btn' onclick='makeBoxes();'>Click to Make Boxes</div>
  </body>
</html>

【问题讨论】:

    标签: javascript


    【解决方案1】:

    循环引用本身并不坏。特别是,V8 的垃圾收集不使用引用计数(例如,CPython),所以如果您使用 V8 实现的 JavaScript,那么循环引用不会阻止垃圾收集。 There are some gotchas, though.

    但循环引用只是关于对象的可移除性。如果你要销毁一个元素,你可以删除所有的引用,这肯定会让它们安全地被垃圾回收。

    如果您想避免扩展属性,您可以使用 JavaScript Map 将 HTML 元素映射到类实例。例如:

    // Global context:
    const domToInstance = new Map();
    //...
    // In constructor:
      this.html_element=this.create_html_element(); // create the html element for the box
      domToInstance.set(this.html_element, this); // reference this class instance with the HTML element
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多