前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript | 笔记

JavaScript | 笔记

作者头像
yiyun
发布2022-04-01 13:09:14
1.5K0
发布2022-04-01 13:09:14
举报
文章被收录于专栏:yiyun 的专栏

引言

Q&A

补充

动态加载 js, css

代码语言:javascript
复制
var utils = {};

utils.dynamicLoad = {
  css: (href, onloadCallbackStr) => {
    let loadStr = `
      (function () {
          var hm = document.createElement("link");
          hm.href = "${href}";
          // 注意: 需要设置以下两项, 浏览器才会加载
          hm.setAttribute("rel", "stylesheet");
          hm.setAttribute("type", "text/css");
          hm.onload = () => {
            ${onloadCallbackStr};

            // 加载完就删除
            // hm.remove();
          };
          var heads = document.getElementsByTagName("head"); 
          if(heads.length) 
            heads[0].appendChild(hm); 
          else 
            document.documentElement.appendChild(hm);
      })();`;

    return loadStr;
  },

  js: (src, onloadCallbackStr) => {
    let loadStr = `
      (function () {
          var hm = document.createElement("script");
          hm.src = "${src}";
          hm.onload = () => {
            ${onloadCallbackStr};

            // 加载完就删除
            // hm.remove();
          };
          var heads = document.getElementsByTagName("head"); 
          if(heads.length) 
            heads[0].appendChild(hm); 
          else 
            document.documentElement.appendChild(hm);
      })();`;

    return loadStr;
  }
};

export default utils;

JavaScript 查找 注释节点: <!-- 注释节点值 -->

参考:

代码语言:javascript
复制
// 从 body 开始向内查找
var bodyElement = document.getElementsByTagName("body")[0];

for (var i=0; i<bodyElement.childNodes.length; i++) {
    // 注释节点 类型 为 8
    if (bodyElement.childNodes[i].nodeType == 8) {
        console.log(bodyElement.childNodes[i].nodeValue);
    }
}

但是这个只能找到body的子节点是注释的情况, 当然,就这样一直循环下去也可以找到body子节点的子节点是注释的情况,但是如果在很深的DOM节点里,用这种循环的方式就很不好书写。 所以我想到用递归来写

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<div>
		<div>
			<div>
				<!-- note1 -->
			</div>
		</div>
		<div>
			<div></div>
		</div>
	</div>
	<div>
		<div>
			<p>
				<!-- note2 -->
			<p>
		</div>
		<div>
			<div></div>
		</div>
	</div>
	<!-- note3 -->
	<div>
		<div>
			<div></div>
		</div>
		<!-- note4 -->
		<div>
			<div></div>
		</div>
	</div>
<script type="text/javascript">
    function eachComment(ele) {
        for (var i=0; i<ele.childNodes.length; i++) {
            var child = ele.childNodes[i];
            if (child.nodeType == 8) {
                console.log(child.nodeValue);
            } else if (child.childNodes) {
                eachComment(child);
            }
        }
    }
    var bodyElement = document.getElementsByTagName("body")[0];
    eachComment(bodyElement);
</script>
</body>
</html>

注意: <!-- PluginCore.IPlugins.IPluginWidget -->console.log(child.nodeValue); 得到的值 是 PluginCore.IPlugins.IPluginWidget 两边有空格, 也 nodeValue 就是内部内容, 不会去除两边空格的

JavaScript Element.replaceWith(...nodes)

参考:

补充

经过测试, 注释节点也可以用

代码语言:javascript
复制
const span = document.createElement("span");
注释节点.replaceWith(span)
// 注意: 注释节点不变, 注释节点 依然指向原来的 , 而不是 replaceWith 后的
// 注意: 经测试: 不同节点.replaceWith(node1) 时, node1 对象不要重复使用, 否则可能导致想象外效果

temp1.replaceWith("<h1>aaa</h1>")
// 这样会替换为 nodeValue: '<h1>aaa</h1>' 的文本节点

image-20220208231739161

正确做法

代码语言:javascript
复制
c = parseDom("<h1>ccc</h1>")
// 注意: 不要省略 "..."
temp4.replaceWith(...c)

image-20220208232013871

语法

我可以使用replaceWith将任意一个子跨度与多个元素和文本节点交换吗

Element.replaceWith()的签名接受数量可变的NodeDOMString参数。。。

Syntax

代码语言:javascript
复制
replaceWith(...nodes)

案例

Using replaceWith()
代码语言:javascript
复制
var parent = document.createElement("div");
var child = document.createElement("p");
parent.appendChild(child);
var span = document.createElement("span");

child.replaceWith(span);

console.log(parent.outerHTML);
// "<div><span></span></div>"

Browser compatibility

image-20220208224120394

Node.nodeType

参考:

只读属性 Node.nodeType 表示的是该节点的类型。

nodeType 属性可用来区分不同类型的节点,比如 元素, 文本注释

