Duilib嵌入CEF以及JavaScript与C++交互
转载:http://blog.csdn.net/foruok/article/details/50573612
转载:http://blog.csdn.net/foruok/article/details/50584985
转载:http://blog.csdn.net/mfcing/article/details/44539035
转载:https://github.com/fanfeilong/cefutil/blob/master/doc/CEF_JavaScript_Cpp.md
转载:https://blog.csdn.net/aseseven/article/details/79482515(CEF3加载本地HTML文件时中文路径乱码的问题解决办法)
转载:https://blog.csdn.net/u012778714/article/category/7003599
JS与Native代码交互,是在Render进程中,所以我们要实现CefRenderProcessHandler接口
一、JS 调用 C++
- JavaScript注册函数给Render进程,Render进程保存该JavaScript函数
- Render进程发消息通知Browser进程
- Browser进程处理后,回发消息给Render进程
- Render进程调用之前保存的JavaScript函数
1.带参数没有返回值
自己的APP类要继承于CefRenderProcessHandler
- #ifndef _CEFBROWSERAPP_H_
- #define _CEFBROWSERAPP_H_
- #include "include/cef_app.h"
- #include "CEFV8HandlerEx.h"
- class CCefBrowserApp
- : public CefApp
- , public CefBrowserProcessHandler
- , public CefRenderProcessHandler
- {
- public:
- CCefBrowserApp();
- virtual ~CCefBrowserApp();
- public:
- virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()OVERRIDE { return this; };
- public:
- // CefBrowserProcessHandler methods:
- virtual void OnContextInitialized();
- //CefRenderProcessHandler methods
- virtual void OnWebKitInitialized();
- CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE{ return this; }
- virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context);
- virtual void OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context);
- protected:
- CefRefPtr<CCEFV8HandlerEx> m_v8Handler;
- IMPLEMENT_REFCOUNTING(CCefBrowserApp);
- };
- #endif //_CEFBROWSERAPP_H_
.cpp
- #include "CefBrowserApp.h"
- #include "stdafx.h"
- CCefBrowserApp::CCefBrowserApp()
- :m_v8Handler(new CCEFV8HandlerEx)
- {
- }
- CCefBrowserApp::~CCefBrowserApp()
- {
- }
- void CCefBrowserApp::OnContextInitialized()
- {
- // do nothing here, because we will create browser in my own dialog
- }
- void CCefBrowserApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
- CefRefPtr<CefFrame> frame,
- CefRefPtr<CefV8Context> context)
- {
- // Retrieve the context's window object.
- CefRefPtr<CefV8Value> object = context->GetGlobal();
- // Create the "NativeLogin" function.
- CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("NativeLogin", m_v8Handler);
- // Add the "NativeLogin" function to the "window" object.
- object->SetValue("NativeLogin", func, V8_PROPERTY_ATTRIBUTE_NONE);
- }
- void CCefBrowserApp::OnWebKitInitialized()
- {
- std::string app_code =
- "var app;"
- "if (!app)"
- " app = {};"
- "(function() {"
- " app.GetId = function() {"
- " native function GetId();"
- " return GetId();"
- " };"
- "})();";
- // Registered Javascript Function, which will be called by Cpp
- " app.registerJavascriptFunction = function(name,callback) {"
- " native function registerJavascriptFunction();"
- " return registerJavascriptFunction(name,callback);"
- " };"
- "})();";
- CefRegisterExtension("v8/app", app_code, m_v8Handler);//第一个参数不能为空,否则报错,这个名字可以自定义
- }
- 注:CefRegisterExtension的注释
- // Example JavaScript extension code:
- // <pre>
- // // create the 'example' global object if it doesn't already exist.
- // if (!example)
- // example = {};
- // // create the 'example.test' global object if it doesn't already exist.
- // if (!example.test)
- // example.test = {};
- // (function() {
- // // Define the function 'example.test.myfunction'.
- // example.test.myfunction = function() {
- // // Call CefV8Handler::Execute() with the function name 'MyFunction'
- // // and no arguments.
- // native function MyFunction();
- // return MyFunction();
- // };
- // // Define the getter function for parameter 'example.test.myparam'.
- // example.test.__defineGetter__('myparam', function() {
- // // Call CefV8Handler::Execute() with the function name 'GetMyParam'
- // // and no arguments.
- // native function GetMyParam();
- // return GetMyParam();
- // });
- // // Define the setter function for parameter 'example.test.myparam'.
- // example.test.__defineSetter__('myparam', function(b) {
- // // Call CefV8Handler::Execute() with the function name 'SetMyParam'
- // // and a single argument.
- // native function SetMyParam();
- // if(b) SetMyParam(b);
- // });
- //
- // // Extension definitions can also contain normal JavaScript variables
- // // and functions.
- // var myint = 0;
- // example.test.increment = function() {
- // myint += 1;
- // return myint;
- // };
- // })();
- // </pre>
- // Example usage in the page:
- // <pre>
- // // Call the function.
- // example.test.myfunction();
- // // Set the parameter.
- // example.test.myparam = value;
- // // Get the parameter.
- // value = example.test.myparam;
- // // Call another function.
- // example.test.increment();
- // </pre>
- ///
- void CCefBrowserApp::OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
- {
- m_v8Handler = nullptr;
- }
OnContextCreated给window对象绑定了一个NativeLogin函数,这个函数将由ClientV8Handler类来处理,当HTML中的JS代码调用window.NativeLogin时,ClientV8Handler的Execute方法会被调用。
OnWebKitInitialized注册了一个名为app的JS扩展,在这个扩展里为app定义了GetId方法,app.GetId内部调用了native版本的GetId()。HTML中的JS代码可能如下:
- alert(app.GetId());
当浏览器执行上面的代码时,CCEFV8HandlerEx的Execute方法会被调用,现在来看CCEFV8HandlerEx的实现
.h
- #ifndef _CEFV8HANDLEREX_H_
- #define _CEFV8HANDLEREX_H_
- #include "include/cef_v8.h"
- class CCEFV8HandlerEx : public CefV8Handler {
- public:
- CCEFV8HandlerEx();
- ~CCEFV8HandlerEx();
- public:
- virtual bool Execute(const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception) override;
- private:
- // Map of message callbacks.
- typedef std::map<std::pair<std::string, int>, std::pair<CefRefPtr<CefV8Context>, CefRefPtr<CefV8Value> > >CallbackMap;
- CallbackMap callback_map_;
- protected:
- IMPLEMENT_REFCOUNTING(CCEFV8HandlerEx);
- };
- #endif//_CEFV8HANDLEREX_H_
.cpp
- #include "CEFV8HandlerEx.h"
- #include "stdafx.h"
- #include <strsafe.h>
- CCEFV8HandlerEx::CCEFV8HandlerEx()
- {
- }
- CCEFV8HandlerEx::~CCEFV8HandlerEx()
- {
- // Remove any JavaScript callbacks registered for the context that has been released.
- if (!callback_map_.empty()) {
- CallbackMap::iterator it = callback_map_.begin();
- for (; it != callback_map_.end();) {
- if (it->second.first->IsSame(it->second.first))
- callback_map_.erase(it++);
- else
- ++it;
- }
- }
- }
- bool CCEFV8HandlerEx::Execute(const CefString& name /*JavaScript调用的C++方法名字*/, CefRefPtr<CefV8Value> object /*JavaScript调用者对象*/, const CefV8ValueList& arguments /*JavaScript传递的参数*/, CefRefPtr<CefV8Value>& retval /*返回给JS的值设置给这个对象*/, CefString& exception/*通知异常信息给JavaScript*/)
- {
- if (name == "NativeLogin")
- {//Window Binding
- if (arguments.size() == )
- {
- CefString strUser = arguments.at()->GetStringValue();
- CefString strPassword = arguments.at()->GetStringValue();
- //TODO: doSomething() in native way
- CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("login_msg");
- // Retrieve the argument list object.
- CefRefPtr<CefListValue> args = msg->GetArgumentList();
- // Populate the argument values.
- args->SetSize();
- args->SetString(, strUser);
- args->SetString(, strPassword);
- // Send the process message to the browser process.
- CefV8Context::GetCurrentContext()->GetBrowser()->SendProcessMessage(PID_BROWSER, msg);
- retval = CefV8Value::CreateInt();//函数的返回值 我们可以拿这个返回值做判断或者其他操作
//var result = window.NativeLogin(document.getElementById("userName").value, document.getElementById("password").value);
//document.getElementById("text").innerHTML = result
- }
- else
- {
- retval = CefV8Value::CreateInt();
- }
- return true;
- }
- else if (name == "GetId")
- {//JS Extensions
- if (arguments.size() == )
- {
- // execute javascript
- // just for test
- CefRefPtr<CefFrame> frame = CefV8Context::GetCurrentContext()->GetBrowser()->GetMainFrame();
- frame->ExecuteJavaScript("alert('Hello, I came from native world.')", frame->GetURL(), );
- // return to JS
- retval = CefV8Value::CreateString("");
- return true;
- }
- }
- // Function does not exist.
- return false;
- }
在Browser进程中接受Render进程发过来的消息
重写 virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process,CefRefPtr<CefProcessMessage> message);这个虚函数
我把C++函数都写在了窗口类中,所以我对CCefBrowserEventHandler做了修改,把窗口指针传到Browser中,方便调用
.h
- #ifndef _CEFBROWSEREVENTHANDLER_H_
- #define _CEFBROWSEREVENTHANDLER_H_
- #include "include/cef_client.h"
- #include "include/base/cef_lock.h" //线程安全
- class CMainFrameWnd;
- class CCefBrowserEventHandler
- : public CefClient
- , public CefDisplayHandler // 显示变化事件
- , public CefLoadHandler // 加载错误事件
- , public CefLifeSpanHandler // 声明周期事件
- //, public CefContextMenuHandler // 上下文菜单事件
- //, public CefDialogHandler // 对话框事件
- //, public CefDownloadHandler // 下载事件
- //, public CefDragHandler // 拖拽事件
- //, public CefFindHandler // 查找事件
- //, public ...
- {
- public:
- CCefBrowserEventHandler(CMainFrameWnd* pMainFrame);
- virtual ~CCefBrowserEventHandler();
- public:
- // CefClient 事件处理器,如果没有对应处理器则默认使用内部处理器
- virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE;
- virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE;
- virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE;
- public:
- // display handler method
- virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) OVERRIDE;
- public:
- // load handler method
- virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
- ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE;
- public:
- // display handler meethod
- virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
- virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
- virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
- virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
- CefProcessId source_process,
- CefRefPtr<CefProcessMessage> message);
- bool IsClosing() const { return m_bIsClosing; }
- CefRefPtr<CefBrowser> GetBrowser(){return m_Browser;}
- protected:
- CefRefPtr<CefBrowser> m_Browser;
- bool m_bIsClosing;
- CMainFrameWnd* m_pMainWnd;
- IMPLEMENT_REFCOUNTING(CCefBrowserEventHandler);
- //由于CEF采用多线程架构,有必要使用锁和闭包来保证在多不同线程安全的传递数据。IMPLEMENT_LOCKING定义提供了Lock()和Unlock()方法以及AutoLock对象来保证不同代码块同步访问
- IMPLEMENT_LOCKING(CCefBrowserEventHandler);//必须包含#include "include/base/cef_lock.h"
- };
- #endif//_CEFBROWSEREVENTHANDLER_H_
.cpp
- #include "CefBrowserEventHandler.h"
- #include "stdafx.h"
- #include <sstream>
- #include <string>
- #include "include/cef_app.h"
- #include "include/wrapper/cef_closure_task.h"
- #include "include/wrapper/cef_helpers.h"
- #include "MainFrameWnd.h"
- CCefBrowserEventHandler::CCefBrowserEventHandler(CMainFrameWnd* pMainFrame)
- :m_bIsClosing(false)
- ,m_pMainWnd(pMainFrame)
- {
- }
- CCefBrowserEventHandler::~CCefBrowserEventHandler()
- {
- }
- CefRefPtr<CefDisplayHandler> CCefBrowserEventHandler::GetDisplayHandler()
- {
- return this;
- }
- CefRefPtr<CefLifeSpanHandler> CCefBrowserEventHandler::GetLifeSpanHandler()
- {
- return this;
- }
- CefRefPtr<CefLoadHandler> CCefBrowserEventHandler::GetLoadHandler()
- {
- return this;
- }
- void CCefBrowserEventHandler::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title)
- {
- }
- void CCefBrowserEventHandler::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode,
- const CefString& errorText, const CefString& failedUrl)
- {
- CEF_REQUIRE_UI_THREAD();
- if (ERR_ABORTED == errorCode)
- return ;
- std::stringstream ss;
- ss << "<html><body bgcolor=\"white\">"
- "<h2>Failed to load URL " << std::string(failedUrl) <<
- " with error " << std::string(errorText) << " (" << errorCode <<
- ").</h2></body></html>";
- frame->LoadString(ss.str(), failedUrl);
- }
- void CCefBrowserEventHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
- {
- CEF_REQUIRE_UI_THREAD();
- //base::AutoLock lock_scope(lock_);
- AutoLock lock_scope(this);
- m_Browser = browser;
- }
- bool CCefBrowserEventHandler::DoClose(CefRefPtr<CefBrowser> browser)
- {
- CEF_REQUIRE_UI_THREAD();
- //base::AutoLock lock_scope(lock_);
- AutoLock lock_scope(this);
- if(m_Browser)
- {
- // Set a flag to indicate that the window close should be allowed.
- m_bIsClosing = true;
- }
- return false;
- }
- void CCefBrowserEventHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
- {
- CEF_REQUIRE_UI_THREAD();
- //base::AutoLock lock_scope(lock_);
- AutoLock lock_scope(this);
- if(m_Browser->IsSame(browser))
- m_Browser = NULL;
- }
- bool CCefBrowserEventHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
- CefProcessId source_process,
- CefRefPtr<CefProcessMessage> message)
- {
- const std::string& messageName = message->GetName();
- if (messageName == "login_msg")
- {
- // extract message
- CefRefPtr<CefListValue> args = message->GetArgumentList();
- CefString strUser = args->GetString();
- CefString strPassword = args->GetString();
- m_pMainWnd->CEFLoginJsCallCPP(strUser,strPassword);//窗口类的成员函数
- //如果函数有返回值也可以通过向Render发送消息传递
- //send reply to render process
- CefRefPtr<CefProcessMessage> outMsg = CefProcessMessage::Create("login_reply");
- // Retrieve the argument list object.
- CefRefPtr<CefListValue> replyArgs = outMsg->GetArgumentList();
- // Populate the argument values.
- replyArgs->SetSize();
- replyArgs->SetInt(, );
- // Send the process message to the renderer process.
- browser->SendProcessMessage(PID_RENDERER, outMsg);
- return true;
- }
- return false;
- }
Browser进程处理完后向Render进程发了消息,The render process receives the IPC message处理
.h
- #ifndef _CEFBROWSERAPP_H_
- #define _CEFBROWSERAPP_H_
- #include "include/cef_app.h"
- #include "CEFV8HandlerEx.h"
- class CCefBrowserApp
- : public CefApp
- , public CefBrowserProcessHandler
- , public CefRenderProcessHandler
- {
- public:
- CCefBrowserApp();
- virtual ~CCefBrowserApp();
- public:
- virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()OVERRIDE { return this; };
- public:
- // CefBrowserProcessHandler methods:
- virtual void OnContextInitialized();
- //CefRenderProcessHandler methods
- virtual void OnWebKitInitialized();
- CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE{ return this; }
- virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context);
- virtual void OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context);
- //收消息
- virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message);
- protected:
- CefRefPtr<CCEFV8HandlerEx> m_v8Handler;
- IMPLEMENT_REFCOUNTING(CCefBrowserApp);
- };
- #endif //_CEFBROWSERAPP_H_
.cpp
- #include "CefBrowserApp.h"
- #include "stdafx.h"
- CCefBrowserApp::CCefBrowserApp()
- :m_v8Handler(new CCEFV8HandlerEx)
- {
- }
- CCefBrowserApp::~CCefBrowserApp()
- {
- }
- void CCefBrowserApp::OnContextInitialized()
- {
- // do nothing here, because we will create browser in my own dialog
- }
- void CCefBrowserApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
- CefRefPtr<CefFrame> frame,
- CefRefPtr<CefV8Context> context)
- {
- // Retrieve the context's window object.
- CefRefPtr<CefV8Value> object = context->GetGlobal();
- // Create the "NativeLogin" function.
- CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("NativeLogin", m_v8Handler);//第一个参数和SetValue参数保持一致,否则无法调用
- // Add the "NativeLogin" function to the "window" object.
- object->SetValue("NativeLogin", func, V8_PROPERTY_ATTRIBUTE_NONE);
- // Add the "register" function to the "window" object.
- object->SetValue("register",CefV8Value::CreateFunction("register", m_v8Handler),V8_PROPERTY_ATTRIBUTE_NONE);
- }
- void CCefBrowserApp::OnWebKitInitialized()
- {
- std::string app_code =
- "var app;"
- "if (!app)"
- " app = {};"
- "(function() {"
- " app.GetId = function() {"
- " native function GetId();"
- " return GetId();"
- " };"
- "})();";
- // Registered Javascript Function, which will be called by Cpp
- " app.registerJavascriptFunction = function(name,callback) {"
- " native function registerJavascriptFunction();"
- " return registerJavascriptFunction(name,callback);"
- " };"
- "})();";
- CefRegisterExtension("v8/app", app_code, m_v8Handler);//第一个参数不能为空
- }
- void CCefBrowserApp::OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
- {
- m_v8Handler = nullptr;
- }
- bool CCefBrowserApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,CefProcessId source_process,CefRefPtr<CefProcessMessage> message)
- {
- const std::string& messageName = message->GetName();
- if (messageName == "login_reply")
- {
- // extract message
- CefRefPtr<CefListValue> args = message->GetArgumentList();
- bool status = args->GetBool();
- CefRefPtr<CefFrame> frame = browser->GetMainFrame();
- if (status)
- {
- frame->ExecuteJavaScript("IsSuccess();", frame->GetURL(), );
- }
- return true;
- }
- return false;
- }
2.JS CallBack
在OnContextCreated()函数中给window绑定函数
- // Create the "register" function.
- CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("register", m_v8Handler);//第一个参数和SetValue参数保持一致,否则无法调用
- // Add the "register" function to the "window" object.
- object->SetValue("register", func, V8_PROPERTY_ATTRIBUTE_NONE);
在Exectue()函数中处理
- else if (name == "register")
- {
- if (arguments.size() == && arguments[]->IsFunction())
- {
- CefRefPtr<CefV8Value> callback_func_ = arguments[];
- CefRefPtr<CefV8Context> callback_context_ = CefV8Context::GetCurrentContext();
- callback_func_->ExecuteFunction(NULL, arguments);//执行回调函数
- return true;
- }
- }
在HTML的JavaScript里这样写
- function myFunc()
- {
- // do something in JS.
- alert("callback");
- }
- //js CALLback
- function CallBack()
- {
- window.register(myFunc);
- }
3.C++ 调用 JS
C++调用JS函数相对简单多了,因为CEF有接口可以直接使用CefFrame::ExecuteJavaScript,看看注释:
- ///
- // Execute a string of JavaScript code in this frame. The |script_url|
- // parameter is the URL where the script in question can be found, if any.
- // The renderer may request this URL to show the developer the source of the
- // error. The |start_line| parameter is the base line number to use for error
- // reporting.
- ///
- /*--cef(optional_param=script_url)--*/
- virtual void ExecuteJavaScript(const CefString& code,
- const CefString& script_url,
- int start_line) =;
首先需要获取到我们的浏览器里的主框架对象,code是JS函数和传入参数的字符串,URL可以直接忽略。
- CefRefPtr<CefFrame> frame = m_handler->GetBrowser()->GetMainFrame();
- m_handler是我们自己定义的Handler对象
- /C++ 调用js方法
- //frame->ExecuteJavaScript(L"Test();",frame->GetURL(),0);//提示框
- //frame->ExecuteJavaScript(L"ModifyValue();",frame->GetURL(),0);//无参数函数
- frame->ExecuteJavaScript(L"ModifyValue('巴萨牛逼');",frame->GetURL(),);//有参数函数
9 如果参数是可变的,可以这样
- CString strJsCode;
strJsCode.Format(L"setInstallStatus('%s','%s','%d');", lpData->strId.c_str(), strStatus, nPercent);
- 其中setInstallStatus是js函数,它有三个参数
我在HMTL里写的
- function Test()
- {
- alert("js被C++非礼了");
- }
- function ModifyValue( arr)
- {
- //document.getElementById("text").innerHTML = "被修改了";
- alert(arr);
- document.getElementById("text").innerHTML = arr;
- }
Duilib嵌入CEF以及JavaScript与C++交互的更多相关文章
- CEF中JavaScript与C++交互
在CEF里,JS和Native(C/C++)代码能够非常方便的交互,这里https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegr ...
- Duilib嵌入CEF出现窗口显示不正常
参考资料:https://www.aliyun.com/zixun/wenji/1247250.html 转载:https://www.cnblogs.com/gongxijun/p/4857977. ...
- Duilib嵌入CEF禁止浏览器响应拖拽事件
转载:http://blog.csdn.net/liuyan20092009/article/details/53819473 转载:https://blog.csdn.net/u012778714( ...
- iOS中JavaScript和OC交互
转载自:http://www.devzeng.com/blog/ios-uiwebview-interaction-with-javascript.html 还可参考的文章:http://blog.c ...
- jQuery基础与JavaScript与CSS交互-第五章
目录 JavaScript框架种类及其优缺点 jQuery库 jQuery对象$ 掌握基本选择器 掌握过滤选择器 掌握表单选择器 RIA技术 常见的RIA技术 Ajax Sliverlight Fle ...
- 在android中实现webview与javascript之间的交互(转)
参见“在android中实现webview与javascript之间的交互”
- Hybrid App: 对比UIWebView和WebKit实现JavaScript与Native交互
一.简介 在前面一篇文章中讲到过实现JavaScript与Native交互的方式有一种就是使用原生内嵌webView.在iOS8之前,开发者只能使用苹果提供的UIWebView类来加载URL或者HTM ...
- Qt和JavaScript使用QWebChannel交互一——和Qt内嵌网页交互
Qt和JavaScript使用QWebChannel交互一--和Qt内嵌网页交互 目录 Qt和JavaScript使用QWebChannel交互一--和Qt内嵌网页交互 前言 一.效果 二.实现过程 ...
- iOS中JavaScript和OC交互 --by 胡 xu
在iOS开发中很多时候我们会和UIWebView打交道,目前国内的很多应用都采用了UIWebView的混合编程技术,最常见的是微信公众号的内容页面.前段时间在做微信公众平台相关的开发,发现很多应用场景 ...
随机推荐
- 升级win8.1后mysql服务不能启动的问题
升级win8.1后发现服务列表中MySQL55不见了. 1. 先把服务恢复. mysql没有看到maitenance,找到安装文件 mysql-installer-community-5.6.12.0 ...
- Net中httpResponse和httpRequest的简单实用;
这对象很简单,封装很多常用的方法和属性:使用起来也很方便: 这个关键是要对我们的 http中的各种协议要很了解滴呀: 模拟一个简单的暴力破解: public static class HttpInfo ...
- 英康手机订单系统APP使用说明
1.登陆手机APP 输入卖家提供的账号和密码登陆APP. 2.商品购买列表 可以在全部商品.促销商品.收藏商品.最近订购.再次购买等几种商品列表下把商品加入购物车: 3.加入商品到购物车 点击商品列表 ...
- ios - runtime运行时应用---交换方法
runtime运行时用法之一 --- 交换类的方法,此处简单写了把系统的UIView的setBackgroundColor的方法换成了自定义的pb_setBackgroundColor 首先创建UIV ...
- onload事件-----addLoadEvent函数
在给网页加一些特效时经常要在<body>中加入“onload”事件,即在网页加载完后执行某事件,例如:<body onload=”alert(‘欢迎光临!')”,但这样做有个大的缺陷 ...
- PC管理端与评委云打分配合步骤及疑难问题汇编,即如何使用PC管理端的云服务管理功能
一.前期环境及数据准备 A.PC管理端主要流程 1.进入菜单 编辑/选项/服务器 界面,如下图所示,采用我官方所提供的云服务,不采用自己假设的AppWeb服务. 切记:AppWeb服务和云服务只能二选 ...
- html页面定位
对于css中的position:relative;我始终搞不明白它是什么意思,有什么作用? 对于position的其它几个属性,我都搞懂了 引用 static : 无特殊定位,对象遵循HTML定位规则 ...
- 暑假CTF训练一
暑假CTF训练一 围在栅栏中的爱 题目: 最近一直在好奇一个问题,QWE到底等不等于ABC? -.- .. --.- .-.. .-- - ..-. -.-. --.- --. -. ... --- ...
- AD中各层的说明
PCB各层说明: 1.丝印层(OverLay,Silkscreen):有顶层丝印和底层丝印.用来画器件轮廓,器件编号和一些图案等. 2.信号层(SignalLayer):对于两层板,主要是TopLay ...
- NOI 1.5 42:画矩形
描述 根据参数,画出矩形. 输入 输入一行,包括四个参数:前两个参数为整数,依次代表矩形的高和宽(高不少于3行不多于10行,宽不少于5列不多于10列):第三个参数是一个字符,表示用来画图的矩形符号:第 ...