虎绿林HU60.CN
发现版块
Enter
发布登录
发现版块发布我的社区荣誉
登录
虎绿林让技术讨论持续生长
主题Jhin经典
京ICP备18041936号-1

有什么方式可以将web页面封装成apk

张小强
2023年1月24日讨论/求助
40.7万 63
免费开源的方案?
登录后收藏
楼层讨论

63 条回复

默认正序
无
无名啊2023年1月24日
#1

@张小强,一个木函、Fusion App 啥的可以么?(没咋用过,但记得有这个功能)

罐
罐子2023年1月24日
#2

@张小强,封装成小程序我试过,APP应该也是可以
一加8Pro

童真再见2023年1月25日
#3

用APP封装的容易闪退
手机

hik2023年1月25日
#4
webcat
张小强2023年3月26日
#5
@ChatGPT 写一个js方法获取sessionStorage会话存储中的tk值,如果这个值不存在则使用fetch请求api获取这个值并返回,
ChatGPT2023年3月26日
#6

@张小强,好的,下面是一个获取sessionStorage中tk值或使用fetch请求获取tk值的JavaScript方法:

async function getTk() {
  let tk = sessionStorage.getItem('tk');
  if (tk) {
    return tk;
  } else {
    try {
      const response = await fetch('https://api.example.com/tk');
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      const data = await response.text();
      sessionStorage.setItem('tk', data);
      return data;
    } catch (error) {
      console.error('There was a problem with the fetch operation:', error);
    }
  }
}

在这个方法中,我们首先尝试从sessionStorage中获取tk值。如果存在,则直接返回该值。

如果不存在,则使用fetch函数请求https://api.example.com/tk接口获取tk值。在获取到tk值之后,我们将其存储到sessionStorage中,并将其返回。

在获取tk值的过程中,如果发生了错误,则使用catch方法捕获并处理它们。在该示例中,我们将错误打印到控制台中,但也可以根据具体情况进行其他处理。

需要注意的是,该方法使用了async/await语法糖,需要在支持ES6+的环境中运行。如果需要兼容旧版浏览器,可以使用Promise和then/catch语法来替代async/await。

张小强2023年3月26日
#7
@ChatGPT,Js遍历dom树,将所有的文本放在一个json数组中,并将这个json转换成文本fetch header中发送给服务器翻译,翻译结果返回为json数组格式,然后遍历这个json数组将页面上对应dom中的文字替换成翻译后的。
ChatGPT2023年3月26日
#8

@张小强,好的,下面是一个使用JavaScript遍历DOM树,将所有文本放在一个JSON数组中,并使用fetch将该JSON数组发送到服务器进行翻译,并将翻译结果应用于页面的示例代码:

// 遍历DOM树,将所有文本存储在一个JSON数组中
function getTextNodes(node, textNodes = []) {
  if (node.nodeType === Node.TEXT_NODE) {
    if (node.nodeValue.trim() !== '') {
      textNodes.push({
        text: node.nodeValue.trim(),
        translatedText: ''
      });
    }
  } else {
    for (let i = 0; i < node.childNodes.length; i++) {
      getTextNodes(node.childNodes[i], textNodes);
    }
  }
  return textNodes;
}

// 将JSON数组转换为文本,用于发送给服务器
function toJSONString(data) {
  return JSON.stringify(data, function(key, value) {
    return (typeof value === 'function') ? value.toString() : value;
  });
}

// 翻译文本并将结果应用于DOM树
async function translateText() {
  const textNodes = getTextNodes(document.body);
  const jsonData = toJSONString(textNodes);

  try {
    const response = await fetch('https://api.example.com/translate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: jsonData
    });

    if (!response.ok) {
      throw new Error('Network response was not ok');
    }

    const translatedData = await response.json();

    for (let i = 0; i < textNodes.length; i++) {
      textNodes[i].translatedText = translatedData[i].translatedText;
      textNodes[i].parentNode.replaceChild(document.createTextNode(translatedData[i].translatedText), textNodes[i]);
    }

  } catch (error) {
    console.error('There was a problem with the fetch operation:', error);
  }
}

translateText();

在这个示例代码中,我们首先定义了一个getTextNodes函数,用于遍历DOM树并将所有文本节点存储在一个JSON数组中。该函数使用递归实现DOM树的遍历,并将每个文本节点存储为一个对象,其中包含原始文本和翻译后的文本(初始值为空字符串)。

