我试图弄明白为什么有些书签在iOS上什么也不做--甚至不会触发错误--因为它无法访问MacOS设备。
作为参考,请考虑以下两个书签(以下格式化源代码):
// DebugSimple.js
javascript:/* DebugSimple.js - 10:02:50 2019-12-23 */(function(){ document.body.innerHTML='';document.body.style.all='initial';function putString(string){document.body.innerText+=string;}const oldConsoleLog=console.log;console.log=function(...args){putString('(log) '+args.map(e=>e.toString()).join(' '));return oldConsoleLog(...args);};window.addEventListener('error',event=>{var msg='\n(err) ';msg+=!event ?'!!event = '+event :!event.error ?'!!event.error = '+event.error :!event.error.stack ?'!!event.error.stack = '+event.error.stack : event.error.stack;if(event&&event.error)for(const key in event.error){msg+='\nevent.error.'+key+'='+event.error[key];}putString(msg);});console.log("Log test.");setTimeout(backtraceTest,10);function backtraceTest(){backtraceTest2();}function backtraceTest2(){noSuchFunctionShouldExist();}})();undefined;
// DebugOverlay.js
javascript:/* DebugOverlay.js - 10:07:25 2019-12-23 */(function(){ const highestZIndex=Math.max(...Array.from(document.getElementsByTagName('*')).map(e=>window.getComputedStyle(e).zIndex).map(parseInt).filter(e=>!isNaN(e)));console.log(highestZIndex);function append(parent,html,callback=undefined){var e=document.createElement('DIV');parent.appendChild(e);e.outerHTML=html;e=parent.lastElementChild;if(callback)callback(e);return e;}const ifr=document.createElement('IFRAME');document.body.prepend(ifr);ifr.id='debugOverlay.js';ifr.style.all='initial';ifr.style.zIndex=highestZIndex+1;ifr.style.position='fixed';ifr.style.left='5%';ifr.style.right='5%';ifr.style.width='90%';ifr.style.height='90%';ifr.style.opacity='90%';ifr.style.backgroundColor='#ddd';ifr.style.border='1pt solid #888';ifr.contentDocument;ifr.contentDocument.open();ifr.contentDocument.close();const header=append(ifr.contentDocument.body,"<DIV id='header'/>",e=>{e.style.position='static';});const closeButton=append(header,"<A href='#' id='closeButton'>[CLOSE]</A>",e=>{e.addEventListener('click',()=>ifr.parentElement.removeChild(ifr));});const clearButton=append(header,"<A href='#' id='clearButton'>[CLEAR]</A>",e=>{e.addEventListener('click',()=>{output.innerHTML='';});});const output=append(ifr.contentDocument.body,"<DIV id='outputPane'/>",e=>{e.style.fontFamily='Sans';});append(ifr.contentDocument.body,"<DIV id='overScroll' style='height:30vh'/>");var fontSizeScale=0.8;function setOutputFontSize(scale){output.style.fontSize=(fontSizeScale*100)+'%';}setOutputFontSize(fontSizeScale);const fontSizePlus=append(header,"<A href='#' id='fontSizePlus'>[LGR]</A>",e=>{e.addEventListener('click',()=>{setOutputFontSize(fontSizeScale*=1.2);});});const fontSizeMinus=append(header,"<A href='#' id='fontSizePlus'>[SML]</A>",e=>{e.addEventListener('click',()=>{setOutputFontSize(fontSizeScale/=1.2);});});const toggleLog=append(header,"<A href='#' id='toggleLog'>[log(on)]</a>",e=>{var logVisibility=true;e.addEventListener('click',()=>{setLogVisibility(logVisibility=!logVisibility);});function setLogVisibility(bool){Array.from(output.getElementsByClassName('log')).forEach(ee=>{ee.style.display=bool ?'block':'none';e.innerText=bool ?'[log(on)]':'[log(off)]';});}setLogVisibility(logVisibility);});window.addEventListener('error',(evt)=>(addEntry(evt.error.stack)));function addEntry(string,category='error'){append(output,"<DIV class='entry "+category+"'/>",e=>{e.style.marginTop='0.5em';e.style.borderTop='1px solid #888';e.style.fontWeight=category=='error'?'bold':'';append(e,'<CODE/>',e=>{e.innerText=string;});});};const oldConsoleLog=console.log;console.log=function(...args){oldConsoleLog(...args);addEntry(args.join(' '),'log');};function testingIfErrorLogWorks_a(){testingIfErrorLogWorks_b();}function testingIfErrorLogWorks_b(){noSuchFunction();}setTimeout(testingIfErrorLogWorks_a,10);setTimeout(()=>console.log('LogTest'),20);setTimeout(testingIfErrorLogWorks_b,30);})();undefined;
我在GoogleChrome(Windows 10)上添加了这些书签,并与iOS和Android同步。
在Android和Windows上,这两个脚本都可以正常工作:
DebugSimple.js使用回溯跟踪将页面主体替换为错误日志,以及console.log召唤。 DebugOverlay.js广告一个iframe覆盖,在那里错误记录更干净。 在IOS上,更简单的脚本DebugSimple.js将按预期执行和记录错误,因此我知道在IOS上捕获错误,尽管其输出效果不如Android和Windows 10。javascript:};进入URL栏(语法错误)。
但是,如果我调用DebugOverlay.js脚本,即使我手动复制-粘贴它从书签,什么都没有发生;DebugSimple.js也不会报告任何错误。
我怀疑,这可能与书签的长度有关,因为这种行为似乎主要发生在大型书签中;但是无论如何,似乎根本没有任何东西可以说明原因。
此时,我不知道如何进行;请记住,我没有任何Mac设备。
格式化源DebugSimple.js
document.body.innerHTML = '';
document.body.style.all = 'initial';
function putString(string) {
document.body.innerText += string;
}
const oldConsoleLog = console.log;
console.log = function(...args) {
putString('(log) ' + args.map(e => e.toString()).join(' '));
return oldConsoleLog(...args);
};
window.addEventListener('error', event => {
var msg = '\n(err) ';
msg +=
!event ? '!!event = ' + event :
!event.error ? '!!event.error = ' + event.error :
!event.error.stack ? '!!event.error.stack = ' + event.error.stack :
event.error.stack;
if(event && event.error) for(const key in event.error) {
msg += '\nevent.error.' + key + '=' + event.error[key];
}
putString(msg);
});
// Test error.
console.log("Log test.");
setTimeout(backtraceTest,10);
function backtraceTest(){ backtraceTest2(); }
function backtraceTest2(){ noSuchFunctionShouldExist(); }
格式化源DebugOverlay.js
// DOES NOT WORK IN CHROME WHEN PASTED TO THE CONSOLE.
// The console messes somehow with error events.
// Should work when executed as bookmarklet or 'javascript:' URI.
const highestZIndex = Math.max(
...Array.from(document.getElementsByTagName('*'))
.map(e=>window.getComputedStyle(e).zIndex)
.map(parseInt)
.filter(e => !isNaN(e)));
console.log(highestZIndex);
function append(parent, html, callback = undefined) {
var e = document.createElement('DIV');
parent.appendChild(e);
e.outerHTML = html;
e = parent.lastElementChild;
if(callback) callback(e);
return e;
}
const ifr = document.createElement('IFRAME');
document.body.prepend(ifr);
ifr.id = 'debugOverlay.js';
ifr.style.all = 'initial';
ifr.style.zIndex = highestZIndex + 1;
ifr.style.position = 'fixed';
ifr.style.left = '5%';
ifr.style.right = '5%';
ifr.style.width = '90%';
ifr.style.height = '90%';
ifr.style.opacity = '90%';
ifr.style.backgroundColor = '#ddd';
ifr.style.border = '1pt solid #888';
// Firefox requires content to be initialized.
ifr.contentDocument;
ifr.contentDocument.open();
ifr.contentDocument.close();
const header = append(ifr.contentDocument.body, "<DIV id='header'/>", e => {
e.style.position = 'static';
});
const closeButton = append(header, "<A href='#' id='closeButton'>[CLOSE]</A>", e => {
e.addEventListener('click', () => ifr.parentElement.removeChild(ifr));
});
const clearButton = append(header, "<A href='#' id='clearButton'>[CLEAR]</A>", e => {
e.addEventListener('click', () => {
output.innerHTML = '';
});
});
const output = append(ifr.contentDocument.body, "<DIV id='outputPane'/>", e => {
e.style.fontFamily = 'Sans';
});
append(ifr.contentDocument.body, "<DIV id='overScroll' style='height:30vh'/>");
var fontSizeScale = 0.8;
function setOutputFontSize(scale) {
output.style.fontSize = (fontSizeScale * 100) + '%';
}
setOutputFontSize(fontSizeScale);
const fontSizePlus = append(header, "<A href='#' id='fontSizePlus'>[LGR]</A>", e => {
e.addEventListener('click', () => {
setOutputFontSize(fontSizeScale *= 1.2);
});
});
const fontSizeMinus = append(header, "<A href='#' id='fontSizePlus'>[SML]</A>", e => {
e.addEventListener('click', () => {
setOutputFontSize(fontSizeScale /= 1.2);
});
});
const toggleLog = append(header, "<A href='#' id='toggleLog'>[log(on)]</a>", e => {
var logVisibility = true;
e.addEventListener('click', () => {
setLogVisibility(logVisibility = !logVisibility);
});
function setLogVisibility(bool) {
Array.from(output.getElementsByClassName('log')).forEach(ee => {
ee.style.display = bool ? 'block' : 'none';
e.innerText = bool ? '[log(on)]' : '[log(off)]';
});
}
setLogVisibility(logVisibility);
});
window.addEventListener('error', (evt) => (addEntry(evt.error.stack)));
function addEntry(string, category='error') {
append(output, "<DIV class='entry "+category+"'/>", e => {
e.style.marginTop = '0.5em';
e.style.borderTop = '1px solid #888';
e.style.fontWeight = category == 'error' ? 'bold' : '';
append(e, '<CODE/>', e => { e.innerText = string; });
});
};
const oldConsoleLog = console.log;
console.log = function (...args) {
oldConsoleLog(...args);
addEntry(args.join(' '), 'log');
};
// For testing.
function testingIfErrorLogWorks_a() { testingIfErrorLogWorks_b(); }
function testingIfErrorLogWorks_b() { noSuchFunction(); }
setTimeout(testingIfErrorLogWorks_a,10);
setTimeout(()=>console.log('LogTest'), 20);
setTimeout(testingIfErrorLogWorks_b,30);
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。