假设我有public final class MyRunnable {
private static final int READY_TO_START = 0;
private static final int ACTIVE = 1;
private static final int STOPPED = 2;
private final AtomicInteger status = new AtomicInteger(READY_TO_START);
public void start() {
if (!status.compareAndSet(READY_TO_START, ACTIVE)) {
throw new IllegalStateException("Already started");
}
// My one-time start code.
}
public void stop() {
if (!status.compareAndSet(ACTIVE, STOPPED)) {
throw new IllegalStateException("Can't stop, either not started or already stopped");
}
// My one-time stop code.
}
}
。
我有一个 <DataGrid x:Name="CellStyleGrid" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="309,50,0,0" IsReadOnly="False" IsEnabled="True" CanUserAddRows="True" Width="172" RenderTransformOrigin="0.501,0.477" SelectionUnit="Cell" Grid.ColumnSpan="2" AlternatingRowBackground="#C2C2C2" AlternationCount="2" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=col1}" ClipboardContentBinding="{x:Null}" Header="Col1" CanUserResize="True"/>
<DataGridTextColumn Binding="{Binding Path=col2}" ClipboardContentBinding="{x:Null}" Header="Col2" CanUserResize="True"/>
<DataGridTextColumn Binding="{Binding Path=col3}" ClipboardContentBinding="{x:Null}" Header="Col3" CanUserResize="True"/>
</DataGrid.Columns>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#3B3B3B"/>
<Setter Property="Foreground" Value="White"/>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
eventListener。
它会检测用户造成的所有更改:使用鼠标和键盘。但如果我会做这样的事情:
<select id='test'>
更改事件不会连线。
问题:
onchange
事件正在寻找什么,什么时候发生?(我是对的:当我更改JS值时,document.getElementByID('test').value = 'new value';
事件没有连线,因为没有创建change
对象吗?)
答案 0 :(得分:3)
change 事件(注意没有 ChangeEvent 接口)就像任何事件一样,不看任何东西。事件由各种算法fired直接作为这些算法的一部分。
对于具有“文本”类型的输入,触发更改事件的算法是 here。
当前读取
<块引用>对于没有定义输入激活行为的输入元素,但这些事件适用,并且用户界面涉及交互式操作和显式提交操作,那么当用户更改元素的值时,用户代理必须排队用户交互任务源上的元素任务给定 input 元素以在 input 元素触发名为 input 的事件,气泡和组合属性初始化为 true,并且任何时候用户提交更改,用户代理都必须将元素排队给定 input 元素的用户交互任务源上的 task 以在 input 元素触发名为 change 的事件,并且气泡属性初始化为 true。
一些其他类型的输入确实有不同的算法,由它们的 input activation behavior 定义。
当然,您的代码进行了这些更改,您当然可以在更改的地方挂钩回调。
现在,出于调试目的,您可以覆盖输入的 value
属性,以便它在设置值时调用您的回调:
{
const inp = document.querySelector("input");
const original_desc = Object.getOwnPropertyDescriptor( HTMLInputElement.prototype, "value");
const new_desc = Object.assign( {}, original_desc, {
set(val) {
console.log( "value just changed programmatically:", val );
return original_desc.set.call( this, val );
}
} );
Object.defineProperty( inp, "value", new_desc );
}
document.querySelector("button").onclick = () => {
document.querySelector("input").value = "foo";
};
<input>
<button>change value programmatically</button>
但实际上,您必须求助于这种黑客手段,这意味着您需要解决一个更大的设计问题。
因为 change 事件,就像 input 一样,“被触发以表明用户已经与控件交互。” source
作为网络作者,您可以控制在您的页面上运行的脚本,因此为您的脚本自行执行的操作触发事件是没有意义的,它应该能够触发此事件本身。