שיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר
-
להלן סקריפט להסרת אלמנט מיד לאחר שנוצר, שימושי לכל מיני דברים... כאן זה מודגם על החתימה של מיילטראק.
כמובן שאפשר להשתמש בזה לכל מיני פעולות על האלמנט.מתבסס על CSS animations, אמור להיות יותר יעיל משימוש ב DOM (DOMMutationObserver).
מקור לליבה: https://github.com/naugtur/insertionQuery
(function() { if (window.trustedTypes && window.trustedTypes.createPolicy) { window.trustedTypes.createPolicy('default', { createHTML: (string, sink) => string }); } // insertion-query v1.0.3 (2016-01-20) https://github.com/naugtur/insertionQuery // license:MIT // Zbyszek Tenerowicz <naugtur@gmail.com> (http://naugtur.pl/) var insertionQ = (function () { "use strict"; var sequence = 100, isAnimationSupported = false, animationstring = 'animationName', keyframeprefix = '', domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), pfx = '', elm = document.createElement('div'), options = { strictlyNew: true, timeout: 20 }; if (elm.style.animationName) { isAnimationSupported = true; } if (isAnimationSupported === false) { for (var i = 0; i < domPrefixes.length; i++) { if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { pfx = domPrefixes[i]; animationstring = pfx + 'AnimationName'; keyframeprefix = '-' + pfx.toLowerCase() + '-'; isAnimationSupported = true; break; } } } function listen(selector, callback) { var styleAnimation, animationName = 'insQ_' + (sequence++); var eventHandler = function (event) { if (event.animationName === animationName || event[animationstring] === animationName) { if (!isTagged(event.target)) { callback(event.target); } } }; styleAnimation = document.createElement('style'); styleAnimation.innerHTML = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { outline: 1px solid transparent } to { outline: 0px solid transparent } }' + "\n" + selector + ' { animation-duration: 0.001s; animation-name: ' + animationName + '; ' + keyframeprefix + 'animation-duration: 0.001s; ' + keyframeprefix + 'animation-name: ' + animationName + '; ' + ' } '; document.head.appendChild(styleAnimation); var bindAnimationLater = setTimeout(function () { document.addEventListener('animationstart', eventHandler, false); document.addEventListener('MSAnimationStart', eventHandler, false); document.addEventListener('webkitAnimationStart', eventHandler, false); //event support is not consistent with DOM prefixes }, options.timeout); //starts listening later to skip elements found on startup. this might need tweaking return { destroy: function () { clearTimeout(bindAnimationLater); if (styleAnimation) { document.head.removeChild(styleAnimation); styleAnimation = null; } document.removeEventListener('animationstart', eventHandler); document.removeEventListener('MSAnimationStart', eventHandler); document.removeEventListener('webkitAnimationStart', eventHandler); } }; } function tag(el) { el.QinsQ = true; //bug in V8 causes memory leaks when weird characters are used as field names. I don't want to risk leaking DOM trees so the key is not '-+-' anymore } function isTagged(el) { return (options.strictlyNew && (el.QinsQ === true)); } function topmostUntaggedParent(el) { if (isTagged(el.parentNode) || el.nodeName === 'BODY') { return el; } else { return topmostUntaggedParent(el.parentNode); } } function tagAll(e) { tag(e); e = e.firstChild; for (; e; e = e.nextSibling) { if (e !== undefined && e.nodeType === 1) { tagAll(e); } } } //aggregates multiple insertion events into a common parent function catchInsertions(selector, callback) { var insertions = []; //throttle summary var sumUp = (function () { var to; return function () { clearTimeout(to); to = setTimeout(function () { insertions.forEach(tagAll); callback(insertions); insertions = []; }, 10); }; })(); return listen(selector, function (el) { if (isTagged(el)) { return; } tag(el); var myparent = topmostUntaggedParent(el); if (insertions.indexOf(myparent) < 0) { insertions.push(myparent); } sumUp(); }); } //insQ function var exports = function (selector) { if (isAnimationSupported && selector.match(/[^{}]/)) { if (options.strictlyNew) { tagAll(document.body); //prevents from catching things on show } return { every: function (callback) { return listen(selector, callback); }, summary: function (callback) { return catchInsertions(selector, callback); } }; } else { return false; } }; //allows overriding defaults exports.config = function (opt) { for (var o in opt) { if (opt.hasOwnProperty(o)) { options[o] = opt[o]; } } }; return exports; })(); if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { module.exports = insertionQ; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// insertionQ('.mt-signature').every(function(element){ element.parentNode.removeChild(element); }); })();
עריכה: הסקריפט תוקן.
-
-
@אדרת אמר בשיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר:
עובד עם התוסף הזה?
https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfoכמובן שזה אמור לעבוד.
תוסיף סקריפט על האתר של GMAIL, ותחליף את הפונקציה להנ"ל. -
@אדרת אמר בשיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר:
עובד עם התוסף הזה?
https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfoכמובן שזה אמור לעבוד.
תוסיף סקריפט על האתר של GMAIL, ותחליף את הפונקציה להנ"ל.@WWW אמר בשיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר:
כמובן שזה אמור לעבוד.
עובד מעולה!!!
האם יש סיכון אבטחה בהזרקת סקריפטים?
-
להלן סקריפט להסרת אלמנט מיד לאחר שנוצר, שימושי לכל מיני דברים... כאן זה מודגם על החתימה של מיילטראק.
כמובן שאפשר להשתמש בזה לכל מיני פעולות על האלמנט.מתבסס על CSS animations, אמור להיות יותר יעיל משימוש ב DOM (DOMMutationObserver).
מקור לליבה: https://github.com/naugtur/insertionQuery
(function() { if (window.trustedTypes && window.trustedTypes.createPolicy) { window.trustedTypes.createPolicy('default', { createHTML: (string, sink) => string }); } // insertion-query v1.0.3 (2016-01-20) https://github.com/naugtur/insertionQuery // license:MIT // Zbyszek Tenerowicz <naugtur@gmail.com> (http://naugtur.pl/) var insertionQ = (function () { "use strict"; var sequence = 100, isAnimationSupported = false, animationstring = 'animationName', keyframeprefix = '', domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), pfx = '', elm = document.createElement('div'), options = { strictlyNew: true, timeout: 20 }; if (elm.style.animationName) { isAnimationSupported = true; } if (isAnimationSupported === false) { for (var i = 0; i < domPrefixes.length; i++) { if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { pfx = domPrefixes[i]; animationstring = pfx + 'AnimationName'; keyframeprefix = '-' + pfx.toLowerCase() + '-'; isAnimationSupported = true; break; } } } function listen(selector, callback) { var styleAnimation, animationName = 'insQ_' + (sequence++); var eventHandler = function (event) { if (event.animationName === animationName || event[animationstring] === animationName) { if (!isTagged(event.target)) { callback(event.target); } } }; styleAnimation = document.createElement('style'); styleAnimation.innerHTML = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { outline: 1px solid transparent } to { outline: 0px solid transparent } }' + "\n" + selector + ' { animation-duration: 0.001s; animation-name: ' + animationName + '; ' + keyframeprefix + 'animation-duration: 0.001s; ' + keyframeprefix + 'animation-name: ' + animationName + '; ' + ' } '; document.head.appendChild(styleAnimation); var bindAnimationLater = setTimeout(function () { document.addEventListener('animationstart', eventHandler, false); document.addEventListener('MSAnimationStart', eventHandler, false); document.addEventListener('webkitAnimationStart', eventHandler, false); //event support is not consistent with DOM prefixes }, options.timeout); //starts listening later to skip elements found on startup. this might need tweaking return { destroy: function () { clearTimeout(bindAnimationLater); if (styleAnimation) { document.head.removeChild(styleAnimation); styleAnimation = null; } document.removeEventListener('animationstart', eventHandler); document.removeEventListener('MSAnimationStart', eventHandler); document.removeEventListener('webkitAnimationStart', eventHandler); } }; } function tag(el) { el.QinsQ = true; //bug in V8 causes memory leaks when weird characters are used as field names. I don't want to risk leaking DOM trees so the key is not '-+-' anymore } function isTagged(el) { return (options.strictlyNew && (el.QinsQ === true)); } function topmostUntaggedParent(el) { if (isTagged(el.parentNode) || el.nodeName === 'BODY') { return el; } else { return topmostUntaggedParent(el.parentNode); } } function tagAll(e) { tag(e); e = e.firstChild; for (; e; e = e.nextSibling) { if (e !== undefined && e.nodeType === 1) { tagAll(e); } } } //aggregates multiple insertion events into a common parent function catchInsertions(selector, callback) { var insertions = []; //throttle summary var sumUp = (function () { var to; return function () { clearTimeout(to); to = setTimeout(function () { insertions.forEach(tagAll); callback(insertions); insertions = []; }, 10); }; })(); return listen(selector, function (el) { if (isTagged(el)) { return; } tag(el); var myparent = topmostUntaggedParent(el); if (insertions.indexOf(myparent) < 0) { insertions.push(myparent); } sumUp(); }); } //insQ function var exports = function (selector) { if (isAnimationSupported && selector.match(/[^{}]/)) { if (options.strictlyNew) { tagAll(document.body); //prevents from catching things on show } return { every: function (callback) { return listen(selector, callback); }, summary: function (callback) { return catchInsertions(selector, callback); } }; } else { return false; } }; //allows overriding defaults exports.config = function (opt) { for (var o in opt) { if (opt.hasOwnProperty(o)) { options[o] = opt[o]; } } }; return exports; })(); if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { module.exports = insertionQ; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// insertionQ('.mt-signature').every(function(element){ element.parentNode.removeChild(element); }); })();
עריכה: הסקריפט תוקן.
-
@WWW אמר בשיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר:
מתבסס על CSS animations, אמור להיות יותר יעיל משימוש ב DOM (DOMMutationObserver).
יש לך מקור לעניין?
-
אתה מחליף את הקטע הראשון בשני.
אנו מדברים על DOMMutationObserver, שעליו הוא כותב שהוא פחות נתמך בכל הדפדפנים, וזה כבר לא רלוונטי עכ"פ בודאי שלא לך. -
@dovid טוב, מודה, כדבריך.
אבל התחביר הרבה יותר קל עם הספרייה שלו.
אני לא כ"כ מבין בזה, אבל בDOMMutationObserver זה לא מאזין לכל האלמנטים המתווספים?
כי בזה אני חושב שזה מאזין רק לסלקטור הזה.
-
@WWW אתה זה שצודק, לא חשבתי על זה. ייתכן מאוד שאכן MutationObserver פחות יעיל במקרה שיודעים את הclass ולא מדובר בהרבה מופעים.
@dovid אמר בשיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר:
@WWW אתה זה שצודק, לא חשבתי על זה. ייתכן מאוד שאכן MutationObserver פחות יעיל במקרה שיודעים את הclass ולא מדובר בהרבה מופעים.
אני חושב שזה הפרש ענק.
בג'מייל לדוגמה, חיפשתי משהו שיעבוד רק על זה, כי אם לא, זה ממש בזבוז.
-
@dovid אמר בשיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר:
@WWW אתה זה שצודק, לא חשבתי על זה. ייתכן מאוד שאכן MutationObserver פחות יעיל במקרה שיודעים את הclass ולא מדובר בהרבה מופעים.
אני חושב שזה הפרש ענק.
בג'מייל לדוגמה, חיפשתי משהו שיעבוד רק על זה, כי אם לא, זה ממש בזבוז.
-
@WWW לא חושב. לדעתי זה לא הפרש ענק ויש מצב שאפילו השני יעיל יותר.
אתה רוצה לבדוק? אבל בשביל זה צריך שתיתן לי את מלוא האלמנט (תעתיק ושים פה), כי לפי סלקטור זה יהיה בדיקה לא הוגנת. -
@WWW לא חושב. לדעתי זה לא הפרש ענק ויש מצב שאפילו השני יעיל יותר.
אתה רוצה לבדוק? אבל בשביל זה צריך שתיתן לי את מלוא האלמנט (תעתיק ושים פה), כי לפי סלקטור זה יהיה בדיקה לא הוגנת.@dovid
לזה התכוונת:<div class="mt-signature" contenteditable="false" g_editable="false"> <table border="0" cellpadding="8" cellspacing="0" contenteditable="false" g_editable="false" data-signature-template="senderNotified" style="user-select: none;"> <tbody><tr> <td> <a href="https://mailtrack.io?utm_source=gmail&utm_medium=signature&utm_campaign=signaturevirality5&" class="mt-no-pointer-events" style="text-decoration:none;" data-mt-detrack-inspected="true"> <img src="https://s3.amazonaws.com/mailtrack-signature/sender_notified.gif" alt="Mailtrack" class="mt-no-pointer-events" width="32" height="32" g_editable="false"> </a> </td> <td> <span style="color:#777">Sender notified by</span> <br> <a href="https://mailtrack.io?utm_source=gmail&utm_medium=signature&utm_campaign=signaturevirality5&" class="mt-install mt-no-pointer-events" style="color:#4374F7" data-mt-detrack-inspected="true">Mailtrack</a> <span style="color: transparent; font-size: 0; user-select: none">11.09.19, 23:13:52</span> </td> <td> <div class="mt-remove-signature-button" g_editable="false"> <a href="#" style="text-decoration:none;" class="mt-remove" data-mt-detrack-inspected="true"><em>×</em><span>REMOVE</span></a> </div> </td> </tr> </tbody></table> </div>
?
-
@dovid אמר בשיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר:
אתה רוצה לבדוק? אבל בשביל זה צריך שתיתן לי את מלוא האלמנט (תעתיק ושים פה), כי לפי סלקטור זה יהיה בדיקה לא הוגנת.
לא הבנתי.
מה הכוונה?const config = { attributes: false, childList: true, subtree: true }; const observer = new MutationObserver( function(mutationsList) { for(let mutation of mutationsList) for(let el of mutation.addedNodes) if(el.tagName == "DIV" && el.getAttribute("class") == "mt-signature") el.remove() } ); observer.observe(document, config);
-
const config = { attributes: false, childList: true, subtree: true }; const observer = new MutationObserver( function(mutationsList) { for(let mutation of mutationsList) for(let el of mutation.addedNodes) if(el.tagName == "DIV" && el.getAttribute("class") == "mt-signature") el.remove() } ); observer.observe(document, config);
-
@dovid נו... זה יותר יעיל?
קודם כל אני רואה שאני צודק שזה בודק את כל האלמנטים המתווספים.
אז זה כבר תלוי כמה אלמנטים מתווספים בדף.אני חושב שבג'ימייל יחסית הרבה.
-
@WWW כן זה יכול להיות יעיל יותר. כמו שיכול להיות שלולאה של אלפי פעמים 1+1 מהירה מפעם אחת console.log.
-
@dovid אמר בשיתוף: סקריפט להסרת אלמנט מיד לאחר שנוצר:
כמו שיכול להיות שלולאה של אלפי פעמים 1+1 מהירה מפעם אחת console.log.
התכוונת הפוך?