长春做网站建设的公司,做网站小程序挣钱吗,野外美食网站设计欣赏,企业服务器小程序不能使用各种浏览器暴露出来的 DOM API#xff0c;进行 DOM 选中和操作
原因#xff1a;在小程序中#xff0c;渲染层和逻辑层是分开的#xff0c;分别运行在不同的线程中#xff0c;逻辑层运行在 JSCore 中#xff0c;并没有一个完整浏览器对象#xff0c;因而缺…小程序不能使用各种浏览器暴露出来的 DOM API进行 DOM 选中和操作
原因在小程序中渲染层和逻辑层是分开的分别运行在不同的线程中逻辑层运行在 JSCore 中并没有一个完整浏览器对象因而缺少相关的DOM API和BOM API。
为什么要这样设计
因为JavaScript是可操纵DOM的如果JavaScript线程和UI线程同时运行即在修改这些元素属性同时渲染界面那么渲染线程前后获得的元素数据就可能不一致导致传统web开发渲染线程和脚本线程是互斥的。于是当JavaScript引擎执行时GUI线程会被挂起GUI更新会被保存在一个队列中等到引擎线程空闲时立即被执行。 因此长时间的脚本运行可能会导致页面失去响应。
小程序DOM操作API —— SelectQuery
浏览器中
const demo document.querySelector(#demo)
console.log(demo.boundingClientRect().top)小程序中
const query wx.createSelectorQuery()
// 组件中const query wx.createSelectorQuery().in(组件id)
query.select(#demo).boundingClientRect()
query.exec(function (res) {console.log(res[0].top)
})可以发现有三点明显的区别
通过createSelectorQuery创建了一个query对象而不是document.querySelector在query对象上执行查询操作并非马上执行而是进入等待队列直至query对象上exec被调用才触发查询行为查询结果是异步返回的在callback中按查询顺序依次从参数中读取
第一点区别产生的原因是首先小程序双线程模型决定了业务代码中不能拿到document对象 也就无法在上面调用相关查询方法。那为什么要通过调用createSelectorQuery()返回查询对象而不是把查询对象定义为全局的呢这是因为小程序每个页面的视图层都对应一个webview而所有的页面都共用一个逻辑线程这种一对多的关系在通讯时需要有id来进行区分所以每次createSelectorQuery时返回的query对象是绑定了当前视图层webview对应id的。
第二、三点的查询非立即执行而是在exec被调用时真正触发比较好理解业务代码在逻辑线程真实dom在另一个webview线程线程间的通讯需要借助宿主能力完成query对象的exec方法被触发时小程序把callbak存储起来然后调用native宿主暴露的方法去通讯拿到webview线程查询回来的结果之后进行反序列化处理传递给先前保存的callbak并开始执行所以这里是异步的。