javascript - 如何创建同一 JS 对象的多个实例来控制单独的 CSS 和 DOM 元素?

标签 javascript object

我正处于创建一个对象作为插件的早期阶段,该插件创建并控制一组 DIVINPUT 元素。目的是让多个实例执行相同的操作,但每个实例仅针对自己的 DIV 和 INPUT。

第一部分工作正常,如代码片段中的黄点所示。

现在,只有当我创建第二个实例时,第一个实例(红点)才会停止工作。第一个对象仍然存在,我可以寻址并设置其参数,只是它应该管理的动画已停止。因此,当存在两个对象时,新输入的事件监听器不起作用,或者我初始化对象的方式是错误的。我在这里需要帮助。

在继续使对象的解析器变得更加复杂之前,我会问这个问题,因为它应该在以后解析和绘制更复杂的多个输入。

如何正确分离两个 Controller 实例?

片段:

function randomButton(button_id){
	if(button_id=='demo_1'){
		while(MyObject_1.val()==MyObject_1.rand()){}	
	}
	if(button_id=='demo_2'){
		end = MyObject_2.rand();
		start = (end-MyObject_2.rand()).toFixed(2);
		if(start<0){start=0;}
		MyObject_2.val(end+" , "+start);
	}
}

function alertObjectInfo(object){
	text = "";
    if (null == object || "object" != typeof object) return object;
    for (var attr in object) {
        if (object.hasOwnProperty(attr)) text += (object[attr]+"\n");
    }	
	alert(text);
}

/* start of of the plug-in code */
var MyPlugin = ( function (element, id) {
	
	if(id===undefined){ // if no ID is provided genetate a hex string as ID
		id = ("OBJ-"+(new Date).getTime().toString(16)+"_"+(new Date).getMilliseconds().toString(16));
	}

	element.addEventListener('change', function () {
		/* this part of the code will only run if the element input value is changed */
		parser.input = this.value;
		parser.run();
		object.draw(parser.result);
	});
	
	defaults = [];
	defaults['size']	= 24;
	defaults['radius']	= 12;
	defaults['padding']	= 4;
	defaults['bgcolor']	= 'orange';
	defaults['color']	= 'yellow';
	defaults['transition']	= '1s';
		
	/* the part below is the parser engine that converts the input  */
	parser = {
	  input  : null,
	  result : null,
	  mode   : 'single', // default is single
	  run : ( function( value ) {
		  
		if(value){this.input = value;} // use value as new input if a value is provided
				
		if(this.mode==='single' || this.mode==false || this.mode===undefined){
			// parse as a single floating point value 
			this.mode = 'single'; // reset mode in case it was undefined
			this.result = parseFloat(this.input);
			if(this.result > 1){this.result = 1;}
			if(this.result < 0){this.result = 0;}
			return this.result;
		}
	
		if(this.mode==='double' || this.mode==2){
			// parse as two seperete floating point values 
			/* to be continued */
		}
	
	  })
	};

	/* the code below creates an object we can talk to and that will manage sprites  */
	var object = {
	  id		: id,			// optional identifier string useful for debugging
	  init  	: false,		// the switch to test if initialise is already done
	  element  	: element,		// the html element we take out input from 
	  sprites	: [],			// the array of sprite elements generated by this object 
	  parser 	: parser,		// the input parser engine
	  	  
	  /* the object's internal functions */
	  draw : function() { 
		/* the main to draw and move all sprites */
		if(this.init==false){alert('error: object is not properly initialised');return false;}
		
		this.sprites[1].style.width = (this.parser.result*100)+"%";
	  },
		
	  show : function() { 
	  	/* the show all sprites function */
		  element.parentNode.style.display = 'inline';
	  },
	  
	  hide : function() { 
	  	/* the hide all sprites function */
		  element.parentNode.style.display = 'none';
	  },
	  
	  val : function( value ) { 
	  /* the set or get value function */
	  	 if(value===undefined){
			 return element.value;
		 }else{
			element.value = value;
			element.dispatchEvent(new Event('change'));
		 }
	  },
	  
	  rand : function( maxVal, minVal, decVal ) { 
	  /* create and set a random value */
	  	 if(minVal===undefined){minVal = 0;} // default minimum value
	  	 if(maxVal===undefined){maxVal = 1;} // default maximum value
	  	 if(decVal===undefined){decVal = 2;} // default decimal precision
	  	 if(maxVal < minVal){ // invert minimum and maximum if incorrect
		 	offVal = maxVal;
			maxVal = minVal;
			minVal = offVal;
		 }
		 offVal = 1; // set or reset offVal
			for (i = 0; i < decVal; i++) { 
			  offVal = offVal/10;
			}
		 r = (Math.random())*((maxVal+offVal)-(minVal)) + minVal;
		 	if(r>maxVal){r=maxVal;}
		 p = Math.pow(10, decVal);
		 r = Math.floor(r*p) / p;
		 element.value = r;
		 element.dispatchEvent(new Event('change'));
		 return r;
	  },
	  
	  initialise : function() {

		if(this.init==false){
		 /* this part will initialise everything with default values once */			
			wrapper = element.parentNode;
			
			container = document.createElement("div");
			
			container.style.backgroundColor = defaults['bgcolor'];
			container.style.height = defaults['size']+'px';
			container.style.padding = defaults['padding']+'px';
			container.style.boxSizing = 'border-box';
			
			relativeRad = (defaults['size']/2)+'px';
			container.style.borderRadius = (relativeRad+' '+relativeRad+' '+relativeRad+' '+relativeRad);
			
			wrapper.appendChild(container);
			this.sprites.push(container);
			
			mover = document.createElement("div");
			
			mover.style.backgroundColor = 'inherit';
			mover.align = 'right'; // not yet controled by defaults
			mover.style.width = '0%'; // start at 0% always
			mover.style.minWidth = (defaults['size']-(defaults['padding']*2))+'px';
			mover.style.transition = defaults['transition'];
			
			container.appendChild(mover);
			this.sprites.push(mover);
			
			sprite = document.createElement("div");

			sprite.style.backgroundColor = defaults['color'];
			sprite.style.height = (defaults['size']-(defaults['padding']*2))+'px';
			sprite.style.width = (defaults['size']-(defaults['padding']*2))+'px';
			sprite.style.minWidth = (defaults['size']-(defaults['padding']*2))+'px';
			sprite.style.display = 'block';
			sprite.style.boxSizing = 'border-box';
			
			relativeRad = (defaults['size']/3)+'px';

			sprite.style.borderRadius = (relativeRad+' '+relativeRad+' '+relativeRad+' '+relativeRad);
			sprite.style.transition = defaults['transition'];
			sprite.innerHTML = '&nbsp;';
			
			mover.appendChild(sprite);
			this.sprites.push(sprite);
			
			this.init = true;
			return this.init;
		}
	  }
	  
	};

	object.initialise();
	return object;
	
});
/* end of of the plug-in code */