然后,我们定义了一个toJSONString函数,用于将JSON数组转换为文本字符串,以便我们可以将其发送到服务器进行翻译。该函数使用JSON.stringify方法将JSON数组转换为文本字符串,并将其中的函数转换为字符串形式。

接下来,我们定义了一个translateText函数,该函数将调用getTextNodes函数获取所有文本节点,并将其转换为JSON字符串,然后使用fetch函数将该JSON字符串发送到服务器进行翻译。

在发送请求之后,我们检查响应是否成功,如果成功,则将翻译后的数据存储在一个新数组中,并遍历文本节点数组,将翻译后的文本应用于每个节点。具体来说,我们使用parentNode.replaceChild方法替换原始文本节点为翻译后的文本节点。

最后,我们在函数末

张小强2023年3月26日
#9
  <script>
    const jsonArr = [];
    const textSet = new Set();

    function traverse(node) {
      if (
        node.nodeType === Node.ELEMENT_NODE &&
        (node.tagName.toLowerCase() === 'head' ||
          node.tagName.toLowerCase() === 'pre' ||
          node.tagName.toLowerCase() === 'script' ||
          node.tagName.toLowerCase() === 'textarea')
      ) {
        return; // 排除 <head>, <pre>, <script>, <textarea> 标签
      }
      if (node.nodeType === Node.TEXT_NODE) {
        const text = node.textContent.trim();
        if (text !== '' && !textSet.has(text)) {
          textSet.add(text); // 将文本内容添加到 Set 中
          jsonArr.push({ "Text": text }); // 添加文本内容到 JSON 数组中
        }
      }
      for (const child of node.childNodes) {
        traverse(child); // 递归遍历子节点
      }
    }

    traverse(document.body); // 从 <body> 元素开始遍历 DOM 树

    fetch('https://edge.microsoft.com/translate/auth', {
      method: 'GET',
      headers: {
        'authority': 'edge.microsoft.com',
        'accept': '*/*',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'origin': window.location.origin,
        'referer': window.location.origin,
        'sec-ch-ua': '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'cross-site',
        'sec-mesh-client-arch': 'x86_64',
        'sec-mesh-client-edge-channel': 'stable',
        'sec-mesh-client-edge-version': '111.0.1661.51',
        'sec-mesh-client-os': 'Windows',
        'sec-mesh-client-os-version': '10.0.18362',
        'sec-mesh-client-webview': '0',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51'
      }
    })
      .then(response => response.text())
      .then(response => {
        sessionStorage.setItem("translateauth", response);
        return response;
      })
      .then(translateauth => {
        return fetch('https://api.cognitive.microsofttranslator.com/translate?from=zh-CHS&to=en&api-version=3.0&includeSentenceLength=true', {
          method: 'POST',
          headers: {
            'authority': 'api.cognitive.microsofttranslator.com',
            'accept': '*/*',
            'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
            'authorization': 'Bearer ' + translateauth,
            'content-type': 'application/json',
            'origin': window.location.origin,
            'referer': window.location.origin,
            'sec-ch-ua': '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"Windows"',
            'sec-fetch-dest': 'empty',
            'sec-fetch-mode': 'cors',
            'sec-fetch-site': 'cross-site',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51'
          },
          body: JSON.stringify(jsonArr),
          redirect: 'follow'
        }).then(response => response.json())
      }).then(response => {
        console.log(response);
      })
  </script>
张小强2023年3月27日
#10
@ChatGPT,js写一个例子: 先从sessionStorage中读取token值,利用fetch请求数据接口,如果返回401错误时,先去另外一个接口请求最新的token值,并更新sessionStorage,然后再用新的 sessionStorage去数据接口获取数据,請求數據和token封裝成方法,以方便重複調
ChatGPT2023年3月27日
#11

[新会话] @张小强,好的,以下是一个示例代码,其中包含了从SessionStorage中获取Token值,以及更新Token值的逻辑,同时将请求数据和Token封装成了方法,以方便重复调用:

// 获取Token值的方法
function getToken() {
  return sessionStorage.getItem('token');
}

// 更新Token值的方法
function updateToken() {
  return fetch('/refreshToken')
    .then(response => response.json())
    .then(data => {
      sessionStorage.setItem('token', data.token);
      return data.token;
    });
}

// 请求数据的方法,包含自动更新Token的逻辑
function fetchData(url) {
  const headers = {
    'Authorization': `Bearer ${getToken()}`
  };
  
  return fetch(url, { headers })
    .then(response => {
      if (response.status === 401) {
        return updateToken().then(newToken => {
          headers.Authorization = `Bearer ${newToken}`;
          return fetch(url, { headers });
        });
      }
      return response;
    })
    .then(response => response.json());
}

