【问题标题】:What is an effective way to call jQuery plugins without a wrapper function in global scope from Flash?从 Flash 在全局范围内调用没有包装函数的 jQuery 插件的有效方法是什么?
【发布时间】:2011-08-21 02:03:35
【问题描述】:

我首先检查了这个问题: Calling jQuery Function from Flash

如果我们有如下风格的 jQuery 插件:

(function(){
 $.fn.pluginName = function () {
   var methods = {
     init: function ( options ) {
       var settings = $.extend( {}, {}, options ); // set your own defaults

       $('#flash')[0].initialise(settings);
     },
     initialised: function ( params ) {
       console.log(params);
     }
   };
   var method = 'init', args = [];
   if(0 < arguments.length) {
     if('object' === typeof(arguments[0])) {
       args = arguments;
     } else if('undefined' !== typeof(methods[arguments[0])) {
       args = Array.prototype.slice.call(arguments);
       args.shift();
       method = arguments[0];
     }
     methods[ method ].apply( this, args );
   }
   return this;
 };
})(jQuery);

假设我们用 id="flash" 初始化一个嵌入式 Flash 对象,然后调用:

$('#controller').pluginName('init',{});

并等待 flash 回调。

如果我写了一个函数,例如:

function flashCallBack( data ) {
 $('#controller').pluginName('init',data);
}

那么我可以在 AS3 中注册这个函数,但是有没有办法直接在适当的对象上调用插件方法,而不必在全局命名空间中编写上述封装函数?

这不起作用:

ExternalInterface.call("$('#controller').pluginName('initialised',"+data+")");

作为闪存上的函数名称字符串,也不是:

ExternalInterface.call("$('#controller').pluginName('initialised')",data);

任何人都可以为我指出如何直接进行此调用的正确方向或澄清它是否只是不受支持的操作吗?

最诚挚的感谢 :) 自动曝光

【问题讨论】:

    标签: jquery flash actionscript-3 externalinterface


    【解决方案1】:

    经过一些试验,我认为这样做的方法是可靠的,而不必具有全局函数:

    (function(){
     $.fn.pluginName = function () {
       var methods = {
         init: function ( options ) {
           var settings = $.extend( {}, {}, options ); // set your own defaults
    
           $('#flash')[0].initialise(settings);
           $(this).click(function(){
              $(this).pluginName('fromFlash');
           });
         },
         initialised: function ( params ) {
           console.log(params);
         },
         callFlash: function(subj,func, data){
            if($('#flash').length > 0){
               $('#flash')[0].callback({
                   subj: (subj || 'subjectName'),
                   message: {
                      func: (func || '$(\'#selector\').trigger'),
                      data: (data || 'click')
                   }
               });
            }
        },
        fromFlash: function(data){
           alert('called from flash');
           console.log(data);
        }
       };
       var method = 'init', args = [];
       if(0 < arguments.length) {
         if('object' === typeof(arguments[0])) {
           args = arguments;
         } else if('undefined' !== typeof(methods[arguments[0])) {
           args = Array.prototype.slice.call(arguments);
           args.shift();
           method = arguments[0];
         }
         methods[ method ].apply( this, args );
       }
       return this;
     };
    })(jQuery);
    

    1) 调用插件的方法传递参数发送到flash:

    $('#plugin').pluginName('callFlash','subjectName',{
        func:'$(\'#plugin\').trigger',
        data: 'click'
    });
    

    或者你可以像这样做一些更有趣的事情:

    $('#plugin').pluginName('callFlash','subjectName',{
        func: '$(\'#plugin\')[\'pluginName\']',
        data: 'fromFlash'
    });
    

    2) 从 flash 中调用该字符串作为外部回调函数字符串。

    public function callback ( msg: Object ): void {
    
        data[0] = msg.message.data; // function callback name
        data[1] = someValue; // from inside flash
    
        switch ( msg.subject ) {
            case "subjectName":
                        // should push an array to the method name of the jquery plugin
                ExternalInterface.call (msg.message.func, data);
            break;
        }
    }
    

    【讨论】:

      【解决方案2】:

      我认为你可以这样做:

      ExternalInterface.call("function() { $('#controller').pluginName('initialised',"+data+"); }");
      

      有点像直接在 ExternalInterface.call() 中定义(和运行)包装函数,而不是在页面的全局空间中定义它。

      我没有专门用 jQuery 插件尝试过,但是定义和执行这样的函数是可行的,例如:

      ExternalInterface.call("function() { alert('Hello World!') }");
      

      另一个技巧我相信在 SO 看到它之后,我使用的另一个技巧是在您想要编写和执行 JavaScript 时使用 ActionScript 支持内联 XML(作为 E4X 的一部分)的事实通过ExternalInterface,通过在XML CDATA块中编写JavaScript代码,带有换行符和缩进等,而不是连接一个JavaScript字符串,然后在ExternalInterface.call()中执行它(作为一个字符串),就像这样:

      var checkBrowser:XML = <![CDATA[
      function() { 
          return {name:navigator.appName, version:navigator.appVersion};
      }
      ]]>;
      
      var browser:Object = ExternalInterface.call(checkBrowser);
      
      trace("Browser: " + browser.name + ", version: " + browser.version);
      

      【讨论】:

      • 这个对我有用,但只有在将“$”更改为“jQuery”离开后:
      【解决方案3】:

      最简单的解决方案似乎是将您的 jquery 代码包装在一个基本的 javascript 函数中,然后使用外部接口从 flash 调用该顶级函数。我找到了这个例子,据说它可以工作:

      function showNeck () { 
         $('.neck').highlightFade({color:'#FFFF… speed: 5000}); 
      } 
      

      在 Flash 脚本中:

      import flash.external.*; 
      ExternalInterface.call("showNeck", ""); 
      

      来源:

      http://old.nabble.com/Call-Jquery-from-Flash--td24959832s27240.html

      【讨论】:

      • 嗨扬升系统。是的,我想做的是“避免”将其置于全局范围内。将其放入全局范围允许您使用我在问题中提出的第三种方法,但我现在正在查看的元素是直接调用 jQuery 插件的方法,而不是使用包装器。例如,如果可以使用 ExternalInterface('$.fn.pluginName','initialised',data);我会尝试,但这是无效的。不幸的是,我可以找到使用包装器的大多数资源,而不是探索它是否不可能或需要替代方法。谢谢!
      • 好吧,如果您找到解决方案,请务必发布!问题是您依赖于 Flash ExternalInteface API 的限制,这似乎是问题所在,因为 VM 不能(似乎)接受这种类型的参数。我相信这就是为什么我能找到的只是提出包装器的解决方案的原因。
      • 我应该 =D 我不确定那里是否有一个,但我想我不妨尝试为其他人提供一个明确的问题和答案,以帮助他们继续前进或帮助他们移动让全局函数更快并节省一点时间 =D 感谢 Ascension Systems。出于同样的原因,我想知道是否可以出于同样的原因将其称为: window['functionName'] 而不是 'functionName' 。有什么想法吗?
      猜你喜欢
      • 2013-06-21
      • 2014-01-07
      • 2018-09-22
      • 2013-06-30
      • 2020-01-17
      • 1970-01-01
      • 2013-08-04
      • 2018-07-01
      • 2012-11-09
      相关资源
      最近更新 更多