/* MyPlugin init */
var MyObject_1 = new MyPlugin(document.getElementById("demo_input_1"),'Object_1');
var MyObject_2 = new MyPlugin(document.getElementById("demo_input_2"),'Object_2');

// test if we can address sprites of the first object after creating a second object
MyObject_1.sprites[2].style.backgroundColor = 'red';
.item-wrap{
	background-color: #999;
	border:0;
	border-radius: 8px;
	padding: 16px;
	margin-bottom: 8px;
}
.demo_input{
	border:0;
	color:white;
	font-size:18px;
	padding:8px;
	background-color:transparent;
	width:100%; 
	box-sizing:border-box; 
	text-align:left
}
.item-text{
	border:0;
	color:white;
	font-size:18px;
	font-family:Avenir, Tahoma, sans-serif;
	padding-left:4px;
	padding-top:8px;
	width:100%; 
	box-sizing:border-box; 
	text-align:left
}
<div class="item-wrap">
	<div class="item-text">
	<strong>Progress animation based on double values (Beta)</strong><br>
    <small>The first value still sends the animation to a relative point between 0 and 1. 
	The second value streches the animated sprite to an offset starting point.</small><br>
    </div>
  <div id="demo_1_wrap" class="demo">
	  <input id="demo_input_2" class="demo_input" type="text" value="0 , 0">
    </div>
    <p>
      <input type="button" name="show" value="show object" onClick="MyObject_2.show()">
      <input type="button" name="hide" value="hide object" onClick="MyObject_2.hide()">
      <input style="float:right" type="button" name="alert" value="alert object" onClick="alertObjectInfo(MyObject_2)">
      <input type="button" name="rand" value="set random" id="demo_2" onClick="randomButton(this.id)">
    </p>
</div>
<div class="item-wrap">
	<div class="item-text">
	<strong>Progress animation based on a single value input</strong><br>
    <small>The input value sends the animation to a relative point between 0 and 1. 
	Empty or wrong input does nothing, where 1 or higher shows the animation at 100%</small><br>
    </div>
  <div id="demo_1_wrap" class="demo">
	  <input id="demo_input_1" class="demo_input" type="text" value="0">
    </div>
    <p>
      <input type="button" name="show" value="show object" onClick="MyObject_1.show()">
      <input type="button" name="hide" value="hide object" onClick="MyObject_1.hide()">
      <input type="button" name="demo_" value="set random" id="demo_1" onClick="randomButton(this.id)">
      <input style="float:right" type="button" name="alert" value="alert object" onClick="alertObjectInfo(MyObject_1)">
    </p>
</div>

预期结果是“MyObject_1”控制标记为 ID“demo_1_wrap”的 DIV 内的所有元素,第二个实例“MyObject_2”对标记为 ID“demo_2_wrap”的 DIV 执行相同操作。

最佳答案

IE 11 还显示了一堆语法问题 - 为什么不使用常见的 IIFE? (IIFEs on MDN)your error is just a listener parameter 。 我的修复至少是在其中打开脚本

Line# in the script / new content
138  this.draw = function (){
179  this.show = function (){
182  this.hide = function (){
185  this.val = function(value) {
194  this.rand = function(maxVal, minVal,decVal) {
would tell no support for default parameters - maybe check for undefined(?)
214  this.initialize = function (){
219      this.container.style.padding = "${this.defaults['padding']}px";
(wrong quotations here)

关于javascript - 如何创建同一 JS 对象的多个实例来控制单独的 CSS 和 DOM 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56176058/

相关文章:

javascript - 单选按钮 'onclick' 在 Chrome 和 Firefox 中有效,但在 IE 中无效

Java 对象和类初学者

Javascript, map 返回未定义

python - 如何将对象存储在动态生成的变量中?

c++ - 将自定义类对象作为值传递到 STL 映射中

php - 如何在 Codeigniter 中实例化同一对象的多个实例?

javascript - 使用 axios 将表单数据发布到 api javascript

javascript - req.body.data 在expressjs中未定义

javascript - 点击select2时自动出现水平滚动条

javascript - 未捕获的类型错误 : Cannot read property 'arc' of undefined