// 使用示例
fetchData('/data').then(data => {
  console.log(data);
}).catch(error => {
  console.error(error);
});

在这个示例代码中,getToken()方法用于从SessionStorage中获取Token值,updateToken()方法用于向服务器请求最新的Token值,并将其更新到SessionStorage中。fetchData()方法是我们封装的请求数据的方法,它会在请求数据时自动携带SessionStorage中的Token值,并在收到服务器返回的401错误时调用updateToken()方法来获取新的Token值,并重新发送请求。

使用示例中的代码,我们可以调用fetchData('/data')来获取数据。如果在请求数据时收到了401错误,它会自动调用updateToken()方法来获取新的Token值,并重新发送请求。

张小强2023年3月27日
#12
@ChatGPT,js写一个例子: 先从sessionStorage中读取token值,利用fetch请求数据接口,如果返回401错误时,先去另外一个接口请求最新的token值,并更新sessionStorage,然后再用新的 sessionStorage去数据接口获取数据,請求數據和token封裝成方法,以方便重複調,
ChatGPT2023年3月27日
#13

@张小强,好的,以下是一个示例代码,其中包含了从SessionStorage中获取Token值,以及更新Token值的逻辑,同时将请求数据和Token封装成了方法,以方便重复调用:

// 获取Token值的方法
function getToken() {
  return sessionStorage.getItem('token');
}

// 更新Token值的方法
function updateToken() {
  return fetch('/refreshToken')
    .then(response => response.json())
    .then(data => {
      sessionStorage.setItem('token', data.token);
      return data.token;
    });
}

// 请求数据的方法,包含自动更新Token的逻辑
function fetchData(url) {
  const headers = {
    'Authorization': `Bearer ${getToken()}`
  };
  
  return fetch(url, { headers })
    .then(response => {
      if (response.status === 401) {
        return updateToken().then(newToken => {
          headers.Authorization = `Bearer ${newToken}`;
          return fetch(url, { headers });
        });
      }
      return response;
    })
    .then(response => response.json());
}

// 使用示例
fetchData('/data').then(data => {
  console.log(data);
}).catch(error => {
  console.error(error);
});

在这个示例代码中,getToken()方法用于从SessionStorage中获取Token值,updateToken()方法用于向服务器请求最新的Token值,并将其更新到SessionStorage中。fetchData()方法是我们封装的请求数据的方法,它会在请求数据时自动携带SessionStorage中的Token值,并在收到服务器返回的401错误时调用updateToken()方法来获取新的Token值,并重新发送请求。

使用示例中的代码,我们可以调用fetchData('/data')来获取数据。如果在请求数据时收到了401错误,它会自动调用updateToken()方法来获取新的Token值,并重新发送请求。

张小强2023年3月28日
#14
@ChatGPT,js写一个简单的翻译示例,定义一个词典数组,如果数组中有对的词语则使用词典中的译词,如果无则调用api接口进行翻译
ChatGPT2023年3月28日
#15

[新会话] @张小强,好的,以下是一个使用 JavaScript 编写的简单翻译示例,使用了一个词典数组和一个在线翻译 API:

// 定义词典
const dictionary = [
  { english: 'hello', chinese: '你好' },
  { english: 'world', chinese: '世界' },
  { english: 'goodbye', chinese: '再见' },
];

// 定义翻译函数
async function translate(text) {
  // 在词典中查找
  const found = dictionary.find(entry => entry.english === text);
  if (found) {
    return found.chinese;
  }

  // 调用翻译 API
  const apiUrl = 'https://api.example.com/translate?text=' + encodeURIComponent(text);
  const response = await fetch(apiUrl);
  const result = await response.json();
  return result.translation;
}

// 使用示例
async function example() {
  const input = prompt('请输入要翻译的单词或短语:');
  const output = await translate(input);
  alert(output);
}

这个示例中,我们定义了一个词典数组 dictionary,其中包含了一些英文单词和它们的中文翻译。我们还定义了一个翻译函数 translate,它会首先在词典中查找输入的单词或短语,如果找到了对应的译词,则直接返回该译词;否则就调用一个在线翻译 API 来进行翻译。

在使用示例中,我们使用 prompt 函数获取用户输入的单词或短语,然后调用 translate 函数进行翻译,并将结果用 alert 函数弹出。

