17 résultats taggé js

Mastodon share & DM with inline javascript

<!-- Share -->
<a href="javascript:var server=prompt('Instance ?').replace(/(http(s)?:\/\/)/g,'').replace(/\/$/,'');window.location.href=`https://${server}/share?visibility=public&text=%20via%20@yomli@mastodon.xyz%20%3A%20&url={racine_du_site}{lien_permalink}`;void 0;">Share</a>
<!-- Direct message -->
<a href="javascript:var server=prompt('Instance ?').replace(/(http(s)?:\/\/)/g,'').replace(/\/$/,'');window.location.href=`https://${server}/share?visibility=direct&text=@yomli@mastodon.xyz%20%3A%20&url={racine_du_site}{lien_permalink}`;void 0;">DM</a>

Send a direct message on Mastodon with a one-click link

<a href="javascript:var server=prompt('Instance ?').replace(/(http(s)?:\/\/)/g,'').replace(/\/$/,'');window.location.href=`https://${server}/?visibility=direct&text=@yomli@mastodon.xyz`;void 0;">Direct</a>

Javascript - Efficiently replace all accented characters in a string

const strip_accents = (str) => str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');

Two things are happening here:

  1. normalize()ing to NFD Unicode normal form decomposes combined graphemes into the combination of simple ones. The è of Crème ends up expressed as e + ̀.
  2. Using a regex character class to match the U+0300 → U+036F range, it is now trivial to globally get rid of the diacritics, which the Unicode standard conveniently groups as the Combining Diacritical Marks Unicode block.

Same with another syntax:

str.normalize('NFKD').replace(/\p{Diacritic}/gu, '');

Universal code syntax hightlighter

Un syntax highlighter minimal (encore plus léger et themable que microlight).

const hightlight = (code) => code
  // operators
.replaceAll(/\b(var|function|typeof|new|return|if|for|in|while|break|do|continue|switch|case|try|catch)([^a-z0-9\$_])/g,
  '<span class="c-keyword">$1</span>$2')
  // types
.replaceAll(/\b(RegExp|Boolean|Number|String|Array|Object|Function|this|true|false|NaN|undefined|null|Infinity)([^a-z0-9\$_])/g,
  '<span class="c-type">$1</span>$2')
  // comments
  .replaceAll(/(\/\*[^]*?\*\/|(\/\/)[^\n\r]+)/gim,'<span class="c-comment">$1</span>')
  // strings
  .replaceAll(/('.*?')/g,'<span class="c-string">$1</span>')
  // function & variables names (with link)
  .replaceAll(/([a-z\_\$][a-z0-9_]*)(\s?([\(\)\[\];]|[=+\-\*,<]\s)|\s>)/gi,'<a id="var-$1" href="#var-$1" class="c-variable">$1</a>$2')
  // braces
  .replaceAll(/(\{|\}|\]|\[|\|)/gi,'<span class="c-punctuation">$1</span>')
  // numbers
  .replaceAll(/(0x[0-9a-f]*|\b(\d*\.)?([\d]+(e-?[0-9]*)?)\b)/gi,'<span class="c-atom">$1</span>')//|(0x[0-9abcdefx]*)
  // tabulations (2 spaces)
  //.replace(/\t/g,'  ')

document.querySelectorAll('code')
    .forEach((code) => {
        code.innerHTML=hightlight(code.innerText)
    });
