2017-06-22 41 views
3

环境:
只有JavaScript(jQuery的无:()
按钮单击事件处理程序不适用于改变有没有听文本框的方式,当其值编程方式更改

是有办法如果它的值是编程方式更改听文本框?

<input type="button" id="button1" value="button" /> 
<input type="text" id="text1" /> 


var btn1 = document.getElementById('button1'); 
var txt1 = document.getElementById('text1'); 
btn1.onclick=function(){ txt1.value = 'hello world'} 

https://jsfiddle.net/yrt7e57w/

+0

txt.onchange =函数(){} ... –

+1

我想我试过了,它不适合我 - https://jsfiddle.net/yrt7e57w/1/ – Rod

+0

你试过使用add事件函数并给它“change”事件类型? – Carcigenicate

回答

2

你可以依靠编程器改变元素来知道触发onChange,但这是一个不确定的命题。通过其他帖子看,这看起来非常有前途:对于你的文本元素,重写setter和getters,以便它们自动触发键控更改或程序设计。

var btn1 = document.getElementById('button1'); 
 
var txt1 = document.getElementById('text1'); 
 

 

 
btn1.onclick = function() { 
 
    txt1.value = 'hello world' 
 
    } 
 
    
 
txt1.addEventListener("change", function(e){ 
 
    console.log(txt1.value); 
 
}) 
 
    
 
    //property mutation for hidden input 
 
Object.defineProperty(txt1, "value", { 
 
    // Don't override the getter, but stub it in. 
 
    get: function() { 
 
    return this.getAttribute("value"); 
 
    }, 
 
    // In the setter, we want to set the value 
 
    // and also fire off the change event. 
 
    // By doing this, the coder changing the 
 
    // value never needs worry about it. 
 
    set: function(val) { 
 
    console.log("set"); 
 

 
    // handle value change here 
 
    this.setAttribute("value", val); 
 

 
    //fire the event 
 
    if ("createEvent" in document) { //NON IE browsers 
 
     var evt = document.createEvent("HTMLEvents"); 
 
     evt.initEvent("change", false, true); 
 
     txt1.dispatchEvent(evt); 
 
    } else { //IE 
 
     var evt = document.createEventObject(); 
 
     txt1.fireEvent("onchange", evt); 
 
    } 
 
    } 
 
});
<input type="button" id="button1" value="button" /> 
 
<input type="text" id="text1" />

还是把它看成是小提琴Here

因此,要回答你关于为什么点击处理程序是显示为具有空值的输入问题,这是因为,吸气/ setter正在重写默认值行为。解决最简单的方法是创建一个自定义的getter/setter充当接口值属性:

var btn1 = document.getElementById('button1'); 
 
var txt1 = document.getElementById('text1'); 
 

 
btn1.onclick = function() { 
 
    console.log("in the button's click handler, "); 
 
    console.log("Value is: " + txt1.val); 
 
    console.log("--------------------------------") 
 
    txt1.val = 'hello world' 
 
} 
 

 
txt1.addEventListener("change", function(e) { 
 
    console.log("in txt1.onChange function...") 
 
    console.log(this.val); 
 
    console.log("--------------------------------") 
 
}) 
 

 

 
//property mutation for hidden input 
 
Object.defineProperty(txt1, "val", { 
 
    get: function() { 
 
    return this.value; 
 
    }, 
 
    set: function(val) { 
 
    // handle value change here 
 
    this.value = val; 
 

 
    //fire the event 
 
    if ("createEvent" in document) { //NON IE browsers 
 
     var evt = document.createEvent("HTMLEvents"); 
 
     evt.initEvent("change", false, true); 
 
     txt1.dispatchEvent(evt); 
 
    } else { //IE 
 
     var evt = document.createEventObject(); 
 
     txt1.fireEvent("onchange", evt); 
 
    } 
 
    } 
 
});
<input type="button" id="button1" value="button" /> 
 
<input type="text" id="text1" />

什么发生在这里,当点击该按钮时,我获取输入的val属性(它获得幕后的值),然后以编程方式设置相同输入的val属性(这又是设置value属性)。出于某种原因,您不能在输入的value属性中使用get/set在object.defineProperty中,而不能完全打破它。因此,在控制台中,您将看到三个函数调用:当您单击该按钮时,输入失去焦点,触发其更改方法,但该按钮本身会触发其单击处理程序,然后更改输入的值并触发改变处理程序一次。

希望这会有所帮助!

再次,将此视为fiddle ...

+0

奖励:如果我在文本中键入内容并尝试第一次提醒它显示为空,那么您是否可以对原因做一些了解? https://jsfiddle.net/dyLb6543/1/ – Rod

+0

与https://jsfiddle.net/dyLb6543/2/ – Rod

+1

@Rod,看看我的帖子的变化。这是一个小问题,因为它创建了一个自定义val属性作为value属性的接口,但它工作得非常好。 – Snowmonkey

3

则您可以在使用element.dispatchEvent(event)以编程方式更改文本。在您的例子看起来会像:

var btn1 = document.getElementById('button1'); 
var txt1 = document.getElementById('text1'); 

btn1.addEventListener("click", function() { // Add to OnClick of button. 
    txt1.dispatchEvent(new Event('change')); // force change event to run on textbox. 
}); 

txt1.addEventListener("change", function(e){ // EventListener for OnChange of the element. 
    alert("changed"); 
}); 

刚上了自己的addEventListener不会,因为它是不完全作为一个在DOM改变工作。

上面是一个简单的解决方案,需要几个按键,但对于更易维护和可重复使用的解决方案,请查看Snowmonkey的答案(也可能是大多数其他问题的答案),https://stackoverflow.com/a/44708746/640263

+0

任何方式在按钮点击处理程序之外工作(该部分是密封的)。我很抱歉没有提到这一点。 – Rod

+0

我已经更新了我的答案,您应该仍然可以通过addEventListener将'click'事件添加到元素。 –

+0

在我看来,文本元素本身应该负责触发onchange - 连接按钮和文本框之间的连接会增加一个可能不够灵活的硬依赖项。 – Snowmonkey

0

也许这就是矫枉过正,
但你可以使用mutationObserver apilisten to an attribute change
你将不得不通过setAttribute方法来改变值:

var btn1 = document.getElementById('button1'); 
 
var txt1 = document.getElementById('text1'); 
 

 
btn1.onclick=function(){ txt1.setAttribute('value', 'hello world') } 
 

 
// create an observer instance 
 
var observer = new MutationObserver(function(mutations) { 
 
    mutations.forEach(function(mutation) { 
 
    console.log(mutation); 
 
    });  
 
}); 
 
    
 
// configuration of the observer: 
 
var config = { attributes:true }; 
 
    
 
// pass in the target node, as well as the observer options 
 
observer.observe(txt1, config);
<input type="button" id="button1" value="button" /> 
 
<input type="text" id="text1" />

相关问题