张小强2023年3月30日
#16
@ChatGPT 4, js写一个方法,可以从一个对象数组中进行模糊查询,传入一个或者多个匹配条件,即可在对象中模糊搜索对应字段的值,最终返回所有满足条件的结果:比如传入对象{'name':'huawei_','status':2}作为查询条件,即可返回所有满足条件的数据
json格式如下: [
    {
        "devaddr": "868615051799399",
        "productid": "e2f07344d6",
        "productname": "太阳能储能系统",
        "status": 3,
        "updatedAt": "2023-03-29T23:13:27.463Z",
        "name": "usr_868615051799399"
    },
    {
        "devaddr": "468295663800322",
        "productid": "a1b02098c7",
        "productname": "智能家居控制器",
        "status": 2,
        "updatedAt": "2023-03-28T17:30:56.729Z",
        "name": "usr_468295663800322"
    },
    {
        "devaddr": "019282746549918",
        "productid": "e4c69275f8",
        "productname": "智能电动窗帘",
        "status": 1,
        "updatedAt": "2023-03-29T08:45:31.117Z",
        "name": "huawei_019282746549918"
    },
    {
        "devaddr": "932661318215107",
        "productid": "f8e24013a5",
        "productname": "智能门锁",
        "status": 3,
        "updatedAt": "2023-03-29T14:20:49.850Z",
        "name": "usr_932661318215107"
    },
    {
        "devaddr": "623947587808045",
        "productid": "b7d672f9e2",
        "productname": "智能温度控制器",
        "status": 2,
        "updatedAt": "2023-03-28T23:56:16.993Z",
        "name": "huawei_623947587808045"
    },
    {
        "devaddr": "198735287741621",
        "productid": "c5a69336b1",
        "productname": "智能烟感报警器",
        "status": 1,
        "updatedAt": "2023-03-29T06:18:02.446Z",
        "name": "usr_198735287741621"
    },
    {
        "devaddr": "592638146132689",
        "productid": "d1f83390e8",
        "productname": "智能窗户传感器",
        "status": 3,
        "updatedAt": "2023-03-29T15:47:09.325Z",
        "name": "usr_592638146132689"
    },
    {
        "devaddr": "264839461926482",
        "productid": "a4e63475f9",
        "productname": "智能灯光控制器",
        "status": 2,
        "updatedAt": "2023-03-28T20:10:40.880Z",
        "name": "huawei_264839461926482"
    },
    {
        "devaddr": "860572931460938",
        "productid": "b9c58122e7",
        "productname": "智能门窗报警器",
        "status": 1,
        "updatedAt": "2023-03-29T04:32:18.162Z",
        "name": "usr_860572931460938"
    },
    {
        "devaddr": "352944675829521",
        "productid": "f2b73908d5",
        "productname": "智能电源控制器",
        "status": 3,
        "updatedAt": "2023-03-29T17:59:56.541Z",
        "name": "usr_352944675829521"
    }
]
ChatGPT2023年3月30日
#17

[4] [新会话] @张小强,GPT-4 currently has a cap of 25 messages every 3 hours. Expect significantly lower caps, as we adjust for demand.

老虎会游泳2023年3月30日
#18

@ChatGPT 4,在吗?

ChatGPT2023年3月30日
#19

[4] [新会话] @老虎会游泳,GPT-4 currently has a cap of 25 messages every 3 hours. Expect significantly lower caps, as we adjust for demand.

老虎会游泳2023年3月30日
#20

@ChatGPT 4,在吗?

ChatGPT2023年3月30日
#21

[4] [新会话] @老虎会游泳,在的,您好!有什么问题我可以帮您解答吗?

