jq怎么判断某个js文件是否引入?
封装了如下函数:
/**
* 检测js文件是否导入
*/
function checkJsFileIsImported(jsFileSrc) {
return $(`script[src='${jsFileSrc}']`).length > 0;
}
其实还有种方式是,判断你引入js文件中某个变量或者函数是否存在,如果存在则表明是引入了
封装了如下函数:
/**
* 检测js文件是否导入
*/
function checkJsFileIsImported(jsFileSrc) {
return $(`script[src='${jsFileSrc}']`).length > 0;
}
其实还有种方式是,判断你引入js文件中某个变量或者函数是否存在,如果存在则表明是引入了
封装了函数如下: (其实引入js文件,jq提供了个更优雅的方式$.getScript(),不过考虑到这个页面可能被其他页面多次调用,那就会重复引入,而直接append script标签不会,所以是比较好的方式)
function importJsFileIfMissing(jsUrl) {
if (!checkJsFileIsImported(jsUrl)) {
let script = document.createElement("script");
script.setAttribute("src", jsUrl);
$('head').append(script);
}
}
/**
* 检测js文件是否导入
*/
function checkJsFileIsImported(jsFileSrc) {
return $(`script[src='${jsFileSrc}']`).length > 0;
}
看到一篇不错的国外整理文章,特此记录下. 使用原生js监控变量的变化主要有6种,具体如下.
1.使用setInterval轮询检测
<script>
/**
* 轮询检测变量变化
* @param varName '要检测的变量名称'
* @param callback '变量变化后执行的函数'
* @param checkTimes '需要检测几次.0表示一直检测,1为检测1次就停止检测,以此类推'
*/
function watch(varName, callback, checkTimes = 1) {
clearcheck = setInterval(repeatcheck, 500, varName);//500毫秒检测一次
let current = 0;
let oldvalue = window[varName]
function repeatcheck(varName) {
if (window[varName] !== oldvalue) {
current++;
callback && callback(oldvalue, window[varName], current)
if (checkTimes > 0 && current > checkTimes) {
clearInterval(clearcheck);
}
console.log(`${varName} value changed from ${oldvalue} to ${window[varName]} (${current} times)`);
oldvalue = window[varName]
}
}
}
//用法
var myVar = 'hello';//初始化要检测的变量,一定要声明为全局变量
let title = 'beautiful!';
watch('myVar', function (oldValue, newValue, changeTImes) {//changeTImes: 改变的次数
//do something you want.做你的逻辑
alert(`changeTime ${changeTImes}: ; now value is: ${newValue}`)
}, 0)
myVar = 'world';//改变值,测试下
</script>
2.监听DOM变化
//设置隐藏的dom
<div id="watchdiv" style='visibility:hidden;width:0;height:0'>0</div>
<script>
document.getElementById('watchdiv')
.addEventListener('DOMSubtreeModified', function () {
//做你的逻辑
console.log("value changed to "
+ document.getElementById('watchdiv').innerHTML)
});
</script>
3.为对象的每个属性设置setter和getter
缺点就是需要较多的设置代码; 同时对于新增或删除的属性是通知不到的.为属性设置setter和getter官方文档
看下这个简单栗子,很容易就会用了.
const o = {
a: 7,
get b() {
return this.a + 1;
},
set c(x) {
this.a = x / 2;
}
};
console.log(o.a); // 7
console.log(o.b); // 8 <-- 这时get b()会被调用
o.c = 50; // <-- 这时set c(x)会被调用
console.log(o.a); // 25
4.使用代理对象proxy object (都2202年了推荐使用这个)
proxy object方法简单说就是他能为一个目标对象创建一个代理对象,所有操作都会被代理对象拦截下来且可被重新定义操作.(我们操作代理对象而不是直接操作目标对象).举个简单栗子很快就会明白.
let targetObj = {};
let targetProxy = new Proxy(targetObj, {
set: function (target, key, value) {//设置对象属性会被调用
//做你的逻辑
console.log(`${key} set to ${value}`);
target[key] = value;
return true;
},
get: function (target, key) {//访问对象属性会调用
//做你的逻辑
console.log(`access the ${key}`)
}
});
targetProxy.a = 'test'//注意是操作代理对象,而不是直接操作目标对象
综上,第3和4方法会比较好用,其中推荐可采用第4种方法.
参考:
https://stackoverflow.com/questions/1759987/listening-for-variable-changes-in-javascript
https://lage.us/Javascript-Watch-Variables-for-Change.html
有时候我们需要访问变量名动态指定的变量.
js中有两种方法可以做到.
window[变量名]或者window.变量名
的方式即可访问到.下面举个栗子:
varName = 'a'
var a = 'hello world'; //注意用let和const声明的是局部变量,所以全局window中是不存在该变量的.var可写可不写,不写默认也是var声明方式.
function test(){
let a = 'good';
eval(varName); //eval()能先找最近范围内变量,输出 good
window[varName]; //输出 hello world
}
test()