登录 立即注册

找到493个回复 (用户: 无名啊)

无名啊 55楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,你想浏览时能点击加载?

无名啊 52楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,看来这应该也是最快最好的办法了

无名啊 51楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,我看看啊,实际上,你的代码分成两个部分:

  1. 替换img.src(尽量早执行,也即插件列表开头)
  2. 点击显示原图,恢复onclick(尽量晚执行,也即插件列表结尾)

是吧?Emm……

无名啊 49楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,开始各种卷了

不如从根头解决,只依赖用户设定的顺序?

无名啊 47楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,现在你加setTimeout解决了,再后来的脚本想在你之后执行,该咋办呢

无名啊 45楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,感觉可以和viewer作者协调下,去掉 $(document).ready()

你也说多个$(document).ready()执行顺序不定,不利于后面脚本按顺序执行

无名啊 43楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,不对噢,viewer加了defer

那就是你先执行$(document).ready(),然后解析完DOM后,viewer再执行$(document).ready()

触发DOMContentLoaded后,你先绑定onclick,再由viewer绑定?

所以,你的也应该加上defer

无名啊 41楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,你的插件排在viewer之后,并且也用$(document).ready()的话,是不是就能在viewer绑定onclick后执行了?

无名啊 40楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,看来也用不了async属性,要保证按用户设定的脚本顺序执行

无名啊 37楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,研究这个咋会无意义呢?

现在你的代码,还是和viewer冲突

无名啊 36楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,啊这。。那 @读书顶个鸟用defer的目的是啥??

无名啊 34楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,不是,之前你的版本,最后存活的onclickviewer的,导致没法点击后加载

无名啊 31楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,我理解错了?https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/script#attr-defer

defer布尔属性被设定用来通知浏览器该脚本将在文档完成解析后,触发 DOMContentLoaded (en-US) 事件前执行。
defer 属性的脚本会阻止 DOMContentLoaded 事件,直到脚本被加载并且解析完成。

无名啊 29楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,我好奇为何你的脚本会和图片浏览器(下称viewer冲突

按说,viewerdefer,在DOMContentLoaded之前执行,(之前)你的在触发后执行,应该是可以由你保存好vieweronclick,最后存活的onclick是你的啊

无名啊 25楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)
@老虎会游泳,我装了你的,关了表情,测了本贴第一页,已缓存的图片算是发出请求吗?
无标题.png.avif(43.59 KB)
无名啊 22楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,我感觉DOMContentLoaded触发后,各个图片都下了一小点了(所以也经常会闪烁一下才消失),也不知道能不能利用上

那些拦截广告的,也不知道怎么做到不会有闪烁就过滤掉广告的,感觉像浏览器解析DOM前,就过滤掉了

无名啊 20楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,噢,看漏了,看成“新上传的图片才有文件大小”了

对外站图片用啥方法好呢

无名啊 18楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,旧图片、外站图片、音乐、视频啥的,好像没有提供文件大小

对这些情况,有啥更好的办法吗(除了HEAD再查询一次)

无名啊 17楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,我用的我7楼的代码,有小概率能用上图片浏览器(此时正常,点击按钮重现图片后也正常),大部分时候被你的 footer.js 代替了,点击图片就新窗口打开