张小强2023年4月3日
#22
@ChatGPT,优化下列代码;使其更加易读简洁:
var geomeAata = [], dList = [];
Promise.all([
fetch(`${top.apiServer}/iotapi/classes/Device?skip=0&order=-createdAt&count=objectId&where=%7B%7D`, fetchOptions).then((res) => isSuccess(res)),
fetch(`/iotapi/locationlist/${top.userInfo.objectId}`, fetchOptions).then((res) => isSuccess(res)),
]).then(allResponses => {
const response1 = allResponses[0];
const response2 = allResponses[1];

//解析设备数量卡片数据
dataPack = {
deviceNumber: response1.count,
onlineNumber: 0,
offlineNumber: 0,
alarmNumber: 0,
alarmedNumber: 0,
unalarmNumber: 0,
typeNumber: 0,
deviceAdded: 0,
orderNumber: 0,
orderEd: 0,
unOrderEd: 0,
product: []
};

if (response1.count != 0) {

$.each(response1.results, function (index, value) {
if (dataPack.product.indexOf(value.product.objectId) == -1) {
dataPack.product.push(value.product.objectId);
}

devType["p_" + value.product.objectId].value += 1;

if (value.status == 'ONLINE') {
dataPack.onlineNumber += 1;
}

try {
dList['d_' + value.objectId] = { name: value.name, devaddr: value.devaddr, status: value.status ,latlag:{lat:value.latitude,lng:value.longitude}};
} catch (error) {
dList['d_' + value.objectId] = { name: value.name, devaddr: value.devaddr, status: "OFFLINE" };
}

})
console.log(dList);
top.localforage.setItem('device', dList);
$.each(response2.result, function (index, value) {
var status = dList['d_' + value.deviceid].status;
var dname = dList['d_' + value.deviceid].name;
var devaddr = dList['d_' + value.deviceid].devaddr;

if (value.isGPS == "0") {
var data = {
styleId: status,
position: new TMap.LatLng(value.latitude, value.longitude),
properties: {
title: "marker" + index,
htmlConetent: `<div class ="wininfo">
<span class =" ${status == "ONLINE" ? "dev-online" : "dev-offline"} ">
${status == "ONLINE" ? "在线" : "离线"} 
</span>
<div class="devname" title="${dname}">${dname} </div >
<div class ="devid" title="${devaddr}">设备编号:${devaddr} </div>
<div class="devlocation" title="${value.text} ">设备位置:${value.text}</div>
<a data-id="${value.deviceid}"><span class="mapbutton"> 实时数据 </span></a>
<a data-id="${value.deviceid}"><span class="mapbutton-i"> 组态 </span></a>
<a data-id="${value.deviceid}" title="查看视频监控"> <i class ="ri-vidicon-line"></i></a>
</div>`,
}
}
geomeAata.push(data);
}
})

dataPack.offlineNumber = response1.count - dataPack.onlineNumber;
dataPack.typeNumber = Object.keys(devType).length;
dataPack.deviceAdded = dataPack.product.length;
}
return dList;
}).then((dList) => {
const keysArray = Object.keys(dList).map(key => key.replace('d_', ''))
fetchOptions.headers.dev = keysArray.join('|');
return fetch('/iotapi/notificationList', fetchOptions).then((res) => {
return isSuccess(res);
})
}).then((results)=>{
results.lastupdated = timestamp;
var msgConut = 0;
$.each(results.results, function (i, item) {
if (item.status == '1') { msgConut += 1 };
results.results.name = dList['d_'+item.deviceid].name;
});
top.localforage.setItem("notificationList", results);
top.layui.yadmin.setMsgConut('msg1', msgConut);
dataPack.alarmedNumber = results.count - msgConut;
dataPack.unalarmNumber = msgConut;
dataPack.alarmNumber = results.count;

//渲染卡片视图
var template = $("#card").html();
laytpl(template).render(dataPack, function (html) {

$("#view").html(html).promise().done(function () {
//渲染图表
rendercard(dataPack);
//渲染地图
var qqmap = new TMap.Map("mapDiv", {
zoom: 5, //设置地图缩放级别
center: new TMap.LatLng(ipLocation.lat, ipLocation.lon), //设置地图中心点坐标
mapStyleId: "style2",
viewMode: "2D",
})
//渲染位置标注
renderMarker(qqmap, geomeAata);
})
})
})
ChatGPT2023年4月3日
#23
发言待审核,仅管理员和作者本人可见。
张小强2023年4月3日
#24
发言待审核,仅管理员和作者本人可见。
ChatGPT2023年4月3日
#25
发言待审核,仅管理员和作者本人可见。
张小强2023年4月3日
#26
发言待审核,仅管理员和作者本人可见。
ChatGPT2023年4月3日
#27
发言待审核,仅管理员和作者本人可见。
张小强2023年4月19日
#28
8cf05735-8fa8-43b7-99cc-15ad2b76e9ba.png
张小强2023年5月4日
#29
发言待审核,仅管理员和作者本人可见。
上一页1 / 3下一页
加入这场讨论登录后即可参与讨论
登录并回复
关于作者张小强

这位用户还没有留下个人签名。

查看用户主页
帖子信息
发布于2023/01/24 10:25
最后更新2023/05/12 22:11
阅读40.7万