code .c-type {font-weight:700}
code .c-variable, .c-type {color: #228}
code .c-keyword {color: #708}
code .c-string {color:#a22}
code .c-punctuation {color:#666}
code .c-atom {color:#281}
code .c-comment, .c-comment * {color: #A70!important}
code *:target{background-color:#ff6}

Mais en quelques minutes d'utilisation, on voit qu'il souffre quelques problèmes. On peut donc l'améliorer rapidement en :

const hightlight = (code) => code
    .replaceAll(/(<)/g,'<span>$1</span>') // Mandatory, else innerHTML comments them with <!-- -->  
    // Strings
    .replaceAll(/('.*?'|".*?")/g,'<span class="c-string">$1</span>')
    // Operators
    .replaceAll(/\b(var|const|let|function|typeof|new|return|if|for|foreach|in|while|break|do|continue|switch|case|try|catch)([^a-z0-9\$_])/g,
        '<span class="c-operator">$1</span>$2')
    // Types
    .replaceAll(/\b(RegExp|Boolean|Number|String|Array|Object|Function|this|true|false|NaN|undefined|null|Infinity)([^a-z0-9\$_])/g,
        '<span class="c-type">$1</span>$2')
    // Comments
    .replaceAll(/(\/\*[^]*?\*\/|(?<!\:)(\/\/)[^\n\r]+|<span><<\/span>\!\-\-[^]*?\-\->)/gim,'<span class="c-comment">$1</span>')
    // Variables & Function names
    .replaceAll(/([a-z\_\$][a-z0-9_]*)(\s?([\(\)\[\];]|[=+\-\*,<]\s)|\s>)/gi,'<a id="var-$1" href="#var-$1" class="c-variable">$1</a>$2')
    // Braces
    .replaceAll(/(\{|\}|\]|\[|\|)/gi,'<span class="c-punctuation">$1</span>')
    // Numbers
    .replaceAll(/(0x[0-9a-f]*|\b(\d*\.)?([\d]+(e-?[0-9]*)?)\b)/gi,'<span class="c-atom">$1</span>')//|(0x[0-9abcdefx]*)
    // Tabs (2 spaces)
    //.replace(/\t/g,'  ')

document.querySelectorAll('pre > code')
                .forEach((code) => {
                    code.innerHTML=hightlight(code.textContent)
                });
code .c-type {font-weight:700}
code .c-variable, .c-type {color: #228}
code .c-operator {color: #708}
code .c-string {color:#a22}
code .c-punctuation {color:#666}
code .c-atom {color:#281}
code .c-comment, .c-comment * {color: #A70!important}
code *:target{background-color:#ff6}
/* Tomorrow Night theme */
@media screen and (prefers-color-scheme: dark) {
    code .c-type {color:#DB9455;font-style:700}
    code .c-operator {color: #B194B4}
    code .c-variable {color: #83A1C1}
    code .c-string {color:#D7C467}
    code .c-atom {color: #B1BE59}
    code .c-punctuation {color:inherit}
    code .c-comment, .c-comment * {color: #999!important;opacity:.5}
}

Modifications :

  • thème sombre automatique
  • support des langages à markup et PHP
  • ajout de const et let pour Javascript, foreach pour PHP
  • les commentaires ne se font plus dans les strings
  • les commentaires ne se font plus sur les URI (//)
  • appel via textContent et non le plus lent et moins fiable innerText (voir http://www.kellegous.com/j/2013/02/27/innertext-vs-textcontent/ mais pour résumer : innerText n'était pas standard, il ne s'applique qu'à des HTMLElement et non des Node, il ne retourne que le contenu visible, change les espaces et demande des infos de layout qui font qu'il est de 12 à 300 fois moins rapide)

Use $ & $$ Instead of document.querySelector/All in JavaScript without jQuery

From comment below:

const $ = (q, d = document) => 
  /#\S+$/.test(q)                       // check if query asks for ID
  ? d.querySelector.bind(d)(q)          // if so, return one element
  : [...d.querySelectorAll.bind(d)(q)]  // else, return all elements in an array.

Usage : $('#main').innerHTML

Invidio.us bookmarklet

Redirects a youtube page to an invidio.us one. Copy and paste this into the url field of a browser bookmark.

javascript:(window.location.href.includes("www.youtube"))?location.href=window.location.href.replace("www.youtube.com","www.invidio.us"):console.log('not a youtube page')

Chargement dynamique d'un Javascript en fonction de l'existence d'une classe dans le DOM

function isAnyClassOutThere(class,tag){
   // On transforme le string passé en paramètre en une expression régulière
   //(sans cela, test() ne retournera rien)
   var regExpClass = new RegExp(class);

   // S'il n'y avait pas de tag passé en paramètre, on considère que l'on regarde
   // tous les tags
   var tag = tag || "all";
   var elm = (tag == "all") ? document.all : document.getElementsByTagName(tag);

   var result = false;

   // Pour chaque élément que l'on a récupéré dans elm
   for(var i=0; i < elm.length; i++){

      // On test la correspondance
      if(regExpClass.test(elm[i].className)){
         result = true;

         // On sort de la boucle (pas très joli, mais évite de faire un return 
         // dans une boucle)
         i+=elm.length;
       }
   }

return result;
}
function loadJS(url){
   // On crée un élément script
   var elm=document.createElement("script");

   // On lui attribue une url
   elm.setAttribute("src", url);

   // On renseigne le type
   elm.setAttribute("type", "text/javascript");

   // Enfin, on l'ajoute en temps qu'enfant de l'élément head
   document.getElementsByTagName("head")[0].appendChild(elm);
}
window.onload=function(){
   if(isAnyClassOutThere("galerie", "ul")){
      loadJS("http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
      loadJS("./gallery.js");
   }
}

Oubliez votre lien d'administration avec Javascript !

Appuyer 3 fois sur Entrée mènera au lien d'administration :

function keyboardAuth(redirection) {
    var enterCount = 0;

    //$(document).keypress(function(event){
    document.addEventListener("keypress", function(event) {
        var keycode = (event.keyCode ? event.keyCode : event.which);
        if(keycode == '13'){
            enterCount++;
            if(enterCount >= 3){
                enterCount = 0;
                window.location = redirection;
            }
        setTimeout(function(){ enterCount = 0; },2000);
        }

    });
}

Scrolling doux vers une ancre

$('a[href*=#]').on('click', function(event){
event.preventDefault();
$('html,body').animate({scrollTop:$(this.hash).offset().top}, 700); });

Un lien « Retour en haut » dynamique

<div class="relative">
    <div class="toTop">
        <a href="#top" title="Retour en haut">
            Retour en haut
        </a>
    </div>
</div>
<footer id="footer">
…
</footer>
.relative {
    position:relative;
}

.toTop {
    display:none;
    position:fixed;
    right:20px;
    bottom:20px;
    z-index:1000;
}
function toTop(element,footer){
    var scroll = $(window).scrollTop();
    var maxScroll = $(window).height() * 0.4;

    if(scroll > maxScroll)
        $(element).show();
    else
        $(element).hide();

    if($(element).offset().top + $(element).height() >= $(footer).offset().top - 10)
        $(element).css('position', 'absolute');
    if($(document).scrollTop() + window.innerHeight < $(footer).offset().top)
        $(element).css('position', 'fixed');
}   

$(window).scroll(function() {
    toTop('.toTop',"#footer");
});

$(window).resize(function() {
    toTop('.toTop',"#footer");
});

Effet parallax avec jQuery

/*
* Adds a parallax effect to a background image
* (position:fixed;no-repeat;background-size:42%;)
*
* element : the element with a background image
* percent : percent of the background-size (0.42)
* height : height of the background image
* width : width of the background image
* factor : factor of speed (the lower the faster)
* reference : the element bottom-placed to get the total
*             height of the page
*
* author : Guillaume Litaudon  <guillaume.litaudon@gmail.com>
*/

function parallax(element,percent,height,width,factor,reference){
    var winWidth = $(window).width();
    var winHeight = $(window).height();

    var sizePercent = percent == 1 ? height : ((winWidth*percent)/width)*height;

    var maxScroll = -(sizePercent - winHeight);
    var speed = factor*($(reference).offset().top / winHeight);
    var yPos = -($(window).scrollTop() / speed);
    yPos = yPos >= 0 ? 0 : yPos;
    yPos = yPos >= maxScroll ? yPos : maxScroll;
    var coords = '0 '+ yPos + 'px';

    $(element).css({ backgroundPosition: coords });
}

function goGoParallaxEffect(){
    /* La taille dépend de si l'on est en-dessous
    * de pictureWidth ou non
    */
    var pictureHeight = 1080;
    var pictureWidth = 388;

    if($(window).width() > pictureWidth)
        parallax('#page',0.42,pictureWidth,pictureHeight,5,footer);
    else
        parallax('#page',1,pictureWidth,pictureHeight,5,footer);
}

$(window).scroll(function() {
    goGoParallaxEffect();
});

$(window).resize(function() {
    goGoParallaxEffect();
}); 

The Perfect URL Regular Expression

%^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d{1,3}(?:\.\d{1,3}){3}|(?:(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)(?:\.(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)*(?:\.[a-z\x{00a1}-\x{ffff}]{2,6}))(?::\d+)?(?:[^\s]*)?$%iu
/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/
<‍input type="url" /‍>
SELECT field FROM table 
WHERE field 
REGEXP "^(https?://|www\\.)[\.A-Za-z0-9\-]+\\.[a-zA-Z]{2,4}

Snippets for Vanilla JS Coding

When coding in VanillaJS, I usually create shortcuts:

const D = document
const $ = D.querySelector.bind(D)
const $$ = (selector, elem = D) => elem.querySelectorAll(selector)

With that dollar functions, you can already use a syntax that is similar to jQuery:

$('#button').onclick = () => {
alert('You clicked me!')
}
$$('.button').map(btn => {
btn.style.backgroundColor = 'red'
})

When it comes to event handling, having an on method can be useful:

Array.prototype.on = function(type, listener, options) {
this.map(el => {
if (el instanceof Element) {
el.addEventListener(type, listener, options)
}
})
return this // for chaining
}
$$('.button').on('click', e => {
const btn = e.target
alert('You clicked ' + btn.textContent)
}).on('mouseover', e => {
const btn = e.target
btn.style.backgroundColor = 'red'
}).on('mouseout', e => {
const btn = e.target
btn.style.backgroundColor = 'blue'
})

Autorun Javascript

On page loaded:

function autorun() {
    // Your code here
}
if (window.addEventListener) window.addEventListener("load", autorun, false);
else if (window.attachEvent) window.attachEvent("onload", autorun);
else window.onload = autorun;

On DOM ready:

if (document.addEventListener) document.addEventListener("DOMContentLoaded", autorun, false);
else if (document.attachEvent) document.attachEvent("onreadystatechange", autorun);
else window.onload = autorun;

Export JSON to file using javascript

// Set export button
var exportButton = document.getElementById('button-export');

var dataStr = JSON.stringify(localLinks);
var dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
var exportFileDefaultName = 'data.json';

exportButton.setAttribute('href', dataUri);
exportButton.setAttribute('download', exportFileDefaultName);

localStorage javascript

;(function (window, document, undefined) {
    // Feature test for localStorage
    if(!('localStorage' in window)) return;
    // Get links
    var localLinks = localStorage.getItem('go--links');
    if (!localLinks) return;
    // The action
    var userButton = document.getElementById('button-user');
    userButton.classList.remove('hidden');
})(window, document);   

Three methods:

localStorage.setItem('global--night-mode', true);
localStorage.getItem('global--night-mode');
localStorage.removeItem('global--night-mode');

localStorage only supports strings. Use JSON.stringify() and JSON.parse().

var names = [];
names[0] = prompt("New member name?");
localStorage.setItem("names", JSON.stringify(names));

//...
var storedNames = JSON.parse(localStorage.getItem("names"));

Copy to the clipboard in JS

   // Code from http://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
    function copyTextToClipboard(text) {
        var textArea              = document.createElement("textarea");
        textArea.style.position   = 'fixed';
        textArea.style.top        = 0;
        textArea.style.left       = 0;
        textArea.style.width      = '2em';
        textArea.style.height     = '2em';
        textArea.style.padding    = 0;
        textArea.style.border     = 'none';
        textArea.style.outline    = 'none';
        textArea.style.boxShadow  = 'none';
        textArea.style.background = 'transparent';
        textArea.value            = text;

        document.body.appendChild(textArea);
        textArea.select();

        try {
          var successful = document.execCommand('copy');
          var msg = successful ? 'successful' : 'unsuccessful';
          console.log('Copying text command was ' + msg);
        } catch (err) {
          alert('La copie dans le presse-papier ne fonctionne pas sur ce navigateur.');
        }

        document.body.removeChild(textArea);
        return successful;
    }

Then, there is two ways:

onClick and input[type=text]

Your input:

<input type="text" value="foobar" onclick="copyThis('<?php echo $str; ?>', this); select()" />

Note that select() alone select all the content of the input text but is optional. Then:

function copyThis(text, item) {
        var success = copyTextToClipboard(text);
        if(success) {
            item.classList.add('copied');
            window.setTimeout(function(){
                item.classList.remove('copied');
            }, 750);
        }
    }

addEventListener

var element = document.getElementById('clipboard');
element.classList.remove('hidden'); // element is only showed when JS is available
element.addEventListener('click', function(e){
   e.preventDefault(); // Cancel the native event
   e.stopPropagation();// Don't bubble/capture the event
    success = copyTextToClipboard('<?php echo $str; ?>');
        if(success) {
            element.classList.add('copied');
            window.setTimeout(function(){
                element.classList.remove('copied');
            }, 750);
        }
 }, false);

The first one seems more versatile when using PHP, since you don't have to write the string inside a function at the bottom of a page/on another document. Of course we could use a data attribute ton store the string, and get used by the Event Listener.