代码语言:javascript
复制
var type = node.nodeType;

返回一个整数,其代表的是节点类型。其所有可能的值请参考 节点类型常量.

节点类型常量

常量

描述

Node.ELEMENT_NODE

1

一个 元素 节点,例如 ](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/p) 和 [。

Node.TEXT_NODE

3

Element 或者 Attr 中实际的 文字

Node.CDATA_SECTION_NODE

4

一个 CDATASection,例如 <!CDATA[[ … ]]>。

Node.PROCESSING_INSTRUCTION_NODE

7

一个用于XML文档的 ProcessingInstruction (en-US) ,例如 <?xml-stylesheet ... ?> 声明。

Node.COMMENT_NODE

8

一个 Comment 节点。

Node.DOCUMENT_NODE

9

一个 Document 节点。

Node.DOCUMENT_TYPE_NODE

10

描述文档类型的 DocumentType 节点。例如 <!DOCTYPE html> 就是用于 HTML5 的。

Node.DOCUMENT_FRAGMENT_NODE

11

一个 DocumentFragment 节点

例子

不同的节点类型

代码语言:javascript
复制
document.nodeType === Node.DOCUMENT_NODE; // true
document.doctype.nodeType === Node.DOCUMENT_TYPE_NODE; // true

var fragment = document.createDocumentFragment();
fragment.nodeType === Node.DOCUMENT_FRAGMENT_NODE; // true

var p = document.createElement("p");
p.textContent = "很久很久以前...";

p.nodeType === Node.ELEMENT_NODE; // true
p.firstChild.nodeType === Node.TEXT_NODE; // true

注释

代码语言:javascript
复制
// 该示例会检查 document 下第一个节点是不是注释,如果不是,则会提醒。
var node = document.documentElement.firstChild;
if (node.nodeType != Node.COMMENT_NODE)
  console.log("你应该认真编写代码注释!");

Element.remove()

删除 Element 节点

字符串转 DOM 对象

参考:

代码语言:javascript
复制
function parseDom(arg) {
   var objE = document.createElement("div");
   objE.innerHTML = arg;
   return objE.childNodes;
};

axios

参考:

Promise based HTTP client for the browser and node.js

Using npm:

代码语言:javascript
复制
npm install axios

Using unpkg CDN:

代码语言:javascript
复制
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
代码语言:javascript
复制
const axios = require('axios');

Axios API

代码语言:javascript
复制
// Send a POST request
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
代码语言:javascript
复制
// GET request for remote image in node.js
axios({
  method: 'get',
  url: 'http://bit.ly/2mTM3nY',
  responseType: 'stream'
})
  .then(function (response) {
    response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
  });

The Axios Instance

代码语言:javascript
复制
const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

Request Config

代码语言:javascript
复制
// `responseType` indicates the type of data that the server will respond with
// options are: 'arraybuffer', 'document', 'json', 'text', 'stream'
//   browser only: 'blob'
responseType: 'json', // default

Config Defaults

Global axios defaults

代码语言:javascript
复制
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

Custom instance defaults

代码语言:javascript
复制
// Set config defaults when creating the instance
const instance = axios.create({
  baseURL: 'https://api.example.com'
});

// Alter defaults after instance has been created
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

// 注意: timeout 的单位 是 ms, 因此这里是 2.5 seconds
instance.defaults.timeout = 2500;

axios 例子: request.js

utils/request.js

代码语言:javascript
复制
import axios from "axios";
import qs from "qs";

// build 环境
// axios.defaults.baseURL = 'http://api.tikotiko.fun';
// axios.defaults.baseURL = 'http://localhost:4530/';
axios.defaults.baseURL = process.env.VUE_APP_API;

// axios 请求拦截 - 在发送请求之前做某件事
axios.interceptors.request.use(
  function(request) {
    // 解决跨域 post 变 OPTIONS,导致 404
    if (request.method === "post") {
      request.headers["Content-Type"] =
        "application/x-www-form-urlencoded;charset=UTF-8";
      request.data = qs.stringify({
        ...request.data
      });
    }

    // 如果有登录状态token的话,则添加到请求头
    if (localStorage.token) {
      // 在 headers 中设置 Authorization 属性放token,token是存在缓存中的
      request.headers.Authorization = `Bearer ${localStorage.token}`;
    }

    return request;
  },
  function(error) {
    return Promise.reject(error);
  }
);

/**
 * 发送http请求
 * @param {String} url 目标rl
 * @param {String} method 方法get,post,put etc.
 * @param {Object} params 对象参数
 * @returns {Promise<unknown>}
 */
const request = function(url, method, params) {
  return new Promise((resolve, reject) => {
    if (method == "get") {
      axios({
        url: url,
        method: "get",
        params: params
      })
        .then(res => {
          res.data.status = res.status;
          resolve(res.data);
        })
        .catch(err => {
          err.data.status = err.status;
          reject(err.data);
        });
    } else {
      axios({
        url: url,
        method: method,
        data: params
      })
        .then(res => {
          res.data.status = res.status;
          resolve(res.data);
        })
        .catch(err => {
          err.data.status = err.status;
          reject(err.data);
        });
    }
  });
};

export default request;

使用 request.js api/plugins.js

代码语言:javascript
复制
import request from "@/utils/request.js";

export page => request("/article/last", "get", { page: page });

export pluginId => request("/plugincore/admin/plugins/install", "post", { pluginId: pluginId });

axios 例子: 请求 html 字符串

参考:

responseType

XMLHttpRequest

XMLHttpRequest 本身就是支持responseType

  • ""
    • responseType 为空字符串时,采用默认类型 DOMString,与设置为 text 相同。
  • arraybuffer
    • response 是一个包含二进制数据的 JavaScript ArrayBuffer。
  • blob
    • response 是一个包含二进制数据的 Blob 对象 。
  • document
    • response 是一个 HTML Document 或 XML XMLDocument,这取决于接收到的数据的 MIME 类型。请参阅 XMLHttpRequest 中的 HTML 以了解使用 XHR 获取 HTML 内容的更多信息。
  • json
    • response 是一个 JavaScript 对象。这个对象是通过将接收到的数据类型视为 JSON 解析得到的。
  • text
    • response 是一个以 DOMString 对象表示的文本。
  • ms-stream
    • response 是下载流的一部分;此响应类型仅允许下载请求,并且仅受 Internet Explorer 支持。

补充: 默认 xhr 请求 会 自动 带上 Cookie

动态创建 script

  1. F12 直接修改html页面加script标签,这样方式浏览器只会解析,不会执行js, network中也没有加载 script.src
  2. F12 Console 通过执行 js createElement 动态创建 script 标签形式,这种方式就能加载js并执行

补充: 动态插入JS可以不阻碍 DOMContentLoad

image-20220209140325367

前端存储 cookie、sessionStorage、localStorage、websql、indexeddb

参考:

cookie

Cookie是不可以跨域名的,隐私安全机制禁止网站非法获取其他网站的Cookie。

正常情况下,同一个一级域名下的两个二级域名也不能交互使用Cookie,比如test1.mcrwayfun.com和test2.mcrwayfun.com,因为二者的域名不完全相同。如果想要mcrwayfun.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数为.mcrwayfun.com,这样使用test1.mcrwayfun.com和test2.mcrwayfun.com就能访问同一个cookie。

一级域名又称为顶级域名,一般由字符串+后缀组成。熟悉的一级域名有baidu.com,qq.com。com,cn,net等均是常见的后缀。 二级域名是在一级域名下衍生的,比如有个一级域名为mcrfun.com,则blog.mcrfun.com和www.mcrfun.com均是其衍生出来的二级域名。

path属性决定允许访问Cookie的路径。比如,设置为"/"表示允许所有路径都可以使用Cookie。

sessionStorage

访问限制性
  • 不同于cookie,sessionStorage的访问限制更高一些,只有当前设定sessionStorage的域下才能访问,而且不同的两个tab之间不能互通。例,我在www.qq.com下种下了sessionStorage,在wx.qq.com下是,无法访问的;
  • 在新开的tab下,或者关闭本TAB再打开后(也是www.qq.com),也是无法访问到之前种的sessionStorage的;
  • 而本tab刷新的时候,sessionStorage确是可以访问的。

以上种种,证明sessionStorage里面的session,并不同于cookie,是以tab为级别的session。

localStorage

访问的限制性

localStorage与sessionStorage虽然相似,但是访问限制却不尽相同,localStorage的访问域默认设定为设置localStorage的当前域,其他域名不可以取。 这点与sessionStorage相同,但是与sessionStorage不同的是,localStorage设定后,新开tab是可以访问到的

存储时间

localStorage理论上讲是 永久性质的存储。但是,免不了用户会使用浏览器清除数据,或者浏览器有时候为了节省,去清除数据。

websql 与 indexeddb

参考

感谢帮助!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • Q&A
  • 补充
    • 动态加载 js, css
      • JavaScript 查找 注释节点: <!-- 注释节点值 -->
        • JavaScript Element.replaceWith(...nodes)
          • 补充
          • 语法
        • Syntax
          • 案例
          • Browser compatibility
        • Node.nodeType
          • 节点类型常量
          • 例子
        • Element.remove()
          • 字符串转 DOM 对象
            • axios
              • Axios API
              • The Axios Instance
              • Request Config
              • Config Defaults
              • axios 例子: request.js
              • axios 例子: 请求 html 字符串
              • responseType
            • XMLHttpRequest
              • 动态创建 script
                • 前端存储 cookie、sessionStorage、localStorage、websql、indexeddb
                  • cookie
                  • sessionStorage
                  • localStorage
                  • websql 与 indexeddb
              • 参考
              相关产品与服务
              内容分发网络 CDN
              内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档