1

有没有可能做这样的事情

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

只要鼠标悬停在特定视图上,我就希望重复一个动作。
(在 laszlo-user 邮件列表中询问)

4

2 回答 2

1

由于 ActionScript 和 JavaScript 都是单线程的,因此在每次循环迭代之间不可能有一个带有暂停的 while 循环。在 SWF10/11 运行时中,您需要确保每个方法或函数中的代码可以在应用程序的一帧(持续时间取决于 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()方法一次,然后重复使用定时器,只要没有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 回答