1,315 Matching Annotations
  1. Dec 2022
  2. Nov 2022
    1. js const { generateFragment } = await import('https://unpkg.com/text-fragments-polyfill/dist/fragment-generation-utils.js'); const result = generateFragment(window.getSelection()); if (result.status === 0) { let url = `${location.origin}${location.pathname}${location.search}`; const fragment = result.fragment; const prefix = fragment.prefix ? `${encodeURIComponent(fragment.prefix)}-,` : ''; const suffix = fragment.suffix ? `,-${encodeURIComponent(fragment.suffix)}` : ''; const textStart = encodeURIComponent(fragment.textStart); const textEnd = fragment.textEnd ? `,${encodeURIComponent(fragment.textEnd)}` : ''; url += `#:~:text=${prefix}${textStart}${textEnd}${suffix}`; console.log(url); }

  3. Oct 2022
  4. Sep 2022
    1. It works because in JavaScript, true && expression always evaluates to expression, and false && expression always evaluates to false. Therefore, if the condition is true, the element right after && will appear in the output. If it is false, React will ignore and skip it.

      Good example for the {var > 0 %% } type of expression.

    2. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.

      Remember to BIND for Class Components or just USE arrow functions instead.

    3. You can put any valid JavaScript expression inside the curly braces in JSX. For example, 2 + 2, user.firstName, or formatName(user) are all valid JavaScript expressions.

      ANY JS!

  5. Aug 2022
    1. ```js const today = new Date(); today.setUTCHours(0,0,0,0); console.log("Today: ", today);

      const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); yesterday.setUTCHours(0,0,0,0); console.log("Yesterday: ", yesterday); ```

    1. ```js // Time of writing article = 14th January, 2022

      // ✅ Set date to Nearest Midnight in the Past const d1 = new Date(); d1.setHours(0, 0, 0, 0);

      console.log(d1); // Fri Jan 14 2022 00:00:00

      // ✅ Set date to Nearest Midnight in the future const d2 = new Date(); d2.setHours(24, 0, 0, 0);

      console.log(d2); // Sat Jan 15 2022 00:00:00 ```

    1. As other answers state, it's perfectly possible, because arrays in JavaScript are just objects. However, there is still the a question of whether it's a good idea or not. That's a "coding style" question, so it's hard to say objectively, but Douglas Crockford doesn't have a problem with it (at least in some cases). In JavaScript: The Good Parts, he actually uses the example of adding a "total" method to an array.

      Because an array is really an object, we can add methods directly to an individual array:

      ```js // Give the data array a total function

      data.total = function () {
          return this.reduce(add, 0);
      };
      
      total = data.total();    // total is 108
      

      ``` Since the string 'total' is not an integer, adding a total property to an array does not change its length.

    1. ```js let array = [1, 2, 3, 4, 5];

      for(let i = array.length - 1; i >= 1; i--) { let j = Math.floor(Math.random() * (i + 1)); // 0 <= j <= i let temp = array[j]; array[j] = array[i]; array[i] = temp; } ```

    1. The Widget API allows you to externally control the widget that is embedded on your website through javascript. You set the width and height of the widget to 0 and it hides the widget. I tinkered with this on codepen this week and I am pleased that I now have a working playlist ready to be utilized on my website.

      https://codepen.io/mdcrowcodes/pen/eYEMyzY

      ```js var iframeElement = document.querySelector('iframe'); var iframeElementID = iframeElement.id; var widget = SC.Widget(iframeElement); var x = document.getElementById("play");

      widget.bind(SC.Widget.Events.FINISH,function(){ widget.getCurrentSound(function(currentSound) { document.getElementById("currentTrack").innerHTML = currentSound.title; }); });

      function play(){<br /> if (x.innerHTML === "▶") { x.innerHTML = "||"; } else {x.innerHTML = "▶"; } widget.toggle(); };

      function next(){ x.innerHTML = "||"; widget.next(); widget.seekTo(0); widget.getCurrentSound(function(currentSound) { document.getElementById("currentTrack").innerHTML = currentSound.title; }); };

      function prev(){ x.innerHTML = "||"; widget.prev(); widget.seekTo(0); widget.getCurrentSound(function(currentSound) { document.getElementById("currentTrack").innerHTML = currentSound.title; }); };

      widget.bind(SC.Widget.Events.READY, function() { widget.getCurrentSound(function(currentSound) { document.getElementById("currentTrack").innerHTML = currentSound.title;

      widget.getSounds(function(tracks){ for (var i in tracks) {

         $('#tracklist').append("<li class='track-item' id='" + i + "'" + ">" + tracks[i].title + "</li>");
        }
      
       $(".track-item").click(function(){
         var s = this.id
         widget.seekTo(0);
      widget.skip(s);       
        x.innerHTML = "||" ;     widget.getCurrentSound(function(currentSound) {
      

      document.getElementById("currentTrack").innerHTML = currentSound.title; });

      });

      });

      }); }); ```

    1. ```js (function () { var html = document.documentElement.innerHTML;

      /** 
       * the iframe's onload event is triggered twice: once when appending it to the document, 
       * and once when the form finishes submitting and the new URL is loaded 
       */
      var loaded = 0;
      
      var iframe = document.createElement('iframe');
      
          // unique name, to make sure we don't create any conflicts with other elements on the page
          iframe.name = 'bookmarklet-' + Math.floor((Math.random() * 10000) + 1);
          iframe.style.display = 'none';
      
          iframe.onload = function () {
              // remove the iframe from the document on the second firing of the onload event
              if (++loaded == 1) {
                  return;
              }
      
              // you can also alert('Done!') here :)
              document.body.removeChild(iframe);
          };
      
      var form = document.createElement('form');
          form.method = "POST";
          form.action = "http://requestb.in/sbnc0lsb?nocache=" + Math.random();
          form.target = iframe.name;
      
      var textarea = document.createElement('textarea');
          textarea.name = 'source';
          textarea.value = html;
      
      form.appendChild(textarea);
      iframe.appendChild(form);
      
      document.body.appendChild(iframe);
      
      form.submit();
      

      })(); ```

    1. The main difference between these two syntaxes is that pattern using slashes /.../ does not allow for expressions to be inserted (like string template literals with ${...}). They are fully static

      This is the main difference between creating a regular expression by using slashes /<here your reg exp>/ and creating a new instance of RegExp() class. You cannot use literal template ${varSubstitution}

    1. ```js // Fetch and return the promise with the abort controller as controller property function fetchWithController(input, init) { // create the controller let controller = new AbortController() // use the signal to hookup the controller to the fetch request let signal = controller.signal // extend arguments init = Object.assign({signal}, init) // call the fetch request let promise = fetch(input, init) // attach the controller promise.controller = controller return promise }

      // and then replace a normal fetch with

      let promise = fetchWithController('/') promise.controller.abort() ```

    1. Sanitizing iframes

      ```html

      <iframe id="webpage"></iframe>

      <br/> <button onclick="sanitize()">Sanitize</button>

      <script> function sanitize() { // Create a sanitizer object with the default config const sanitizer = new Sanitizer(); // Find the iframe node const iframe = document.getElementById('webpage'); // Sanitize the iframe's document node const sanitizedFrameNodes = sanitizer.sanitize(iframe.contentWindow.document); iframe.replaceChildren(sanitizeFrameNodes); } </script>

      ```

    1. The setHTML() method of the Element interface is used to parse and sanitize a string of HTML and then insert it into the DOM as a subtree of the element. It should be used instead of Element.innerHTML for inserting untrusted strings of HTML into an element.

      ```js const unsanitized_string = "abc <script>alert(1)<" + "/script> def"; // Unsanitized string of HTML const sanitizer1 = new Sanitizer(); // Default sanitizer;

      // Get the Element with id "target" and set it with the sanitized string. document.getElementById("target").setHTML(unsanitized_string, {sanitizer: sanitizer1});

      // Result (as a string): "abc def" ```

    1. js function transclude(elementId) { var clone = document.getElementById(elementId).cloneNode(true), placeholder; clone.id = null; document.write('<br id="__placeholder__">'); placeholder = document.getElementById('__placeholder__'); placeholder.parentNode.insertBefore(clone, placeholder); placeholder.parentNode.removeChild(placeholder); return transclude; }

      ```html

      This is paragraph 1.

      This is paragraph 2.

      This is paragraph 3. It should contain paragraphs 1 and 2. <script>transclude("p1")("p2")</script>

      ```

    1. ```js / Adapted from: https://github.com/openannotation/annotator/blob/v1.2.x/src/plugin/document.coffee Annotator v1.2.10 https://github.com/openannotation/annotator Copyright 2015, the Annotator project contributors. Dual licensed under the MIT and GPLv3 licenses. https://github.com/openannotation/annotator/blob/master/LICENSE /

      /* * nb. The DocumentMetadata type is renamed to avoid a conflict with the * DocumentMetadata class below. * * @typedef {import('../../types/annotator').DocumentMetadata} Metadata /

      import { normalizeURI } from '../util/url';

      /* * @typedef Link * @prop {string} link.href * @prop {string} [link.rel] * @prop {string} [link.type] /

      /* * Extension of the Metadata type with non-optional fields for dc, eprints etc. * * @typedef HTMLDocumentMetadata * @prop {string} title * @prop {Link[]} link * @prop {Record<string, string[]>} dc * @prop {Record<string, string[]>} eprints * @prop {Record<string, string[]>} facebook * @prop {Record<string, string[]>} highwire * @prop {Record<string, string[]>} prism * @prop {Record<string, string[]>} twitter * @prop {string} [favicon] * @prop {string} [documentFingerprint] /

      / * HTMLMetadata reads metadata/links from the current HTML document. */ export class HTMLMetadata { / * @param {object} [options] * @param {Document} [options.document] */ constructor(options = {}) { this.document = options.document || document; }

      /* * Returns the primary URI for the document being annotated * * @return {string} / uri() { let uri = decodeURIComponent(this._getDocumentHref());

      // Use the `link[rel=canonical]` element's href as the URL if present.
      const links = this._getLinks();
      for (let link of links) {
        if (link.rel === 'canonical') {
          uri = link.href;
        }
      }
      
      return uri;
      

      }

      / * Return metadata for the current page. * * @return {HTMLDocumentMetadata} */ getDocumentMetadata() { / @type {HTMLDocumentMetadata} */ const metadata = { title: document.title, link: [],

        dc: this._getMetaTags('name', 'dc.'),
        eprints: this._getMetaTags('name', 'eprints.'),
        facebook: this._getMetaTags('property', 'og:'),
        highwire: this._getMetaTags('name', 'citation_'),
        prism: this._getMetaTags('name', 'prism.'),
        twitter: this._getMetaTags('name', 'twitter:'),
      };
      
      const favicon = this._getFavicon();
      if (favicon) {
        metadata.favicon = favicon;
      }
      
      metadata.title = this._getTitle(metadata);
      metadata.link = this._getLinks(metadata);
      
      const dcLink = metadata.link.find(link => link.href.startsWith('urn:x-dc'));
      if (dcLink) {
        metadata.documentFingerprint = dcLink.href;
      }
      
      return metadata;
      

      }

      / * Return an array of all the content values of <meta> tags on the page * where the value of the attribute begins with <prefix>. * * @param {string} attribute * @param {string} prefix - it is interpreted as a regex * @return {Record<string,string[]>} */ _getMetaTags(attribute, prefix) { / @type {Record<string,string[]>} */ const tags = {}; for (let meta of Array.from(this.document.querySelectorAll('meta'))) { const name = meta.getAttribute(attribute); const { content } = meta; if (name && content) { const match = name.match(RegExp(^${prefix}(.+)$, 'i')); if (match) { const key = match[1].toLowerCase(); if (tags[key]) { tags[key].push(content); } else { tags[key] = [content]; } } } } return tags; }

      /* @param {HTMLDocumentMetadata} metadata / _getTitle(metadata) { if (metadata.highwire.title) { return metadata.highwire.title[0]; } else if (metadata.eprints.title) { return metadata.eprints.title[0]; } else if (metadata.prism.title) { return metadata.prism.title[0]; } else if (metadata.facebook.title) { return metadata.facebook.title[0]; } else if (metadata.twitter.title) { return metadata.twitter.title[0]; } else if (metadata.dc.title) { return metadata.dc.title[0]; } else { return this.document.title; } }

      / * Get document URIs from <link> and <meta> elements on the page. * * @param {Pick<HTMLDocumentMetadata, 'highwire'|'dc'>} [metadata] - * Dublin Core and Highwire metadata parsed from <meta> tags. * @return {Link[]} */ _getLinks(metadata = { dc: {}, highwire: {} }) { / @type {Link[]} */ const links = [{ href: this._getDocumentHref() }];

      // Extract links from `<link>` tags with certain `rel` values.
      const linkElements = Array.from(this.document.querySelectorAll('link'));
      for (let link of linkElements) {
        if (
          !['alternate', 'canonical', 'bookmark', 'shortlink'].includes(link.rel)
        ) {
          continue;
        }
      
        if (link.rel === 'alternate') {
          // Ignore RSS feed links.
          if (link.type && link.type.match(/^application\/(rss|atom)\+xml/)) {
            continue;
          }
          // Ignore alternate languages.
          if (link.hreflang) {
            continue;
          }
        }
      
        try {
          const href = this._absoluteUrl(link.href);
          links.push({ href, rel: link.rel, type: link.type });
        } catch (e) {
          // Ignore URIs which cannot be parsed.
        }
      }
      
      // Look for links in scholar metadata
      for (let name of Object.keys(metadata.highwire)) {
        const values = metadata.highwire[name];
        if (name === 'pdf_url') {
          for (let url of values) {
            try {
              links.push({
                href: this._absoluteUrl(url),
                type: 'application/pdf',
              });
            } catch (e) {
              // Ignore URIs which cannot be parsed.
            }
          }
        }
      
        // Kind of a hack to express DOI identifiers as links but it's a
        // convenient place to look them up later, and somewhat sane since
        // they don't have a type.
        if (name === 'doi') {
          for (let doi of values) {
            if (doi.slice(0, 4) !== 'doi:') {
              doi = `doi:${doi}`;
            }
            links.push({ href: doi });
          }
        }
      }
      
      // Look for links in Dublin Core data
      for (let name of Object.keys(metadata.dc)) {
        const values = metadata.dc[name];
        if (name === 'identifier') {
          for (let id of values) {
            if (id.slice(0, 4) === 'doi:') {
              links.push({ href: id });
            }
          }
        }
      }
      
      // Look for a link to identify the resource in Dublin Core metadata
      const dcRelationValues = metadata.dc['relation.ispartof'];
      const dcIdentifierValues = metadata.dc.identifier;
      if (dcRelationValues && dcIdentifierValues) {
        const dcUrnRelationComponent =
          dcRelationValues[dcRelationValues.length - 1];
        const dcUrnIdentifierComponent =
          dcIdentifierValues[dcIdentifierValues.length - 1];
        const dcUrn =
          'urn:x-dc:' +
          encodeURIComponent(dcUrnRelationComponent) +
          '/' +
          encodeURIComponent(dcUrnIdentifierComponent);
        links.push({ href: dcUrn });
      }
      
      return links;
      

      }

      _getFavicon() { let favicon = null; for (let link of Array.from(this.document.querySelectorAll('link'))) { if (['shortcut icon', 'icon'].includes(link.rel)) { try { favicon = this._absoluteUrl(link.href); } catch (e) { // Ignore URIs which cannot be parsed. } } } return favicon; }

      /* * Convert a possibly relative URI to an absolute one. This will throw an * exception if the URL cannot be parsed. * * @param {string} url / _absoluteUrl(url) { return normalizeURI(url, this.document.baseURI); }

      // Get the true URI record when it's masked via a different protocol. // This happens when an href is set with a uri using the 'blob:' protocol // but the document can set a different uri through a <base> tag. _getDocumentHref() { const { href } = this.document.location; const allowedSchemes = ['http:', 'https:', 'file:'];

      // Use the current document location if it has a recognized scheme.
      const scheme = new URL(href).protocol;
      if (allowedSchemes.includes(scheme)) {
        return href;
      }
      
      // Otherwise, try using the location specified by the <base> element.
      if (
        this.document.baseURI &&
        allowedSchemes.includes(new URL(this.document.baseURI).protocol)
      ) {
        return this.document.baseURI;
      }
      
      // Fall back to returning the document URI, even though the scheme is not
      // in the allowed list.
      return href;
      

      } } ```

    1. If your site is using multiple widgets you can set up Twitter widgets in your pages once, which will make your site faster, and widgets such as embedded Tweets will be more reliable for authors when using content management systems.

      ```html

      <script>window.twttr = (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0], t = window.twttr || {}; if (d.getElementById(id)) return t; js = d.createElement(s); js.id = id; js.src = "https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs); t._e = []; t.ready = function(f) { t._e.push(f); }; return t; }(document, "script", "twitter-wjs"));</script>

      ```

  6. Jul 2022
    1. ```js const versions = [ { version: 1, data: 1}, { version: 3, data: 3}, { version: 17, data: 17}, { version: 95, data: 95} ];

      function getNextVersion(v) { return versions.slice(0).reduceRight((a , b, i , arr) => b.version <= v ? (arr.length = 0, b) : b) } ```

    1. Here's a complete function that removes accents, replaces special characters with hyphens, also removing additional hyphens:

      ```js const replaceSpecialChars = (str) => { return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // Remove accents .replace(/([^\w]+|\s+)/g, '-') // Replace space and other characters by hyphen .replace(/--+/g, '-') // Replaces multiple hyphens by one hyphen .replace(/(^-+|-+$)/g, ''); // Remove extra hyphens from beginning or end of the string }

      console.log(replaceSpecialChars('This is a sentence!!!')); ```

    1. ```js function replaceDiacritics(s) { var s;

      var diacritics =[ /[\300-\306]/g, /[\340-\346]/g, // A, a /[\310-\313]/g, /[\350-\353]/g, // E, e /[\314-\317]/g, /[\354-\357]/g, // I, i /[\322-\330]/g, /[\362-\370]/g, // O, o /[\331-\334]/g, /[\371-\374]/g, // U, u /[\321]/g, /[\361]/g, // N, n /[\307]/g, /[\347]/g, // C, c ];

      var chars = ['A','a','E','e','I','i','O','o','U','u','N','n','C','c'];

      for (var i = 0; i < diacritics.length; i++) { s = s.replace(diacritics[i],chars[i]); }

      document.write(s); } ```

    1. ```js const dbName = 'CustomPeople';

      const exists = await Dexie.exists(dbName);

      if (exists) { var db = new Dexie(dbName); const dynamicDB = await db.open(); const existingVersionNumber = dynamicDB.verno; const columns = await ExternalDBService.getColumns(); db.close(); db = new Dexie(dbName); db.version(existingVersionNumber).stores({ People: columns }); return db.open(); } else { db = new Dexie(dbName); db.version(1).stores({ People: [] }); db.open(); } ```

    1. ```js function formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 Bytes';

      const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } ```

    1. DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言

      DOM 的本质。Document Object Model. #share

    1. this可以用在构造函数之中,表示实例对象。除此之外,this还可以用在别的场合。但不管是什么场合,this都有一个共同点:它总是返回一个对象。

      this 指针总是返回一个对象。 #share

    1. JavaScript 语言使用构造函数(constructor)作为对象的模板。所谓”构造函数”,就是专门用来生成实例对象的函数

      构造函数作为对象的模板。 #share

    1. 所谓“包装对象”,指的是与数值、字符串、布尔值分别相对应的Number、String、Boolean三个原生对象。这三个原生对象可以把原始类型的值变成(包装成)对象。

      何为包装对象?#share

    1. 注意,forEach()方法无法中断执行,总是会将所有成员遍历完。如果希望符合某种条件时,就中断遍历,要使用for循环。

      forEach() 与 for 的区别 #share