Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.
Эта статья приняла участие"Проект "Звезда раскопок"", чтобы выиграть творческий подарочный пакет и бросить вызов творческим поощрительным деньгам.
"Мойка"
бессонница среди ночи,
Толкнуть дверь во двор,
Лотосное дерево тумана во дворе созрело,
Тихо упал красный плод,
Я вырезал кусочек лунного света, чтобы обернуть свое сердце.
Шум насекомых в июле — это три сотни стихотворений Тан, которые взорвались.
Ритм нарушен,
Одна жестяная рифма: Джи Джи Джи Джи Джи Джи.
Я сказал: Рыбак, ты не так хорош, как червь, ты не возвращался три года.
Безбрежному морю нет пути,
только равные слова,
С тем же успехом ты мог бы попросить Синюэ быть посыльным,
Если я отрежу серебристо-белую ткань,
Болезненные раны,
Я буду знать,
Вы не можете вернуться.
Автор задумался, что означает «Навыки фронтальной загрузки 108 стилей»? Это должно принести некоторые навыки развития? Чтобы интегрировать некоторые детали, которые все игнорируют? Неужели для принуждения? Он больше ориентирован на технологии или развлечения? Это проблема компромисса: если вы более техничны, вы потеряете часть интереса, если вы более интересны, вы потеряете часть глубины. На мой взгляд чисто технических статей на самом деле очень много, и я большеНадеюсь внести больше удовольствия в жизнь программистов, В остальных статьях цикла я все же буду стремиться внести в жизнь программы немного разных красок со всех сторон.
Краткое содержание серии опубликованных статей:
- Навыки внешнего принуждения 108 формул (1) - трудящиеся-мигранты
- Фронтальные навыки принуждения 108 формул (2) - не будем говорить о единоборствах
- Навыки внешнего принуждения 108 формул (3) - инженер вызовов API без эмоций
- Навыки загрузки фронтенда 108-стиль (четыре) - качаем вместе
В соответствии со стилем статьи часть справочного материала будет помечена в конце соответствующего подраздела.
Тип 55: Вы когда-нибудь видели танец пажа? —— Эта высокая движущаяся страница похожа на молодость, которую я потерял в те годы.
Помните волшебное Little Apple и Douyin? Как интерфейс, вы когда-нибудь задумывались об этом?Сделайте страницу высокой и танцуйте?
Первый взгляд на эффект:
Следующий код можно выполнить непосредственно на консоли, и он немного длиннее. Вы можете сразу перейти к концу этого раздела и ознакомится с ним, ознакомившись с кратким введением в JS (с музыкальным эффектом)
setTimeout(letDance, 1000);
var bgmSrc =
'https://nd002723.github.io/carnival/audio/Martin%20Jensen%20-%20Fox%20(Loop%20Remix).mp3';
var cssHref = 'https://nd002723.github.io/carnival/css/high.css';
function letDance() {
function loadCss() {
//将css文件引入页面
var myCss = document.createElement('link');
myCss.setAttribute('type', 'text/css');
myCss.setAttribute('rel', 'stylesheet');
myCss.setAttribute('href', cssHref); //css文件地址
myCss.setAttribute('class', l);
document.body.appendChild(myCss);
}
function h() {
var e = document.getElementsByClassName(l);
for (var t = 0; t < e.length; t++) {
document.body.removeChild(e[t]);
}
}
function p() {
var e = document.createElement('div');
e.setAttribute('class', a);
document.body.appendChild(e);
setTimeout(function () {
document.body.removeChild(e);
}, 100);
}
function getSize(e) {
//获取目标的宽高
return {
height: e.offsetHeight,
width: e.offsetWidth,
};
}
function checkSize(i) {
//判断目标大小是否符合要求
var s = getSize(i); //获取目标的宽高
return (
s.height > minHeight &&
s.height < maxHeight &&
s.width > minWidth &&
s.width < maxWidth
); //判断目标是否符合条件
}
function m(e) {
var t = e;
var n = 0;
while (!!t) {
n += t.offsetTop;
t = t.offsetParent;
}
return n;
}
function g() {
var e = document.documentElement;
if (!!window.innerWidth) {
return window.innerHeight;
} else if (e && !isNaN(e.clientHeight)) {
return e.clientHeight;
}
return 0;
}
function y() {
if (window.pageYOffset) {
return window.pageYOffset;
}
return Math.max(
document.documentElement.scrollTop,
document.body.scrollTop
);
}
function E(e) {
var t = m(e);
return t >= w && t <= b + w;
}
function setBgm() {
//设置音乐
var e = document.createElement('audio');
e.setAttribute('class', l);
e.src = bgmSrc; //bgm地址
e.loop = false;
e.addEventListener(
'canplay',
function () {
setTimeout(function () {
x(k);
}, 500);
setTimeout(function () {
N();
p();
for (var e = 0; e < O.length; e++) {
T(O[e]);
}
}, 15500);
},
true
);
e.addEventListener(
'ended',
function () {
N();
h();
},
true
);
e.innerHTML =
' <p>If you are reading this, it is because your browser does not support the audio element. We recommend that you get a new browser.</p> <p>';
document.body.appendChild(e);
e.play();
}
function x(e) {
e.className += ' ' + s + ' ' + o;
}
function T(e) {
e.className += ' ' + s + ' ' + u[Math.floor(Math.random() * u.length)];
}
function N() {
var e = document.getElementsByClassName(s);
var t = new RegExp('\\b' + s + '\\b');
for (var n = 0; n < e.length; ) {
e[n].className = e[n].className.replace(t, '');
}
}
var minHeight = 3; //最小高度
var minWidth = 3; //最小宽度
var maxHeight = 800; //最大高度
var maxWidth = 1400; //最大宽度
var s = 'mw-harlem_shake_me';
var o = 'im_first';
var u = ['im_drunk', 'im_baked', 'im_trippin', 'im_blown'];
var a = 'mw-strobe_light';
var l = 'mw_added_css'; //最终要移除的css
var b = g();
var w = y();
var C = document.getElementsByTagName('*');
var k = null;
for (var L = 0; L < C.length; L++) {
var targetDiv = C[L];
if (checkSize(targetDiv)) {
if (E(targetDiv)) {
k = targetDiv;
break;
}
}
}
if (targetDiv === null) {
//如果没找到合适大小的
console.warn('没能找到合适的大小. 换一个页面试试?.');
return;
}
loadCss(); //将自定义css文件引入页面
setBgm(); //添加背景音乐
var O = [];
for (var L = 0; L < C.length; L++) {
var targetDiv = C[L];
if (checkSize(targetDiv)) {
O.push(targetDiv);
}
}
//网页整体倾斜效果(这块儿本来是JQuery实现的,为了避免引入JQuery,做了改动。)
var style = document.createElement('style');
style.type = 'text/css';
try {
style.appendChild(
document.createTextNode(
'body{overflow-x:hidden;transform: rotate(1deg);-webkit-transform: rotate(1deg);-moz-transform: rotate(1deg);-o-transform: rotate(1deg);-ms-transform: rotate(1deg)}'
)
);
} catch (ex) {
style.styleSheet.cssText = 'body{background-color:red}'; //针对IE
}
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
}
Или, говоря более кратко, введите следующий код в адресную строку страницы или консоль, чтобы просмотреть его напрямую:
Если вы вставите следующее в адресную строку браузера,Три момента, на которые следует обратить внимание, во-первых, это должна быть страница с существующим контентом, во-вторых, если копировать и вставлять код в адресную строку браузера IE и Chromeавтоматически удалит начало кода
javascript:
, поэтому для корректного выполнения его нужно добавлять вручную, и хотя он не будет автоматически удален в Firefox, он вообще не поддерживает запуск JS-кода в адресной строке; третий — эталонныйcarnival.js
будет зависеть отJQuery
(Хорошо, если это не так, но на странице отсутствует эффект наклона).
javascript: void (function () {
var d = document,
a = 'setAttribute',
s = d.createElement('script');
s[a]('tyle', 'text/javascript');
s[a]('src', 'https://nd002723.github.io/carnival/js/carnival.js');
d.head.appendChild(s);
})();
Пятьдесят шестая форма: в прошлом золотой ранг Baiyutang теперь видит только зеленую сосну - Может ли режим инкогнито браузера действительно быть невидимым?
Режим инкогнито и уникальная идентификация устройства
Все мы знаем, что режим браузера в режиме инкогнито может лишить других возможности узнать, какие веб-сайты вы посещали и что вы делали.В режиме инкогнито открываемые вами страницы и файлы, которые вы загружаете, не будут записываться в вашу историю просмотров и историю загрузок. , середина. Все новые файлы cookie удаляются после закрытия всех открытых окон в режиме инкогнито. Но действительно ли режим инкогнито является инкогнито? Неужели невозможно распознать, что вы посещали один и тот же сайт несколько раз в режиме инкогнито? Если это так, то это определенно инструмент для очистки UV (уникальный посетитель), попробуйте его.личный блог, что верно (я используюне чеснок), то у кого может быть больше UV, чем у меня, 😄😄😄, но подождите, тут видимо что-то не так... Антрацен, оказывается я программист 🤔, а вдруг продуктовым и дата аналитикам нужны точные данные? ? А как насчет страниц, которые не требуют лендингов (например, статьи сообщества) и требуют устранения режима инкогнито, очищающего UV-трафик? Как насчет сайтов для голосования, на которых не нужно входить в систему и нужно предотвращать повторное голосование и лайки в режиме инкогнито? Ну, это должно представитьУникальный идентификатор устройстваконцепция.
В сценарии разработки уникальная идентификация устройства является базовой функцией, которая может иметь множество сценариев применения, напримерАвторизация программного обеспечения (как убедиться, что ваше программное обеспечение можно использовать только на определенной машине после авторизации), лицензия на программное обеспечение, идентификация устройства, идентификация устройстваЖдать.
Если вы хотите получить уникальный идентификатор устройства, вы можете подумать о таких идеях, как IMEI, Android ID, MAC-адрес и т. д., ноОфициальная документация в Android 10Имеются следующие два выражения:
- Начиная с Android 10, приложения должны иметь
READ_PRIVILEGED_PHONE_STATE
Привилегированное право на доступ к несбрасываемому идентификатору устройства (включая IMEI и серийный номер). - По умолчанию на устройствах под управлением Android 10 или выше система передает случайно назначенный MAC-адрес.
Компьютер может иметь несколько сетевых карт и несколько MAC-адресов.Еще одна более фатальная слабость MAC-адресов заключается в том, что MAC-адреса легко изменить вручную.
Что касается Android ID, то он не имеет реальной уникальности, ROOT, перепрошивка, восстановление до заводских настроек, приложения с разной подписью и т.д. приведут к изменению полученного Android ID, а баги систем, настроенных разными производителями, вызовут разные устройства, один и тот же идентификатор Android.
Некоторые другие способы получения уникального идентификатора устройства, в этой статье есть более подробное обсуждение:
Получите уникальный идентификатор устройства: система Windows
Если мы вернемся к нашему внешнему сценарию, то вышеперечисленные методы имеют гораздо больше ограничений, например, некоторые требуют привилегированных разрешений, а некоторые должны полагаться на сотрудничество с нативной разработкой.Требуется только внешнее участие, а как насчет уникальной схемы идентификации, которая также может обеспечить хорошую точность? - Теперь настало время снятия отпечатков пальцев в браузере.
FingerPrint — это то, что мы часто называем распознаванием отпечатков пальцев, которое использует отпечатки пальцев, прижатые к текстуре на передней части пальца, для идентификации личности. Отпечатки пальцев являются надежным методом идентификации и уникальны, поскольку расположение текстур на каждом пальце варьируется от человека к человеку и не меняется в зависимости от развития или возраста. Отпечаток браузера представляет собой строку, состоящую из различной информации о браузере, такой как количество ядер ЦП, информация о видеокарте, системных шрифтах, разрешении экрана, подключаемых модулях браузера и т. д.Пользователь может быть позиционирован почти абсолютно, даже если используется режим приватного окна браузера, это неизбежно..
Это пассивный метод идентификации. То есть, теоретически, если вы посещаете определенный веб-сайт, то этот веб-сайт может идентифицировать вас.Хотя вы не знаете, кто вы, но у вас есть уникальный отпечаток пальца.Реклама, точный толчок, меры безопасности, или несколько других вещей о конфиденциальности, все очень удобно.
На рынке также есть несколько способов определения режима инкогнито, например, проверкаFileSystem API
Наличие, по режиму инкогнито и режиму не инкогнито, выполнение скриптов и разница в скорости записи в файловую систему браузера и т.д.
BrowserLeaks
Долгое время считалось, что IP-адреса и файлы cookie являются единственными надежными цифровыми отпечатками пальцев, используемыми для отслеживания людей в Интернете. Но через некоторое время все вышло из-под контроля, когда современные веб-технологии позволили заинтересованным организациям использовать новые методы идентификации и отслеживания пользователей без их ведома и неизбежных обстоятельств.
BrowserLeaksВсе дело в конфиденциальности просмотра и снятии отпечатков пальцев в веб-браузере. Здесь вы найдете библиотеку инструментов для тестирования безопасности веб-технологий, которые покажут вам, какие типы персональных данных могут быть утеряны, и как защитить себя от таких утечек. Этот веб-сайт обеспечивает просмотр различных типов отпечатков пальцев, включая IP-адреса, географические местоположения, Canvas, WebGL, WebRTC, шрифты и многое другое.
Если вас интересуют технические принципы, вы можете ввестиBrowserLeaks, щелкните соответствующий заголовок карточки, чтобы просмотреть и понять, например,HTML5 Canvas Fingerprintingстраница, которая предоставит такую информацию, как ваш отпечаток пальца Canvas и его уровень уникальности; к ней также можно получить доступ черезИзучите отпечатки пальцев браузераИзучите эту статью.
Реализовать отпечатки пальцев холста
**Canvas Fingerprinting (Canvas Fingerprinting) рисует изображение определенного содержимого на основе Canvas и использует метод canvas.toDataURL() для возврата строки содержимого изображения в кодировке base64. Для формата файла PNG он разделен на фрагменты, и последний фрагмент представляет собой 32-битный код проверки CRC, который можно использовать для уникальной идентификации пользователя путем извлечения этого кода проверки CRC. **Canvas использует HTML5 Canvas API и JavaScript для динамического создания нужных вам изображений. Как и другие технологии отслеживания, этот метод используется тысячами веб-сайтов, в том числе в известной нам сфере рекламы.
Ниже приведена простая реализация отпечатка пальца Canvas.Принцип на самом деле относительно прост.Если вы его не понимаете, то можете обратиться к комментариям:
// PHP 中,bin2hex() 函数把 ASCII 字符的字符串转换为十六进制值。字符串可通过使用 pack() 函数再转换回去
// 下面是PHP 的 bin2hex 的 JavaScript 实现
function bin2hex(s) {
let n,
o = '';
s += '';
for (let i = 0, l = s.length; i < l; i++) {
n = s.charCodeAt(i).toString(16);
o += n.length < 2 ? '0' + n : n;
}
return o;
}
// 获取指纹UUID
function getUUID(domain) {
// 创建 <canvas> 元素
let canvas = document.createElement('canvas');
// getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性
let ctx = canvas.getContext('2d');
// 设置在绘制文本时使用的当前文本基线
ctx.textBaseline = 'top';
// 设置文本内容的当前字体属性
ctx.font = "14px 'Arial'";
// 设置用于填充绘画的颜色、渐变或模式
ctx.fillStyle = '#f60';
// 绘制"被填充"的矩形
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
// 在画布上绘制"被填充的"文本
ctx.fillText(domain, 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText(domain, 4, 17);
// toDataURL返回一个包含图片展示的 data URI
let b64 = canvas.toDataURL().replace('data:image/png;base64,', '');
// atob() 方法用于解码使用 base-64 编码的字符串;base-64 编码使用方法是 btoa() ,第十九式中有介绍
let crc = bin2hex(atob(b64).slice(-16, -12));
return crc;
}
// 调用时,你可以传入任何你想传的字符串,并不局限于传递domain,这里只是为了便于区分
console.log(getUUID('https://www.baidu.com/'));
Результаты теста показывают, что код проверки CRC, генерируемый при доступе одного и того же браузера к этому домену, всегда остается неизменным. можно просто понимать какОдна и та же операция рисования элемента HTML Canvas в разных операционных системах и разных браузерах, сгенерированное содержимое изображения на самом деле не совсем то же самое.. Это может произойти по нескольким причинам:
- Что касается форматов изображений, разные веб-браузеры используют разные механизмы обработки графики, разные параметры экспорта изображений, разные уровни сжатия по умолчанию и т. д.
- На уровне пикселей каждая операционная система использует разные настройки и алгоритмы для операций сглаживания и субпиксельного рендеринга.
- Даже для одной и той же операции рисования результирующие данные изображения все равно различаются на уровне хэша.
FingerprintJS
FingerprintJSэто быстрая библиотека отпечатков пальцев браузера, чистаяJavaScript
Реализовано без каких-либо зависимостей. По умолчанию используйтеMurmur Hash
Алгоритм возвращает 32-битное целое число, а хеш-функцию можно легко заменить. При этом он еще и очень легкий: открытыйgzipped
только после843 bytes
, анонимно определяя веб-браузеры с точностью до94%
.
МурмурХэш — этонезашифрованный хэшФункция, подходящая для общих операций поиска хэша. Изобретенный Остином Эпплби в 2008 году, появилось несколько вариантов, все из которых стали общественным достоянием. По сравнению с другими популярными хэш-функциями функция случайного распределения MurmurHash лучше работает для ключей с высокой регулярностью.
Использование FingerprintJS также относительно простое:
import FingerprintJS from '@fingerprintjs/fingerprintjs';
// 应用启动时初始化:Initialize an agent at application startup.
const fpPromise = FingerprintJS.load();
(async () => {
// Get the visitor identifier when you need it.
const fp = await fpPromise;
const result = await fp.get();
// This is the visitor identifier:
const visitorId = result.visitorId;
console.log(visitorId);
})();
- Введение и использование отпечатков пальцевJS
- fingerprintJS - GitHub
- отпечаток пальцаJS — Официальная документация
Вышеупомянутые методы позволяют получить более 90% уникальных отпечатков пальцев браузера, которые могут быть не совсем уникальными, поскольку, например, переписывая связанные методы холста, используя аналогичныесова браузерДругие специальные браузеры все равно сделают родственные методы недействительными, но технические средства чаще являются лишь общим решением, что увеличивает барьеры и затраты на взлом.Думаю, этого достаточно для поддержки разработки в обычных сценариях.
Owl Browser — это браузер, модифицированный и скомпилированный на основе кода хрома, в нем изменены различные API нижнего уровня, и его можно передавать пользователям для настройки и возврата различных данных, таких как Canvas, Webgl, AudioContext, WebRTC, шрифты, UserAgent. , разрешение экрана, количество ядер ЦП, объем памяти, информацию о подключаемых модулях, язык и другую информацию, чтобы вы могли полностью избежать «генерирования» уникального отпечатка пальца пользователя. Поскольку интернет-компании, рекламодатели и разработчики любят отслеживать ваши действия и действия в Интернете, чтобы предоставлять вам целевую рекламу, это часто считается вторжением в частную жизнь пользователя.
С помощью уникального отпечатка браузера мы можем получить соответствующие отпечатки пальцев, когда мы подсчитываем UV, лайки и голоса, и, естественно, мы можем в значительной степени определить, перехватывали ли пользователи голоса и трафик, но,В конце концов, снятие отпечатков пальцев в браузере — палка о двух концах., решая вышеуказанные проблемы, это неизбежно принесет пользователям больше проблем с утечкой информации.
Пятьдесят седьмой стиль: Головоломки JavaScript!
Как программист, требования есть везде, ошибки есть везде, и, естественно, принуждение может быть везде. Оглядываясь назад на каждое из ваших интервью, вы когда-нибудь презирали или показывали интервьюера? Вспоминая каждое ваше общение с коллегами, вы когда-нибудь теряли дар речи и чувствовали себя некомфортно из-за странных вопросов интервью, заданных вашими коллегами, или из-за трюков 😓, хотите покрасоваться, но какое-то время страдаете от «застенчивости в своем уме»,JavaScript Puzzlers!Это веб-сайт, который собирает различные темы JavaScript.С ним моя мама больше не боится, что я не могу найти какой-либо код/темы, которыми я могу притворяться.
Сначала рассмотрим несколько тем:
var min = Math.min(),
max = Math.max();
min < max; // 答案: false
// 有趣的是, Math.min 不传参数返回 Infinity, Math.max 不传参数返回 -Infinity 😆
// 这个还是相对容易的
var name = 'World!';
(function () {
if (typeof name === 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
// 答案:Goodbye Jack
'1 2 3'.replace(/\d/g, parseInt); // 答案: 1, NaN, 3
Нет, я фронтенд-инженер, можно ли меня называть притворяющимся инженером? Может, это головоломка, бесполезная, но она называетсяВеликая мудрость маленьких хитростей, ха-ха~
Тем не менее, эти извращенные темы включают в себя широкий спектр знаний. Если вы сможете освоить принципы, лежащие в основе этих тем, ваше понимание JavaScript может быть значительно улучшено. Вот темы для справки:
В настоящее время, по неизвестным причинам, может быть, слишком много делать вид, что отвечаю на вопрос 😄,JavaScript Puzzlers!Веб-сайт больше недоступен, но, к счастью, вы также можете просмотреть конкретные темы и анализ по следующим двум ссылкам на GitHub.
- Анализ 44 извращенных вопросов по Javascript (часть 1)
- Анализ 44 извращенных вопросов Javascript (часть 2)
- JavaScript Puzzlers!
Пятьдесят восьмой стиль: классная адресная строка браузера
Как front-end разработчик, мы даже проводим с браузером больше времени каждый день, чем девушка/парень (если есть 😄) проводит с вами, думаем о каждом "не очень радужном" утре, каждом закате, чтобы выполнить задание на время , только браузер и редактор всегда были вашими верными партнерами, так что вы знаете браузер? Поймите, что каждый день вы должны печататьhttp://localhost:3000/
Адресная строка? В этом разделе вы познакомитесь с забавными подробностями об адресной строке.
Адресная строка браузера запускает код JavaScript
Да, вы правильно прочитали, в «адресной строке браузера для запуска кода JavaScript» методjavascript:
За началом следует оператор, который необходимо выполнить. Следует отметить, что еслиСкопировав и вставив код в адресную строку браузера, IE и Chrome автоматически удалит начало кода.javascript:
, поэтому его нужно добавить вручную для правильного выполнения. Причем, запускать нужно в адресной строке сайтаjavascript:
, вместо запуска на только что открытой пустой вкладке, это не вступит в силу.
// 点击确定后,会接着弹出:孤舟蓑笠翁,独钓寒江雪,点击取消则不会弹出
javascript: if (confirm('千山鸟飞绝,万径人踪灭'))
alert('孤舟蓑笠翁,独钓寒江雪');
Адресная строка браузера запускает HTML-код
Если есть много людей, которые знают "запуск кода JavaScript в адресной строке браузера", меньше людей знают о "запуске кода HTML в адресной строке браузера". В адресной строке браузера без ядра IE вы можете напрямую запустить код HTML ! Введите следующий код в адресную строку и нажмите Enter для запуска, появится страница, показанная ниже:
data:text/html,
<h1>Nothing is given, Everything is earned!</h1>
Браузер может быть вашим блокнотом
Это еще возня с адресной строкой браузера.Скопируйте и вставьте следующий код в адресную строку браузера.После запуска браузер становится простым и оригинальным редактором.Сказать особо нечего,просто попробуйте.
data:text/html,
<html contenteditable></html>
Дополнительно добавить универсальный браузерОтменить закрытие страницыГорячая клавиша: под MAC OS,command + shift + t
; Окна:ctrl + shift + t
. этоОткрыть закрытые страницыГорячая клавиша , вы можете продолжать нажимать ее, и закрытые страницы будут восстановлены по очереди~, или же посмотрите, что сделали ваши друзья, чтобы увидеть, будут ли они поражены 😜
Использованная литература:У вас есть все эти малоизвестные холодные знания о внешнем интерфейсе?
Пятьдесят девятый стиль: Ван Фэн будет плакать, когда увидит это - как я легко попал на горячий поиск Baidu?
**«Заголовки Ван Фэна»** всегда были в центре внимания индустрии развлечений. Каждый раз, когда я вижу Ван Фэна в списке горячих поисковых запросов Weibo, я думаю, что смогу достичь вершины списка. Ван Фэн до сих пор не может заголовки давно!
В конце концов, «Помогите Ван Фэну попасть в заголовки» вместо этого стало популярным поиском и даже было включено вЭнциклопедия Байду🐶.
Anthracene 🤔, если Wang Feng - интерфейс-инженер, не будет ли горный поиск в минутах? Даже если вы не понимаете HTML, пока вы знаете HTML5contenteditable
свойства, консольный ввод adocument.body.contentEditable='true';
, горячий поиск не меняется случайно, их сколько угодно 😄.
Антрацен 🤔, научившись этому трюку, даже ты легко сознаешься в объекте через горячий поиск... Но какПрофессиональный разработчик веб-приложений и веб-сайтов, как мы можем быть удовлетворены этим?
Точно так же он также использует HTML5contenteditable
атрибут, разумно добавьте редактируемый тег стиля в тело, затем этот стиль, мы можем изменить его на странице, просто подумайте об этом ... не так много пользы, хахаха, но опять же, этот атрибут находится в. Он все еще полезен в некоторые текстовые редакторы. Многие редакторы форматированного текста основаны наcontenteditable
реализовано, см.Углубленный редактор форматированного текста с возможностью редактирования содержимого.
<style style="display:block; height:50px;" contenteditable>
body {
background: red;
}
</style>
визуализации (картинки из справочной статьи ниже):
Ты думаешьcontenteditable
Толькоtrue
иfalse
? Фактически, его необязательные значения включают в себя:
- contenteditable=""
- contenteditable="events"
- contenteditable="caret"
- contenteditable="plaintext-only"
- contenteditable="true"
- contenteditable="false"
Кроме HTML5contenteditable
атрибут, на самом деле, есть еще один атрибут css, который обычно не используется ——user-modify
Аналогичного эффекта можно добиться,user-modify
Возможные значения следующие четыре:
read-only
read-write
write-only
read-write-plaintext-only
в,write-only
Не волнуйтесь, в эту эпоху практически нет поддержки браузеров, и предполагается, что в будущем ее не будет.read-only
Указывает только для чтения, что является состоянием по умолчанию для обычных элементов. Потом,read-write
иread-write-plaintext-only
Это заставит элемент вести себя как текстовое поле, вы можете сфокусироваться и вводить содержимое, первое может вводить форматированный текст, а второе может вводить только обычный текст.
Вы можете просмотреть конкретный эффект, проверив элемент и добавив стили CSS к элементу, или вы можете напрямую увидеть эффект Чжан Синьсюй.Пример страницы теста поведения свойства CSS с изменением пользователемдемо.
- У вас есть все эти малоизвестные холодные знания о внешнем интерфейсе?
- Небольшой совет: как сделать так, чтобы элемент contenteditable вводил только обычный текст
Шестидесятый стиль: Оглядываюсь вдруг, а человек там, где тусклый свет - куда делась моя мышка?
Этот трюк, чтобы скрыть мышь на странице, на самом деле не стоит упоминания, да и бесполезен. Вы можете напрямую скопировать следующий код в консоль, чтобы попробовать (если вы приостановите контекстное меню на странице, вы все равно сможете увидеть мышь):
var style = document.createElement('style');
document.head.appendChild(style);
style.type = 'text/css';
style.styleSheet
? (style.styleSheet.cssText = '* { cursor: none;!important; }')
: style.appendChild(
document.createTextNode('* { cursor: none;!important; }')
);
Принцип очень прост, настройкаcursor
собственностьnone
Просто:
* {
cursor: none !important;
}
Или введите в адресной строке браузера следующее:
IE и Chrome автоматически скроют предыдущий
javascript:
Затем обработайте последнюю часть как поле запроса. Вам необходимо скопировать следующий код и вставить его, прежде чем добавлять его вручную.javascript:
, а затем появляется эффект возврата каретки.
javascript:function play(){var style = document.createElement('style');document.head.appendChild(style);style.type = 'text/css';style.styleSheet ? (style.styleSheet.cssText = '* { cursor: none !important; }') : style.appendChild(document.createTextNode('* { cursor: none !important; }'));}play();
Использованная литература:Играйте с передним концом
Форма 61: Выйдите после долгого звонка, все еще держа пипу наполовину прикрытой - сделайте свой сайт размытым
Возможно, вы часто сталкиваетесь с такой страницей, когда вы не авторизованы, вы можете видеть только следующие эффекты:
Конечно, эффект здесь размыты на фоновом изображении Plactholder, на самом деле, если вы не рассматриваете безопасность, а также скомпрометированы и другие факторы, мы можем использовать CSS для достижения аналогичного эффекта.
javascript:function play(){var style = document.createElement('style');document.head.appendChild(style);style.type = 'text/css';style.styleSheet ? (style.styleSheet.cssText = '* { color: transparent !important; text-shadow: #333 0 0 10px !important; }') : style.appendChild(document.createTextNode('* { color: transparent !important; text-shadow: #333 0 0 10px !important; }'));}play();
Очевидно, что здесь в основном используются следующие два свойства CSS:
color: transparent !important;
text-shadow: #333 0 0 10px !important;
Использованная литература:Играйте с передним концом
Тип 62: Как веб-сайты блокируют инструменты разработчика
Инструменты разработчика браузера — это то, что дает нам этиПрофессиональный разработчик веб-приложений и веб-сайтовИспользуемые инструменты (конечно, профессионал вы или нет, в вашем сердце будет немного числа B😄), его роль заключается в том, чтобы помочь разработчикам просматривать элементы, макетировать веб-страницы, помогать фронтенд-инженерам лучше отлаживать точки останова. и т. д. Вы также можете использовать Инструмент проверяет процесс загрузки веб-страницы, выполняет анализ и оптимизацию производительности, получает запросы веб-страницы и т. д. (этот процесс также называется захватом пакетов). Автор с уверенностью может сказать,Без инструментов разработчика горячая и интересная фронтенд-разработка станет скучной., потому что я не чувствую, что есть более удобный инструмент, чем собственные инструменты разработчика браузера. Конечно,Говорят, что JS и CSS, написанные настоящим богом, не нуждаются в отладке., тогда давайте поговорим об этом по-другому, очевидно, я не такой человек, как настоящий Бог.
Если инструменты разработчика такие милые и полезные, почему мы должны их блокировать? - вероятно, потому что мы использовали и сделали опытно-конструкторские работы,Я не хочу, чтобы у других была возможность обнаружить код, который мы не понимаем, и содержащиеся в нем коммерческие секреты., Чум, он действительно подонок ~
Итак, в конце может вести себя какПодонок, который блокирует инструменты разработчикаШерстяная ткань?
Возможно, в зависимости от нескольких способов открытия консоли вы, естественно, подумаете:
- монитор F12;
- Отслеживайте и отключайте контекстное меню (поскольку в контекстном меню есть опция «проверить», чтобы открыть консоль);
Но действительно ли это работает? Нет, мы по-прежнему можем найти инструменты разработчика в разделе «Дополнительные инструменты» через три точки в правом верхнем углу браузера и нажать, чтобы открыть.
О чем мы думаем, что делать, чтобы решить эту проблему? Есть много онлайн-решения, некоторые не основные,Срок действия некоторых из них истек из-за обновлений браузера., соответствующие идеи и ссылки будут даны в конце этого раздела, вот только два метода, которые я считаю неплохими:
const im = new Image();
Object.defineProperty(im, 'id', {
get: function () {
// 在这里放入你的代码,比如我这里会让他跳到百度
console.log('Console is opened');
window.location.href = 'http://www.baidu.com';
},
});
console.log(im); //谷歌最新版失效
let num = 0; //谷歌最新版有效
const devtools = new Date();
devtools.toString = function () {
num++;
if (num > 1) {
// 在这里放入你的代码,比如我这里会让他跳到百度
console.log('Console is opened');
// window.location.href = "http://www.baidu.com";
return Date.prototype.toString.call(devtools); // 返回devtools结果(这一步不是必须的)
}
};
console.log(devtools);
Основной принцип вышеуказанного метода заключается в одном моменте:Консольный метод будет выполняться только в том случае, если консоль открыта., при использованииconsole
РаспечататьDate
, который вызоветDate
изtoString
метод, у нас естьtoString
Метод был переписан.Если вы вводите код напрямую, напримерconsole = 1
, приведенный выше код не будет работать.
Несколько других идей включают в себя:
- Прослушайте F12 или shift+ctrl+i, чтобы вызвать инструменты разработчика (вы не можете запретить доступ, чтобы сначала открыть инструменты разработчика, а затем ввести URL-адрес в адресной строке);
- Отслеживайте и отключайте контекстное меню (поскольку в контекстном меню есть опция «проверить», чтобы открыть консоль);
- Размер окна монитора (применимо, если средство разработки не установлено как независимое окно);
- Мониторинг модификаций DOM (подходит для таких сценариев, как защита водяными знаками);
- Используйте характеристики отладчика для бесконечной рекурсии.
Кроме вышеперечисленных методов, существуют такжеdevtools-detectorКласс подключаемых модулей, используемых для мониторинга проблем, открытых инструментами разработчика, поэтому я не буду здесь вдаваться в подробности.
Другие ссылки:
- Как веб-сайт определяет, включены ли инструменты разработчика?
- Обнаружение JS, 6 способов отключить инструменты разработчика браузера
- Как определить, открыл ли браузер пользователя панель отладки (F12, чтобы открыть инструменты разработчика) в JS-файле во фронтенд-разработке?
- Не было бы удобнее для веб-сайта блокировать такие инструменты разработчика, чем отслеживать MouseDown?
- JS запрещает открывать консоль
Шестьдесят третий стиль: идя с двумя кроликами по земле, Ань Нэн может сказать, мужчина я или женщина - мы с тобой говорим о сексе? Итак, как сравнить преимущества и недостатки производительности различных методов записи
Производительность, преимущества и недостатки различных методов письмаОн наиболее часто упоминается и затрагивается в наших ежедневных разработках, технических дискуссиях. При написании фрагмента кода многие студенты могут захотеть узнать, какова его производительность и какой из них быстрее, чем другие методы написания, но они страдают от отсутствия полезных инструментов, поэтому они могут только проверять время выполнения вручную.Одно неудобно, а другое из-за того, что количество отсчетов слишком мало и погрешность большая. Итак, кроме теоретического анализа принципа, как можно лаконично, ясно и эффективно сравнить скорость выполнения и производительность различных методов написания JS? Это включает в себя JSинструмент для тестирования производительности.
Принцип инструментов тестирования производительности JS, как правило, состоит в том, чтобы многократно запускать заданный тестовый пример в указанной среде, а затем выводить результаты сравнения.JSBench.MeЭто такой онлайн-инструмент для тестирования производительности кода.
Также есть плагин npm — мощная библиотека для бенчмаркингаBenchmark.jsОфициально сказано:
Benchmark.js — мощныйОриентирыБиблиотека, которая поддерживает таймеры с высоким разрешением и возвращает статистически значимые результаты. Как видно на jsPerf.
упомянутый вышеjsPerfИзначально это был инструмент, который я хотел внедрить, но этот инструмент меня безжалостно отверг 😭.
Итак, давайте посмотримBenchmark.js
Используйте эту библиотеку:
var suite = new Benchmark.Suite();
// add tests
suite
.add('RegExp#test', function () {
/o/.test('Hello World!');
})
.add('String#indexOf', function () {
'Hello World!'.indexOf('o') > -1;
})
// add listeners
.on('cycle', function (event) {
console.log(String(event.target));
})
.on('complete', function () {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
// run async
.run({ async: true });
// logs:
// => RegExp#test x 4,161,532 +-0.99% (59 cycles)
// => String#indexOf x 6,139,623 +-1.00% (131 cycles)
// => Fastest is String#indexOf
Форма шестьдесят четыре:requestIdleCallback
—— Что делает браузер в одном кадре, не заденет ли он рыбу 🐟?
Что браузер делает с одним фреймом?
Все мы знаем, что содержимое страницы прорисовывается кадр за кадром, а частота обновления браузера показывает, сколько кадров прорисовывает браузер в секунду. В принципе, количество кадров, отрисовываемых за 1 с, также велико, а качество изображения также деликатно.
Стандарт кинопроекции должен показывать 24 кадра в секунду, что означает, что фильм показывает 24 кадра в секунду для достижения эффекта анимации.Если непрерывное изменение составляет более 24 кадров/с, визуальное постоянство будет «анимировать» изображение. статичное изображение. . Исследования показали, что человеческий глаз может выдержать ограничение в 55 кадров в секунду, а исследования показали, что более 60 кадров в секунду могут значительно улучшить впечатления зрителей от просмотра. 120 кадров в секунду — это в 5 раз больше, чем 24 кадра в секунду.Использование этой технологии съемки позволяет сделать картинку более реалистичной, дать зрителям почувствовать себя в ней, дать людям ощущение реальности и фантазии.
В настоящее время большинство браузеров имеют частоту 60 Гц (60 кадров/с), и каждый кадр занимает около 16,6 мс. Так что же делает браузер в течение этого кадра (16,6 мс)?
Из приведенного выше рисунка ясно видно, что браузер будет выполнять следующие процессы в одном кадре:
- Принимать события ввода и обрабатывать взаимодействия с пользователем, такие как клики, касания, прокрутка и т. д.
- Выполнить обратный вызов события
- начать кадр
- Выполнить РАФ (
RequestAnimationFrame
) - макет страницы, расчет стиля
- рендеринг
- Выполнить РИЦ (
RequestIdelCallback
)
Событие RIC на шаге 7 не выполняется в конце каждого кадра, только когда первые 6 действий выполняются в пределах 16,6 мс от кадра и еще остается время, оно будет выполнено. Если после выполнения одного кадра еще есть время для выполнения RIC-события, следующий кадр необходимо отрисовать после окончания выполнения события, поэтому выполнение RIC не должно превышать 30 мс. Если управление не возвращается в браузер в течение длительного времени, это повлияет на следующий кадр.Визуализация страницы приведет к зависанию страницы и несвоевременной реакции на событие.
Вдохновение requestIdleCallback
Мы используем оставшееся время браузера в качестве критерия для прерывания задачи, тогда нам нужен механизм, чтобы уведомить нас, когда у браузера осталось время.
requestIdleCallback((deadline) => {
// deadline 有两个参数
// timeRemaining(): 当前帧还剩下多少时间,最大值50ms
// didTimeout: 是否超时
// 另外 requestIdleCallback 后如果跟上第二个参数 {timeout: ...} 则会强制浏览器在当前帧执行完后执行。
if (deadline.timeRemaining() > 0) {
// TODO
} else {
requestIdleCallback(otherTasks);
}
});
// 用法示例
let tasksNum = 10000;
requestIdleCallback(unImportWork);
function unImportWork(deadline) {
while (deadline.timeRemaining() && tasksNum > 0) {
console.log(`执行了${10000 - tasksNum + 1}个任务`);
tasksNum--;
}
if (tasksNum > 0) {
// 在未来的帧中继续执行
requestIdleCallback(unImportWork);
}
}
На самом деле, некоторые браузеры уже реализовали этот API, а именно requestIdleCallback. Однако из-за следующих факторов при рефакторинге и обновлении React Facebook отказался от нативного API requestIdleCallback и реализовал более полную функцию.requestIdleCallbackpolyfill
,ЭтоScheduler. В дополнение к функции запуска обратных вызовов при простое Scheduler также предоставляет различные приоритеты планирования для задач, которые нужно установить:
- совместимость с браузером;
- Частота запуска нестабильна и зависит от многих факторов. Например, когда наш браузер переключает вкладки, частота requestIdleCallback, зарегистрированная на предыдущей вкладке, станет очень низкой.
requestIdleCallback
Обратный вызов будет выполняться во время простоя браузера, в то время какдокументация w3cЕсть два типа свободного времени:
- При выполнении непрерывной анимации время между представлением данного кадра на экран и началом обработки следующего кадра является временем простоя. Во время непрерывных анимаций и обновлений экрана такие периоды простоя происходят часто, но обычно очень короткие (т. е. менее 16 мс, если наш экран является устройством с частотой 60 Гц (обновление экрана 60 раз за 1 с)), как показано на изображении ниже.
- Еще один вид простоя, когда пользователь бездействует (никак не взаимодействует с веб-страницей) и на экране отсутствует анимация. В этот момент время простоя теоретически бесконечно. Но чтобы избежать заметных пользователю задержек при выполнении непредсказуемых задач (таких как обработка пользовательского ввода), продолжительность этих периодов простоя должна быть ограниченаМаксимум 50 мс, по окончании периода простоя браузер может запланировать еще один период простоя.
То есть, даже если браузер всегда находится в состоянии ожидания,deadline.timeRemaining
Максимальное время, которое вы можете получить, также 50 мс, чтостандарт w3cУказано. Некоторые низкоприоритетные задачи могут быть использованыrequestIdleCallback
Выполнять, когда браузер не занят.В то же время, поскольку время ограничено, задачи, которые он выполняет, должны быть как можно меньше для количественного определения и подразделения.
Максимальный крайний срок в 50 мс исходит из
RESPONSETIME
Исследования, которые показывают, что ответы на вводимые пользователем данные в течение 100 миллисекунд часто воспринимаются людьми как мгновенные. Ограничение периода бездействия до 50 мс означает, что даже если пользовательский ввод происходит сразу после запуска задачи бездействия, у пользовательского агента остается 50 мс для ответа на ввод пользователя без возникновения задержек, воспринимаемых пользователем.
Когда производительность устройства становится все лучше и лучше, а эффект, поддерживаемый браузером, становится все более и более ошеломляющим, разработчики браузера начали рассматривать возможность использования собственного API для работы с некоторыми функциями, которые особенно требовательны к производительности. .requestAnimationFrame
,InsterSectionObserver
,прибытьrequestIdleCallback
, для будущего интерфейса, полного надежд, да, у всех нас будет «светлое будущее», ха-ха 😄 Более подробно о браузерах вы можете узнать из двух моих предыдущих статей:
- Как работают браузеры: Chrome V8 позволяет узнать больше о JavaScript
- 47 картинок перенесут вас в мир браузеров
Дальнейшее чтение и ссылки
- requestIdleCallback — планирование фоновых задач
- Анализ принципа фрейма браузера
- Accurately measuring layout on the web
- Cooperative Scheduling of Background Tasks
Тип 65: Как сгенерировать случайную строку, содержащую прописные и строчные буквы и цифры?
В проекте мы можем столкнуться с необходимостью использования JS для генерации случайных строк определенной длины, таких как хэш-значения, uuid, случайные коды и т. д. Помимо использования некоторых библиотек и плагинов, по сути, в некоторых сценариях , мы полностью настраиваемая реализация функцийслучайная строка указанной длиныпоколение.
Для компактной версии функции требуется всего две строки кода:
/**
* 生成长度为len的包含a-z、A-Z、0-9的随机字符串
*/
function generateStr(len = 18) {
// 一行代码生成0-9、A-Z、a-z、总长度为62的字符数组
var arr = [...new Array(62)].map((item, i) =>
String.fromCharCode(i + (i < 10 ? 0 : i < 36 ? 7 : 13) + 48)
);
return [...new Array(len)]
.map(() => arr[Math.floor(Math.random() * arr.length)])
.join('');
}
generateStr(18);
Если вы беспокоитесь о повторении, вы можете добавитьMap
Чтобы кэшировать сгенерированную строку и судить каждый раз, когда вы возвращаетесь:
/**
* 生成长度为len的包含a-z、A-Z、0-9的随机字符串
*/
const cacheMap = new Map(); // 缓存已经生成过了的字符串
// 一行代码生成0-9、A-Z、a-z、总长度为62的字符数组
const arr = [...new Array(62)].map((item, i) =>
String.fromCharCode(i + (i < 10 ? 0 : i < 36 ? 7 : 13) + 48)
);
function generateStr(len = 18) {
const str = [...new Array(len)]
.map(() => arr[Math.floor(Math.random() * arr.length)])
.join('');
if (cacheMap.has(str)) {
// 这里会有死循环的问题,比如下面的for循环,i设置的大于62
console.log(cacheMap, str);
// i 值越大,len越小,重复的概率越大
return generateStr(len);
} else {
cacheMap.set(str, true);
return str;
}
}
for (let i = 0; i < 20; i++) {
// 长度选小一点,测试20次
// i设置的大于62会出现死循环,可先算出排列组合数进行预防
// i 值越大,len越小,重复的概率越大,执行时间越长
generateStr(1);
}
console.log(cacheMap);
1 строка кода для генерации чисел заданной длины: Этот метод имеет недостатки, малая вероятность недостаточного количества цифр (причина в том, что 0,00566 * 100000 = 566, предыдущий 0 будет потерян), не рекомендуется.
// len 最多16,可能出现
function generateNum(len = 16) {
return Math.floor(Math.random() * Math.pow(10, len));
}
Шестьдесят шестая форма: Почему срединный путь упразднен, а я его сегодня оставляю в покое - как отправить запрос при выходе со страницы?
Когда пользователь удаляет веб-страницу (закрывает браузер, обновляет браузер или переходит на другие страницы), иногда необходимо отправить некоторые статистические данные на сервер; в то же время, когда интерфейс отслеживает аномалии и подсчитывает длину доступа к странице, ему также нужно будет обрушить страницу, чтобы отправить запрос, когда она закрыта. Естественный способ состоит в том, чтобыunload
событие илиbeforeunload
Внутри функции прослушивателя событий используйтеXMLHttpRequest
Объект отправляет данные. Однако это не очень надежно, посколькуXMLHttpRequest
Объект отправляется асинхронно, и, вероятно, когда он будет отправлен, страница и связанные с ней ресурсы были выгружены, что вызоветfunction not found
ошибка, из-за которой отправка отменяется или не отправляется.
РешениеAJAX
Связь меняется на синхронную отправку, то есть выгрузить страницу можно только после завершения отправки. но,Многие браузеры больше не поддерживают синхронизациюXMLHttpRequest
объект(которыйopen()
Третий параметр методаfalse
):
window.addEventListener('unload', logData, false);
function logData() {
var client = new XMLHttpRequest();
// 第三个参数表示同步发送
client.open('POST', '/log', false);
client.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
client.send(analyticsData);
}
Существует несколько обходных путей для синхронной связи:
- Один из способов — создать новый
<img>
элемент, данные помещаются в атрибут src как строка запроса URL-адреса.В это время браузер будет ждать загрузки изображения (ответ сервера) перед выгрузкой. - Другой способ сделать это — создать цикл, выполнение которого занимает несколько секунд, передать данные в течение этих секунд, а затем выгрузить страницу.
Задержите выгрузку, создав элемент изображения и установив его атрибут src в обработчике события выгрузки, чтобы обеспечить отправку данных. так какБольшинство браузеров задерживают выгрузку, чтобы сохранить изображение загруженным, поэтому данные могут быть отправлены в событии выгрузки..
const reportData = (url, data) => {
let img = document.createElement('img');
const params = [];
Object.keys(data).forEach((key) => {
params.push(`${key}=${encodeURIComponent(data[key])}`);
});
img.onload = () => (img = null);
img.src = `${url}?${params.join('&')}`;
};
Общая проблема этих практик заключается в том, что время выгрузки резко увеличивается, загрузка последующих страниц задерживается, а взаимодействие с пользователем ухудшается.
иNavigator.sendBeacon
Он был создан для решения проблемы «отправки запроса при выходе страницы», которую можно использовать для отправки небольших объемов данных по HTTP.асинхронныйпередается на веб-сервер. Можно обнаружить, что используется тот же асинхронный метод, ноNavigator.sendBeacon
Выданный асинхронный запрос выполняется как задача браузера и не связан с текущей страницей.. Поэтому этот метод не блокирует процесс выгрузки страницы и не задерживает загрузку последующих страниц. Когда пользовательский агент успешно добавляет данные в браузерочередь передачичас,sendBeacon()
метод вернетtrue
, если он ограничен общим количеством очередей и размером данных, он вернетfalse
. возвращениеtrue
После этого это просто означает, что он попал в очередь на отправку, браузер будет всеми силами стараться, чтобы отправка прошла успешно, но судить, удалась она или нет, невозможно.
В настоящее время Google Analytics используетNavigator.sendBeacon
сообщить данные.Navigator.sendBeacon
Метод принимает два параметра, первый параметр — это URL-адрес целевого сервера, а второй параметр — это отправляемые данные (необязательно), которые могут быть любого типа (строка, объект формы, двоичный объект и т. д.). Возвращаемое значение этого метода — логическое значение, true, если данные были успешно отправлены, и false в противном случае. Метод HTTP для отправки данных с помощью этого метода — POST, который может быть междоменным, подобно данным отправки формы. Он не может указать функцию обратного вызова.
window.addEventListener('unload', analytics, false);
function analytics(state) {
if (!navigator.sendBeacon) return;
var URL = 'http://example.com/analytics';
var data = 'state=' + state + '&location=' + window.location;
navigator.sendBeacon(URL, data);
}
sendBeacon
Метод имеет следующие характеристики:
- Отправляется асинхронный запрос, и это POST-запрос, при разборе параметров на бэкенде нужно обращать внимание на способ обработки;
- Отправленный запрос выполняется в очереди задач браузера и отделяется от текущей страницы, поэтому он не будет блокировать выгрузку текущей страницы и процесс загрузки следующих страниц, а пользовательский опыт будет лучше;
- Он может только судить, поставлено ли оно в очередь задач браузера, но не может судить об успешной отправке;
-
Beacon API
Соответствующий обратный вызов не предоставляется, поэтому возврат бэкенда лучше не использовать.response body
.
использованная литература
- Google Analytics added sendBeacon functionality to Universal Analytics JavaScript API
- Navigator.sendBeacon неблокирующая статистика отправки
- Навигатор.sendBeacon() — MDN
Шестьдесят седьмой стиль: нет цвета и крылья феникса, у одного есть сердце и сердце - как сделать VSCode, браузер и у тебя есть сердце, и ты можешь "подключиться"?
Когда вы только взялись за относительно большой проект, вы часто можете столкнуться с такой проблемой: вам нужно изменить страницу, но вы не знакомы со структурой проекта, структура папок не стандартизирована и т. д., вы не знаете, какой каталог файл находится внутри, вам нужно изменить ошибку, но трудно быстро найти файл, в котором находится проблема.В это время вы когда-нибудь представляли, что было бы красиво, если бы вы могли щелкнуть компонент на странице, автоматически перейти к соответствующему файлу в VSCode и найти соответствующий номер строки?
react-dev-inspector Просто богиня мечты, чтобы удовлетворить ваши фантазии, этот плагин позволяет пользователям переходить непосредственно от компонентов браузера React к локальному коду IDE простым щелчком мыши. ТА может не только удовлетворить ваши фантазии, но и очень проста и удобна в использовании.Прочитав эту движущуюся картинку, вы все поймете 😜:
Если вы все еще не в своей тарелке после прочтения картинки, вы также можетеПредварительный просмотр онлайнИспытайте адрес (в адресе онлайн-опыта сочетание клавиш для активации щелчка прыжка представляет собой комбинацию четырех кнопок, но вам вообще не нужно об этом беспокоиться, потому что эту комбинацию можно настроить, вы можете полностью ее изменить на комбинацию двух кнопок).
Как упоминалось ранее, способ использования очень прост, всего три шага:
-
Во-первых, убедитесь, что ваша командная строка доступна через
code
команда, чтобы открыть редактор VSCode, напримерcode .
, откройте файл в текущей папке с VSCode, если это не настроено, вы можете обратиться к следующим шагам:- Начните с открытия VSCode.
- использовать
command + shift + p
(Обратите внимание, что использование под окномctrl + shift + p
), а затем найдите код, выберитеinstall 'code' command in path
.
-
Установить
react-dev-inspector
,Исправлятьbabelrc.js
иwebpack.config.ts
документ:
// babelrc.js
export default {
plugins: [
// plugin options docs see:
// https://github.com/zthxxx/react-dev-inspector#inspector-babel-plugin-options
'react-dev-inspector/plugins/babel',
],
};
// webpack.config.ts
import type { Configuration } from 'webpack';
import { launchEditorMiddleware } from 'react-dev-inspector/plugins/webpack';
const config: Configuration = {
/**
* [server side] webpack dev server side middleware for launch IDE app
*/
devServer: {
before: (app) => {
app.use(launchEditorMiddleware);
},
},
};
- Внесите следующие изменения в файл записи проекта:
import React from 'react';
import { Inspector, InspectParams } from 'react-dev-inspector';
const InspectorWrapper =
process.env.NODE_ENV === 'development' ? Inspector : React.Fragment;
export const Layout = () => {
// ...
return (
<InspectorWrapper
// props docs see:
// https://github.com/zthxxx/react-dev-inspector#inspector-component-props
// 这里可以随便配置快捷键,你可以改成两个按键的组合
keys={['control', 'shift', 'command', 'c']}
disableLaunchEditor={false}
onHoverElement={(params: InspectParams) => {}}
onClickElement={(params: InspectParams) => {}}
>
{/*这里是你原来的入口组件jsx*/}
<YourComponent>...</YourComponent>
</InspectorWrapper>
);
};
Конечно, этот плагин в настоящее время также поддерживаетVite2
,create-react-app
,Umi
К нему также очень легко получить доступ, вы можете обратиться кРепозиторий GitHub и его использованиедокументация.
Принцип работы этого плагина просто делится на три шага:
-
во время сборки:добавить одну
webpack loader
идти сПройдите узел AST перед компиляцией и добавьте путь к файлу, имя и другую связанную информацию в узел DOM.. использоватьDefinePlugin
Введите корневой путь среды выполнения проекта, чтобы его можно было использовать для соединения пути к файлу и открытия соответствующего файла в VSCode. -
Время выполнения: необходимо обернуть в самый внешний слой проекта
Inspector
Компонент, используемый для отслеживания сочетаний клавиш на стороне браузера, всплывает слой маски отладки, при нажатии на слой маски используйтеfetch
Отправьте запрос нативному сервису, чтобы открыть VSCode. -
местная служба: надо начинать
react-dev-utils
Промежуточное ПО в , прослушивает определенный путь и выполняет команду для открытия VSCode на локальном сервере, напримерcode src/pages/index.ts
.
Если вам интересен принцип, вы можете обратиться к статье команды ByteDance Web Infra——Оперативность разработки — я нажал на элемент на странице, а VSCode послушно открыл соответствующий компонент? Открытые принципы.
Шестьдесят восьмой стиль: ловишь рыбу и хочешь спрятаться? Почему бы не позволить вашему браузеру сообщать всем, что вы просматриваете порнографический сайт
Водные лыжи и рыбалка на работе, когда приходят коллеги, быстро переключать интерфейс браузера? Почему бы просто не позволить своим коллегам подумать, что вы просматриваете какой-то «серьезный» веб-сайт?
Следующий код при переключении вкладки браузера, чтобы сделать страницу невидимой, изменит эффект отображения заголовка и значка невидимой страницы.Вы можете напрямую скопировать следующий код и попробовать его в консоли.
let interval = null;
(function () {
// 获取icon所在link,rel*="icon"是为了兼容rel="shortcut icon"的情况
const Link = document.querySelector('link[rel*="icon"]');
const sourceTitile = document.title;
const sourceLink = Link.href;
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
// 让title文字动起来,更加醒目
interval = setInterval(scroll, 1000);
// 修改title,这里也可以直接写文字,之所以用编码后的嘛,🤔,是因为不想让你一眼看出代码里下了毒...
document.title = decodeURI(
'%E6%82%A8%E6%AD%A3%E5%9C%A8%E6%B5%8F%E8%A7%88%E9%BB%84%E8%89%B2%E7%BD%91%E7%AB%99...'
);
Link.href =
'https://king-hcj.github.io/images/posts/zhuangbility100/nh.gif?raw=true';
Link.type = 'image/gif';
} else {
clearInterval(interval);
document.title = sourceTitile;
Link.href = sourceLink;
}
});
})();
function scroll() {
// 让title文字动起来,更加醒目
const titleInfo = document.title;
const firstInfo = titleInfo.charAt(0);
const lastInfo = titleInfo.substring(1, titleInfo.length);
document.title = lastInfo + firstInfo;
}
Визуализация:
Тип 69: Элемент с атрибутом Id создает глобальную переменную.
Вероятно, вы уже знакомы с атрибутом Id в HTML:
- Атрибут id указывает уникальный идентификатор HTML-элемента;
- id должен быть уникальным в HTML-документе;
- Атрибут id можно использовать в качестве привязки ссылки для изменения или оформления элемента с указанным идентификатором с помощью JavaScript (HTML DOM) или с помощью CSS.
Для заданного элемента HTML с идентификатором в дереве DOM элемент div можно получить, используя его идентификатор в качестве имени переменной. Итак, следующееconsole.log(foo)
напечатает этот элемент DOM div с идентификатором foo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="foo"></div>
<script type="text/javascript">
console.log(foo); // 会输出id为foo的div 这个 DOM元素
</script>
</body>
</html>
Если не верите мне, то откройте в это время свой сайт и посмотрите:
Значит ли это, что его можно использовать в этих браузерах вместо метода getElementById? В реальном проекте лучше всего писать максимально честно, ведь в таком случае велика вероятность того, что вас потом поприветствует преемник или коллеги 😄 ~
Тип 70: использовать тег для анализа URL
Много раз нам приходилось извлекать доменные имена, ключевые слова запроса, значения переменных параметров и т. д. из URL-адреса, но мы никогда не ожидали, что браузер может легко помочь нам выполнить эту задачу, не прописывая регулярности для сканирования. Метод заключается в том, чтобы сначала создать тег a в коде JS, а затем назначить URL-адрес для анализа атрибуту href атрибута a, а затем получить все, что мы хотим.
var a = document.createElement('a');
a.href = 'https://juejin.cn/user/2796746682939054/posts';
console.log(a.host);
Используя этот принцип и немного расширив его, мы получаем более надежный общий метод разбора каждой части URL-адреса.Ниже приведен распространенный пример инкапсуляции в Интернете.
function urlParse(url, key) {
var a = document.createElement('a');
a.href = url;
var result = {
href: url,
protocol: a.protocol.replace(':', ''),
port: a.port,
query: a.search,
params: (function () {
var ret = {},
centArr,
seg = a.search.replace(/^\?/, '').replace(/^\?/, '').split('&');
for (i = 0, len = seg.length; i < len; i++) {
if (!seg[i]) {
continue;
}
centArr = seg[i].split('=');
ret[centArr[0]] = centArr[1];
}
return ret;
})(),
hash: a.hash,
file: (a.pathname.match(/\/([^\/?#]+)$/i) || [, ''])[1],
path: a.pathname.replace(/^([^\/])/, '/$1'),
relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [, ''])[1],
segments: a.pathname.replace(/^\//, '').split('/'),
};
a = null;
return key ? result[key] : result;
}
H5 имеет новый URL-адрес API, который также может быстро обрабатывать ссылку, что является относительно более кратким.
var url = new URL('https://www.baidu.com/')
url.hash
...
Тип 71: Ваша онлайн-среда IDE — WebContainers, артефакт, который может запускать Node.js в браузере.
в последнейGoogle I/O
Вступительное словоstackblitz
познакомил их сNext.js
иGoogle
Работа в команде разработана онлайнIDE WebContainers
:
Несколько лет назад мы поняли, что Интернет приближается к критической точке перегиба.
WebAssembly
ПоявлениеWebAssembly
, который достаточно мощный, чтобы полностью работать в браузереNode.js
. Мы разработалиБолее быстрая, безопасная и согласованная среда разработки высокого уровня, чем локальная среда, обеспечивающая бесперебойную совместную работу над кодом без необходимости настройки локальной среды., Сегодня, два года спустя, он, наконец, родился!
Заявки на официальном сайтеStackBlitz.com
находится на этой планетеСамая быстрая и безопасная среда разработки, его логотип также является логотипом с молнией:
WebContainers
позволяет создать полныйNode.js
среда, может бытьзапуск в миллисекундах, и может достичьОдин клик онлайн и обмен ссылками. Эта среда имеетVS Code
Мощные функции редактирования, полный терминал и такие функции, как npm.. Он также работает полностью в вашем браузере, что дает некоторые ключевые преимущества:
- Быстрее, чем в локальной среде.коэффициент скорости сборки
yarn/npm
На 20% быстрее, установка пакетов может быть до 5 раз быстрее. - Поддержка отладки в браузере
Node.js
. иChrome DevTools
Бесшовная интеграция обеспечивает отладку встроенной серверной части без необходимости установки расширений. - Безопасность по умолчанию. Все выполнение кода происходит в изолированной программной среде браузера, а не удаленно.
VM
или на локальных двоичных файлах.
Опять же, эти среды не обязательно должны работать на удаленном сервере. Скорее, каждая среда полностью содержится в вашем веб-браузере. Правильно: сама среда выполнения Node.js впервые запускается внутри браузера. ты сможешьStackBlitz.com
Попробуйте сами, вот скриншот страницы, которую я сделал:
72-й класс: Как вместе стать процветающими, демократичными, цивилизованными, гармоничными, свободными и равными?
Другие люди пишут блестяще, и когда я захожу в Интернет, места, которые я нажимаю в Интернете, являются «процветающими, демократическими, цивилизованными, гармоничными, свободными и равными». Горжусь ли я?
Скопируйте следующий код в консоль для выполнения, затем начните нажимать на свою страницу.~ 😎
(function () {
var playWords = [
'富强',
'民主',
'文明',
'和谐',
'自由',
'平等',
'公正',
'法制',
'爱国',
'敬业',
'诚信',
'友善',
], // 点击展示的词库
colors = ['#ff4545', '#3eff00'], // 颜色库
wordIdx = Math.floor(Math.random() * playWords.length); // 随机取词下标
document.body.addEventListener('click', function (e) {
// 监听点击事件
if (e.target.tagName == 'A') {
// a标签
return;
}
var x = e.pageX,
y = e.pageY, // 获取点击位置
span = document.createElement('span'); // 创建展示playWords的span
span.textContent = playWords[wordIdx];
wordIdx = (wordIdx + 1) % playWords.length;
color = colors[Math.floor(Math.random() * colors.length)]; // 随机取色
span.style.cssText = [
'z-index: 9999; position: absolute; top: ',
y - 20,
'px; left: ',
x,
'px; font-weight: bold; color: ',
color,
].join('');
document.body.appendChild(span);
renderWords(span);
});
function renderWords(el) {
var i = 0,
top = parseInt(el.style.top);
var playTimer = setInterval(function () {
if (i > 180) {
clearInterval(playTimer);
el.parentNode.removeChild(el);
} else {
i += 3;
el.style.top = top - i + 'px';
el.style.opacity = (180 - i) / 180;
}
}, 16.7);
}
})();
Использованная литература:Играйте с передним концом
Эта статья была опубликована вличный блог,Добро пожаловатьКоррекция и звезда.
«Добро пожаловать для обсуждения в области комментариев, официальный представитель NuggetsПроект «Звезда раскопок»После мероприятия в комментариях будет разыграно 100 штук Наггетсов.Подробнее о лотерее читайте в статье о мероприятии».