このようなことをすることは可能ですか
while (view.mouseover == true) {
preform action
}
マウスが特定のビューの上にある限り、アクションを繰り返したいです。
(laszlo-user メーリングリストで質問されました)
このようなことをすることは可能ですか
while (view.mouseover == true) {
preform action
}
マウスが特定のビューの上にある限り、アクションを繰り返したいです。
(laszlo-user メーリングリストで質問されました)
ActionScriptとJavaScriptはどちらもシングルスレッドであるため、各ループの反復の間に一時停止を伴うwhileループを作成することはできません。SWF10 / 11ランタイムでは、各メソッドまたは関数内のコードがアプリケーションの1フレーム内で実行できることを確認する必要があります(期間はSWFクリップのフレームレートによって異なります)。
回避策として、タイマーを使用できます。例を次に示します。
<canvas debug="true">
<class name="mouseoverview" extends="view"> <attribute name="timer" type="object" value="null" />
<!-- lz.Delegate instance used by the timer -->
<attribute name="timerdel" type="object" value="null" />
<attribute name="timeractive" type="boolean" value="false" />
<!-- milliseconds to pause before each call to doWhileMouseover method -->
<attribute name="tick" type="number" value="500" />
<handler name="onmouseover">
Debug.info('mouseover');
if (this.timeractive == false) {
this.setAttribute('timeractive', true);
this.timerdel = new lz.Delegate( this, "timerCallback" );
this.timer = lz.Timer.addTimer( this.timerdel, this.tick );
// When the timer is activated, do one call to the method
// containing the loop logic. The following calls will be
// handled by the timer and delegate.
this.doWhileMouseover();
}
</handler>
<handler name="onmouseout">
Debug.info('mouseout');
if (this.timeractive) {
this.setAttribute('timeractive', false);
lz.Timer.removeTimer(this.timerdel);
}
</handler>
<method name="timerCallback" args="millis">
if (this.timeractive) {
lz.Timer.resetTimer(this.timerdel, this.tick);
this.doWhileMouseover();
}
</method>
<method name="doWhileMouseover">
Debug.info("This is your virtual while loop for mouseover");
</method>
</class>
<mouseoverview x="100"
y="100"
width="400"
height="400"
bgcolor="#33aaff"
tick="250">
</mouseoverview>
</canvas>
マウスオーバーが発生すると、timerdel(lz.Delegateのインスタンス)を使用してタイマーが開始されます。次に、doWhileMouseover()メソッドが1回直接呼び出され、onmouseoutイベントが発生しない限り、タイマーを繰り返し使用します。
ソリューションが正しく動作することを確認するためにソリューションをテストしているときに、あなた自身の質問に答えたようですが、OpenLaszlo 4.9.0 SWF10 および OpenLaszlo 4.9.0 DHTML ランタイムで動作する別のソリューションを次に示します。
<canvas width="1000" height="665" debug="true">
<view id="v" bgcolor="0xcccccc" width="200" height="200">
<!--- @param boolean mouseisover: true when the mouse is over -->
<attribute name="mouseisover" type="boolean" value="false" />
<!--- @keywords private -->
<!--- @param lz.Delegate dlgt_repeat: stores the lz.Delegate object -->
<attribute name="dlgt_repeat" type="expression" />
<!--
Called when the 'onmouseover' event occurs
-->
<handler name="onmouseover">
// Step 1) unregister any existing delegate
// mark it for garbage collection
// and prevent its event from triggering:
if (this['dlgt_repeat'])
this.dlgt_repeat.unregisterAll();
// Step 2) update this.mouseisover flag:
if (!this.mouseisover)
this.setAttribute('mouseisover', true);
// Step 3) create an event Delegate and call it
// on the next application idle event:
var objDlgt = new lz.Delegate(this, 'doSomething');
this.setAttribute('dlgt_repeat', objDlgt);
lz.Idle.callOnIdle(this.dlgt_repeat);
</handler>
<!--
Called when the 'onmouseout' event occurs
-->
<handler name="onmouseout">
// Step 1) unregister any existing delegate
// mark it for garbage collection
// and prevent its event from triggering:
if (this['dlgt_repeat'])
this.dlgt_repeat.unregisterAll();
// Step 2) Update this.mouseisover flag:
if (this.mouseisover)
this.setAttribute('mouseisover', false);
</handler>
<!--- @keywords private -->
<!---
Called on application idle event by lz.Idle repeatedly
when the mouse is down.
@param ??? objDummy: required for SWF9+ run-times for methods
called by delegates due to AS3 (ActionScript3 compiler
requirements). Just set default to null to make compiler
happy and ignore...
-->
<method name="doSomething" args="objDummy=null">
<![CDATA[
// Note: CDATA allows '&&' to be used in script below,
// alternatively omit CDATA and use '&&' instead
// of '&&'
// Step 1) Execute your code you want to run here:
if ($debug) Debug.debug('Do something...');
// Step 2): If mouse is still over and the event
// delegate exists then schedule the event to be
// executed upon the next application idle state:
if (this.mouseisover && this['dlgt_repeat'] != null)
lz.Idle.callOnIdle(this.dlgt_repeat);
]]>
</method>
<text text="Move mouse over" />
</view>
</canvas>