1

このようなことをすることは可能ですか

while (view.mouseover == true) {
    preform action
}

マウスが特定のビューの上にある限り、アクションを繰り返したいです。
(laszlo-user メーリングリストで質問されました)

4

2 に答える 2

1

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イベントが発生しない限り、タイマーを繰り返し使用します。

于 2012-09-18T19:12:20.187 に答える
1

ソリューションが正しく動作することを確認するためにソリューションをテストしているときに、あなた自身の質問に答えたようですが、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 '&amp;&amp;' 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>
于 2012-09-18T20:07:43.190 に答える