js动态改变input的值不触发input的change事件的解决办法

原创
2018/02/09 10:42
阅读数 3.1W

看了网上的资料也比较杂,自己也做一个整理共享一下解决方案

1.原生js的改变之后手动添加监听

<body>
    <input type="hidden" id="ttt" /><br/>
    <select id="eee" >
        <option>1</option>
        <option>2</option>
        <option>3</option>
    </select>
</body>
<script type="text/javascript">
        var ttt =  document.getElementById("ttt");
        var eee =  document.getElementById("eee");
        eee.onchange=function (){
            ttt.value=eee.value;
            ttt.addEventListener("input",changeValue(),false);
        }
        function changeValue(){
            alert(ttt.value);
        }
</script>

需要注意的是,ttt添加的监听的方法名一定要加(),就是在eee的change事件触发的是否给ttt赋值,并且手动触发ttt的change事件

2.添加自定义属性触发事件

<body>
    <input type="hidden" id="ttt" /><br/>
    <select id="eee" >
        <option>1</option>
        <option>2</option>
        <option>3</option>
    </select>
</body>
<script type="text/javascript">
        var ttt =  document.getElementById("ttt");
        var eee =  document.getElementById("eee");
        eee.onchange=function (){
            ttt._value=eee.value;
        }
        Object.defineProperty(ttt,"_value",{
        	configurable:true,
        	set:function(value){
        		this.value = value;
        		changeValue();
        	},
        	get:function(){
        	    return this.value;	
        	}
        });
        function changeValue(){
            alert(ttt.value);
        }
</script>

这种方式不需要添加监听,是通过添加自定义属性并且在自定义属性的set方法里触发input的值改变事件

3.jquery的手动触发input改变事件

	<body>
    <input type="text" id="two" /><br/>
    <select id="three" >
        <option>1</option>
        <option>2</option>
        <option>3</option>
    </select>
    <input type="hidden" id="one" />
    <input type="hidden" id="four" />
    <input type="text" id="five" />
	</body>
	<script type="text/javascript">
    	$("#two").on("change",function(){
    		~!($("#one").val())>-2 ? alert($("#one").val()) : ($("#one").on("change",function(){
    		alert($(this).val());
    	}));
    	});
    	$("#three").on("change",function(){
    		$("#two").val($(this).val());
    		$("#two").change();
    	});
    	
    	var index = 0;
    	setInterval(function(){
    		index ++;
    		$("#five").val(index);
    		if (index == 10) {
    			$("#one").val($("#three").val());
    			$("#one").change();
    		}
    	},1000);
    </script>

这种方式是在值改变的时候手动触发change事件,这里的代码是select框的值改变了,并且当#one这个input框有值了才触发,就是满足两个事件才执行

4.最终解决办法(推荐一篇文章

Object.defineProperty(document.getElementById("id"),"value",{
set:(v)=>{
document.getElementById("id").setAttribute("value",v);
/**
*触发chang事件的代码
*/
});

原来的那几种方法,局限性太多,通过重写原形属性的setter方法,实现动态change事件的触发,目前为止,我觉得最好的解决办法。

5.超级最终解决办法

我还是太年轻了,第四种方法有一个很大的弊端,就是手动更改input框数据的时候是不会触发setter方法的,只有js调用了赋值操作才会进,所以,又有了下一个方法

(function($) {
	const o = $.fn.val;
	$.fn.val = function() {
		const r = o.apply(this, arguments);
		if (this.is("#id") && arguments.length > 0) {
			this.trigger("change");
		}
		return r;
	}
})(jQuery);

这个方法,依赖于jQuery,并且js中动态赋值都只能用val,这个方法才生效。

主要的逻辑就是重写jquery的val方法,在方法体中触发input的change事件。

把这个方法拷贝到你的js的文件顶端就可以生效了

展开阅读全文
打赏
1
3 收藏
分享
加载中
更多评论
打赏
0 评论
3 收藏
1
分享
返回顶部
顶部