Greasy Fork

Greasy Fork is available in English.

SKU批量填充

淘宝、拼多多SKU批量填充

当前为 2024-10-17 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         SKU批量填充
// @namespace    none
// @version      0.1.3
// @description  淘宝、拼多多SKU批量填充
// @author       鹿秋夏
// @include      https://sell.publish.tmall.com/tmall/publish.htm?*
// @include      https://mms.pinduoduo.com/goods/goods_add/index?*
// @grant        none
// ==/UserScript==

(() => {
  "use strict";

  // 检查当前页面是否为目标页面
  const isTaobaoPage = window.location.href.includes(
    "https://sell.publish.tmall.com/tmall/publish.htm?"
  );
  const isPinduoduoPage = window.location.href.includes(
    "https://mms.pinduoduo.com/goods/goods_add/index?"
  );

  if (!isTaobaoPage && !isPinduoduoPage) return;

  // 等待指定元素加载完毕后执行回调函数
  const waitForElement = (selector, callback, isXPath = false) => {
    let targetElement;
    if (isXPath) {
      targetElement = document.evaluate(
        selector,
        document,
        null,
        XPathResult.FIRST_ORDERED_NODE_TYPE,
        null
      ).singleNodeValue;
    } else {
      targetElement = document.querySelector(selector);
    }
    if (targetElement) {
      callback(targetElement);
    } else {
      setTimeout(() => waitForElement(selector, callback, isXPath), 100); // 等待0.1秒后重新尝试获取
    }
  };

  // 添加自定义按钮
  const addCustomButton = (targetElement, isPinduoduo) => {
    const customButton = document.createElement("button");
    customButton.id = "custom-button";
    customButton.textContent = "批量SKU填充";
    customButton.style.borderRadius = "3px"; // 圆角
    customButton.style.width = "100px"; // 宽度
    customButton.style.height = "32px"; // 高度
    customButton.style.backgroundColor = "rgb(234, 244, 253)"; // 背景颜色
    customButton.style.color = "rgb(76, 148, 253)"; // 字体颜色
    customButton.style.outline = "none"; // 去除焦点样式
    customButton.style.border = "1px solid rgb(69, 143, 236)"; // 边框样式
    customButton.style.boxShadow = "none"; // 去除阴影样式
    customButton.style.position = "absolute"; // 设置为绝对定位
    customButton.style.cursor = "auto"; // 默认鼠标指针样式
    customButton.style.lineHeight = isPinduoduo ? "0px" : "32px";

    // 动态计算左边距
    const targetRect = targetElement.getBoundingClientRect();
    customButton.style.left = `${
      targetRect.left + targetRect.width + (isPinduoduo ? -497 : 12)
    }px`; // 在目标元素右边12px处或右边-497px处

    // 按钮点击事件处理
    customButton.addEventListener("click", async () => {
      try {
        const text = await navigator.clipboard.readText();
        // 对剪贴板内容进行分割与过滤操作,得到处理后的列表
        const processedList = text
          .split("\n")
          .filter((item) => item.trim() !== "");

        // 循环处理列表中的每个元素
        for (const [index, value] of processedList.entries()) {
          setTimeout(() => {
            if (isTaobaoPage) {
              const addButton = document.evaluate(
                '//div[@id="struct-p-1627207"]//span[@class="next-btn-helper" and text()="新增规格项"]',
                document,
                null,
                XPathResult.FIRST_ORDERED_NODE_TYPE,
                null
              ).singleNodeValue;
              addButton.click();
            }

            // 等待输入框加载完毕
            const inputSelector = isTaobaoPage
              ? 'input[placeholder="主色(必选)"][value=""]'
              : '//div[text()="款式"]/following::input[@placeholder="请输入规格名称" and @value=""]';
            waitForElement(
              inputSelector,
              (inputElement) => {
                inputElement.value = value;
                inputElement.dispatchEvent(
                  new Event("input", { bubbles: true, cancelable: true })
                );
                inputElement.focus();
                inputElement.blur();
                const clickEvent = new MouseEvent("click", {
                  bubbles: true,
                  cancelable: true,
                  view: window,
                });
                inputElement.dispatchEvent(clickEvent);

                // 等待指定时间后检查输入框是否存在
                setTimeout(() => {
                  const checkInput = isTaobaoPage
                    ? document.querySelector(inputSelector)
                    : document.evaluate(
                        inputSelector,
                        document,
                        null,
                        XPathResult.FIRST_ORDERED_NODE_TYPE,
                        null
                      ).singleNodeValue;
                  if (!checkInput) {
                    // 如果输入框不存在,清空内容并重新输入
                    inputElement.value = "";
                    inputElement.dispatchEvent(
                      new Event("input", { bubbles: true, cancelable: true })
                    );
                    inputElement.focus();
                    inputElement.value = value;
                    inputElement.dispatchEvent(
                      new Event("input", { bubbles: true, cancelable: true })
                    );
                    inputElement.focus();
                    inputElement.blur();
                  }
                }, 100);
              },
              isPinduoduo
            );
          }, index * (isTaobaoPage ? 100 : 700)); // 每个元素间隔100ms或500ms处理
        }
      } catch (error) {
        console.error(error);
      }
    });

    // 鼠标悬停时修改鼠标指针和样式
    customButton.addEventListener("mouseenter", () => {
      customButton.style.cursor = "pointer";
      customButton.style.backgroundColor = "rgb(204, 214, 223)"; // 悬停时的背景颜色
    });

    // 鼠标离开时恢复原样式
    customButton.addEventListener("mouseleave", () => {
      customButton.style.cursor = "auto";
      customButton.style.backgroundColor = "rgb(234, 244, 253)";
    });

    // 将按钮插入到目标元素的父节点中
    targetElement.parentNode.insertBefore(
      customButton,
      targetElement.nextSibling
    );
  };

  // 每隔500ms检测页面是否加载了按钮
  const checkButtonInterval = setInterval(() => {
    const customButton = document.getElementById("custom-button");
    if (!customButton) {
      // 等待目标元素加载完毕后添加按钮
      if (isTaobaoPage) {
        waitForElement("div[class='front']", (targetElement) =>
          addCustomButton(targetElement, false)
        );
      } else if (isPinduoduoPage) {
        waitForElement(
          '//div[.//div[text()="款式"] and @class="goods-spec-row-left"]',
          (targetElement) => addCustomButton(targetElement, true),
          true
        );
      }
    } else {
      // 清除所有重复的按钮,只保留一个
      const buttons = document.querySelectorAll("#custom-button");
      if (buttons.length > 1) {
        buttons.forEach((button, index) => index > 0 && button.remove());
      }
    }
  }, 500);
})();