无名啊 7楼回复 老虎会游泳【网页插件】图片点击加载(测试版 r8) (2022-07-31//)

@老虎会游泳,我改写了下,主要更新内容:

  1. 按钮变得好看些
  2. 自动使图片、音乐、视频、内嵌HTML变成点击显示
  3. 自动检测目标链接文件大小。对于图片,若已缓存或较小(如 < 1MB),则直接显示

感觉还存在以下问题:

  1. 不知道有没有直接获取文件大小的方法。

    目前是用fetchHEAD方法再发送一次请求,解析content-length判定文件大小。

    • 会不会有啥安全问题?
    • 会不会跨域啥的获取不了大小?
    • 会不会哪个服务器把HEADGET看,直接返回整个文件?
  2. 还是和图片浏览器插件冲突。

    按理说,我保留了原始img节点,onclick啥的应该都还保留着?

@老虎会游泳,有空能指教下,问题出哪儿不?

<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script>

  const blocks = {
    userimg: {type: 'img', icon: 'image'},
    iframe_box: {type: 'iframe', icon: 'web'},
    audio_box: {type: 'audio', icon: 'audiotrack'},
    video_box: {type: 'video', icon: 'movie'},
  };

  function formatSize(size) {
    const i = size && Math.floor(Math.log(size) / Math.log(1024));
    return (size / (1 << (10 * i))).toFixed(i && 2) + ' ' + ' KMGT'[i].trim() + 'B';
  }

  customElements.define('my-button', class extends HTMLElement {
    #ref = {};
    #orig_node;
    #media_src;
    #media_node;

    #createElementFromObject(obj) {
      let el = document.createElement(obj.tag);
      for (const k in obj) {
        if (k === 'children')
          obj.children.forEach(c => el.appendChild(this.#createElementFromObject(c)));
        else if (k === 'text')
          el.textContent = obj[k];
        else if (k === 'ref')
          this.#ref[obj[k]] = el;
        else if (k !== 'tag')
          el.setAttribute(k, obj[k]);
      }
      return el;
    }

    constructor() {
      super();

      // 创建一个 shadow root
      let shadow = this.attachShadow({mode: 'open'});

      [
        {tag: 'link', rel: 'stylesheet', href: 'https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css'},
        {tag: 'link', rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons'},
        {tag: 'script', src: 'https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js'},
        {tag: 'button', class: 'mdc-fab mdc-fab--extended', style: 'margin: 10px', children: [
            {tag: 'div', class: 'mdc-fab__ripple'},
            {tag: 'span', class: 'material-icons mdc-fab__icon', ref: 'icon'},
            {tag: 'span', class: 'mdc-fab__label', ref: 'text'},
          ]},
        {tag: 'style', text: `
          :host {
            /* --mdc-theme-primary: #e74c3c; */
            --mdc-theme-secondary: #fafafa;
            /* --mdc-theme-background: #f00; */
            /* --mdc-theme-on-primary: #fff; */
            --mdc-theme-on-secondary: #2c3e50;
          }
        `},
      ].forEach(x => shadow.appendChild(this.#createElementFromObject(x)));

      this.onclick = this.recover;
    }

    get text() {
      return this.#ref.text.textContent;
    }

    set text(s) {
      this.#ref.text.textContent = s;
    }

    get icon() {
      return this.#ref.icon.textContent;
    }

    set icon(s) {
      this.#ref.icon.textContent = s;
    }

    // onclick() {  // 为什么不能这样重写方法??
    recover() {
      this.#media_node.src &&= this.#media_src;
      this.parentNode.replaceChild(this.#orig_node, this);
      delete this;
    }

    // 替换掉旧节点,展示本按钮
    replace(root_node, media_node) {
      this.#orig_node = root_node.parentNode.replaceChild(this, root_node);
      this.#media_node = media_node;
      this.#media_src = media_node.src;
      media_node.src &&= ' ';

      // 询问目标链接大小,太大则等待用户选择,较小直接显示
      if (this.#media_src) {
        fetch(this.#media_src, {method: 'HEAD'}).then(resp => {
          if (resp.ok) {
            const size = parseInt(resp.headers.get('content-length'));
            if (size < (1 << 20) && this.icon === blocks.userimg.icon)
              this.recover();
            else if (size > 0)
              this.text += `(${formatSize(size)})`;
          }
        });
      }
    }
  });

  document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll(Object.keys(blocks).map(x => `.${x}`).join()).forEach(x => {

      // 获取 element 类型、显示按钮时的图标
      const {type, icon} = Object.entries(blocks).find(([k]) => x.classList.contains(k))[1];

      // 若图片已下载完毕,就让它显示吧
      if (type === 'img' && x.complete)
        return;

      // 获取真正的多媒体节点
      const media_node = ['audio', 'video'].includes(type) ? x.querySelector(type) : x;

      // 图片有外层链接,则准备替换整个外层
      if (type === 'img' && x.parentNode.href)
        x = x.parentNode;

      // 创建按钮
      let el = document.createElement('my-button');
      el.icon = icon;
      el.text = type === 'iframe' ? '内嵌网页' : media_node.alt || media_node.src;
      el.replace(x, media_node);
    });
  });
</script>
下一页 上一页 (22 / 25页)

5月12日 08:43 星期一

本站由hu60wap6驱动

备案号: 京ICP备18041936号-1