您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自分用のメモ欄をメインページに作成。縦横軸管理画面にも商品コード毎にメモは共有。本登録後も確認可。
// ==UserScript== // @name メモ欄 // @namespace http://tampermonkey.net/ // @version 1.30 // @description 自分用のメモ欄をメインページに作成。縦横軸管理画面にも商品コード毎にメモは共有。本登録後も確認可。 // @license MIT // @match *://plus-nao.com/forests/*/mainedit/* // @match *://plus-nao.com/forests/*/registered_mainedit/* // @match https://starlight.plusnao.co.jp/goods/axisCode* // @grant GM_getValue // @grant GM_setValue // @run-at document-end // ==/UserScript== (function() { 'use strict'; let memoBoxChanged = false; let otherChanges = false; let memoVisible = localStorage.getItem('memoVisible') === 'true'; const isStarlight = window.location.hostname === 'starlight.plusnao.co.jp'; if (isStarlight) { memoVisible = false; } let splitMode = localStorage.getItem('splitMode') || 'none'; const memoDiv = document.createElement('div'); memoDiv.style.position = 'fixed'; memoDiv.style.bottom = isStarlight ? '0' : '25px'; memoDiv.style.right = '5px'; memoDiv.style.zIndex = '1000'; memoDiv.style.border = '1px solid #ccc'; memoDiv.style.backgroundColor = '#EEF7FF'; memoDiv.style.resize = 'both'; memoDiv.style.overflow = 'hidden'; memoDiv.style.borderRadius = '5px'; memoDiv.style.transform = 'scale(-1)'; memoDiv.style.display = memoVisible ? 'flex' : 'none'; memoDiv.style.flexDirection = 'column-reverse'; memoDiv.style.boxSizing = 'border-box'; const savedWidth = localStorage.getItem('memoBoxWidth') || '500px'; const savedHeight = localStorage.getItem('memoBoxHeight') || '500px'; memoDiv.style.width = savedWidth; memoDiv.style.height = savedHeight; const memoHeader = document.createElement('div'); memoHeader.textContent = 'Memo'; memoHeader.style.fontWeight = 'bold'; memoHeader.style.textAlign = 'center'; memoHeader.style.position = 'relative'; memoHeader.style.padding = isStarlight ? '5px 0' : '5px 0'; memoHeader.style.cursor = 'default'; memoHeader.style.transform = 'scale(-1)'; const memoContainer = document.createElement('div'); memoContainer.style.flex = '1'; memoContainer.style.display = 'flex'; memoContainer.style.flexDirection = 'column'; memoContainer.style.overflow = 'hidden'; memoContainer.style.transform = 'scale(-1)'; function simulatePaste(inputElement, text) { if (!text.includes('\n')) { text += '\n'; } navigator.clipboard.writeText(text).then(() => { inputElement.focus(); const pasteEvent = new ClipboardEvent('paste', { clipboardData: new DataTransfer() }); pasteEvent.clipboardData.setData('text', text); inputElement.dispatchEvent(pasteEvent); }).catch(err => { console.error('Clipboardへの書き込みに失敗しました:', err); }); } function createTextarea(index) { const container = document.createElement('div'); container.style.display = 'flex'; container.style.flexDirection = 'column'; container.style.marginBottom = '5px'; const textarea = document.createElement('textarea'); textarea.style.width = '100%'; textarea.style.height = '100%'; textarea.style.resize = 'none'; textarea.style.boxSizing = 'border-box'; textarea.style.padding = '3px'; textarea.placeholder = `Area ${index}`; textarea.dataset.index = index; let productId; if (window.location.hostname === 'starlight.plusnao.co.jp') { const params = new URLSearchParams(window.location.search); productId = params.get('code'); } else { productId = window.location.pathname.split('/').pop(); } let value; if (window.location.hostname === 'starlight.plusnao.co.jp') { if (index === 0) { value = GM_getValue(`personalMemo-${productId}`, ''); } else { value = GM_getValue(`personalMemo-${productId}-@${index}`, ''); } } else { if (index === 0) { value = localStorage.getItem(`personalMemo-${productId}`) || ''; if (value === '') { value = GM_getValue(`personalMemo-@${productId}`, ''); } } else { value = localStorage.getItem(`personalMemo-${productId}-${index}`) || ''; if (value === '') { value = GM_getValue(`personalMemo-${productId}-@${index}`, ''); } } } textarea.value = value; textarea.addEventListener('input', () => { if (window.location.hostname !== 'starlight.plusnao.co.jp') { if (index === 0) { localStorage.setItem(`personalMemo-${productId}`, textarea.value); GM_setValue(`personalMemo-${productId}`, textarea.value); } else { localStorage.setItem(`personalMemo-${productId}-@${index}`, textarea.value); GM_setValue(`personalMemo-${productId}-@${index}`, textarea.value); } } memoBoxChanged = true; }); textarea.addEventListener('mousedown', (event) => { event.stopPropagation(); }); const copyButton = document.createElement('button'); copyButton.textContent = 'コピー'; copyButton.style.marginTop = '5px'; copyButton.style.padding = '9px 6px'; copyButton.style.fontSize = '12px'; copyButton.style.border = 'none'; copyButton.style.backgroundColor = '#007bff'; copyButton.style.color = 'white'; copyButton.style.borderRadius = '3px'; copyButton.style.cursor = 'pointer'; copyButton.style.alignSelf = 'flex-start'; copyButton.addEventListener('click', () => { navigator.clipboard.writeText(textarea.value).then(() => { copyButton.textContent = 'コピーしました'; setTimeout(() => { copyButton.textContent = 'コピー'; }, 1500); }).catch(err => { console.error('コピーに失敗しました: ', err); }); }); const pasteHorizontalButton = document.createElement('button'); pasteHorizontalButton.textContent = '横軸ペースト'; pasteHorizontalButton.style.marginTop = '5px'; pasteHorizontalButton.style.padding = '9px 6px'; pasteHorizontalButton.style.fontSize = '12px'; pasteHorizontalButton.style.border = 'none'; pasteHorizontalButton.style.backgroundColor = '#28a745'; pasteHorizontalButton.style.color = 'white'; pasteHorizontalButton.style.borderRadius = '3px'; pasteHorizontalButton.style.cursor = 'pointer'; pasteHorizontalButton.style.alignSelf = 'flex-start'; pasteHorizontalButton.addEventListener('click', () => { const targetHorizontalInput = document.querySelector('table:nth-of-type(1) tbody tr td:nth-child(4) input.form-control'); if (targetHorizontalInput) { const textToPaste = textarea.value; simulatePaste(targetHorizontalInput, textToPaste); pasteHorizontalButton.textContent = 'ペーストしました'; setTimeout(() => { pasteHorizontalButton.textContent = '横軸ペースト'; }, 1500); } }); const pasteVerticalButton = document.createElement('button'); pasteVerticalButton.textContent = '縦軸ペースト'; pasteVerticalButton.style.marginTop = '5px'; pasteVerticalButton.style.padding = '9px 6px'; pasteVerticalButton.style.fontSize = '12px'; pasteVerticalButton.style.border = 'none'; pasteVerticalButton.style.backgroundColor = '#28a745'; pasteVerticalButton.style.color = 'white'; pasteVerticalButton.style.borderRadius = '3px'; pasteVerticalButton.style.cursor = 'pointer'; pasteVerticalButton.style.alignSelf = 'flex-start'; pasteVerticalButton.addEventListener('click', () => { const verticalTable = document.querySelectorAll('table')[2]; const targetVerticalInputs = verticalTable.querySelectorAll('tbody tr td:nth-child(4) input.form-control'); if (targetVerticalInputs.length > 0) { const textToPaste = textarea.value; targetVerticalInputs.forEach((input, index) => { if (index === 0) { simulatePaste(input, textToPaste); } }); pasteVerticalButton.textContent = 'ペーストしました'; setTimeout(() => { pasteVerticalButton.textContent = '縦軸ペースト'; }, 1500); } }); const buttonContainer = document.createElement('div'); buttonContainer.style.display = 'flex'; buttonContainer.style.gap = '10px'; buttonContainer.style.marginTop = '1px'; container.appendChild(textarea); if (isStarlight) { buttonContainer.appendChild(copyButton); buttonContainer.appendChild(pasteHorizontalButton); buttonContainer.appendChild(pasteVerticalButton); container.appendChild(textarea); container.appendChild(buttonContainer); } return container; } memoDiv.addEventListener('mouseup', () => { if (memoVisible) { localStorage.setItem('memoBoxWidth', memoDiv.style.width); localStorage.setItem('memoBoxHeight', memoDiv.style.height); memoBoxChanged = true; } }); function updateMemoLayout() { memoContainer.innerHTML = ''; let textareas; switch (splitMode) { case 'vertical': { memoContainer.style.flexDirection = 'column'; textareas = [createTextarea(0), createTextarea(1)]; textareas.forEach((container) => { container.style.flex = '1'; memoContainer.appendChild(container); }); break; } case 'horizontal': { memoContainer.style.flexDirection = 'row'; textareas = [createTextarea(0), createTextarea(1)]; textareas.forEach((container) => { container.style.flex = '1'; memoContainer.appendChild(container); }); break; } case 'grid': { memoContainer.style.flexDirection = 'column'; const row1 = document.createElement('div'); row1.style.display = 'flex'; row1.style.flex = '1'; row1.style.flexDirection = 'row'; row1.style.overflow = 'hidden'; const row2 = document.createElement('div'); row2.style.display = 'flex'; row2.style.flex = '1'; row2.style.flexDirection = 'row'; row2.style.overflow = 'hidden'; textareas = [createTextarea(0), createTextarea(1), createTextarea(2), createTextarea(3)]; textareas.forEach((container, index) => { container.style.flex = '1'; if (index < 2) row1.appendChild(container); else row2.appendChild(container); }); memoContainer.appendChild(row1); memoContainer.appendChild(row2); break; } default: { const container = createTextarea(0); container.style.height = '100%'; container.style.width = '100%'; memoContainer.appendChild(container); break; } } } const splitButton = document.createElement('button'); splitButton.textContent = '田'; splitButton.style.position = 'fixed'; splitButton.style.top = '5px'; splitButton.style.right = '30px'; splitButton.style.zIndex = '1001'; splitButton.style.padding = '0px 6px'; splitButton.style.fontSize = '12px'; splitButton.style.border = 'none'; splitButton.style.backgroundColor = '#66CCFF'; splitButton.style.color = '#fff'; splitButton.style.borderRadius = '3px'; splitButton.style.cursor = 'pointer'; splitButton.addEventListener('click', () => { switch (splitMode) { case 'none': splitMode = 'vertical'; break; case 'vertical': splitMode = 'horizontal'; break; case 'horizontal': splitMode = 'grid'; break; case 'grid': splitMode = 'none'; break; } localStorage.setItem('splitMode', splitMode); updateMemoLayout(); }); const buttonStyle = ` #buttonWrapper { position: fixed; bottom: 20px; right: 20px; width: 80px; height: 80px; display: flex; justify-content: center; align-items: center; z-index: 9999; pointer-events: none; } #showButton { width: 40px; height: 40px; background: rgba(102, 204, 102, 0.5); backdrop-filter: blur(8px); border: 1px solid rgba(102, 204, 102, 0.4); border-radius: 50%; font-size: 26px; font-weight: bold; color: #fff; display: flex; justify-content: center; align-items: center; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); pointer-events: auto; transform-origin: center; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); opacity: 0; animation: fadeIn 0.5s forwards; } #showButton:hover { width: 60px; height: 60px; background: rgba(102, 204, 102, 0.6); font-size: 32px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); } #showButton:active { transform: scale(0.9); background: rgba(102, 204, 102, 0.8); transition: transform 0.05s ease; } @keyframes fadeIn { from { opacity: 0; transform: scale(0.5); } to { opacity: 1; transform: scale(1); } } @keyframes buttonPop { 0% { transform: scale(1); } 50% { transform: scale(1.4) rotate(10deg); } 100% { transform: scale(1); } } @keyframes fadeInMemo { from { opacity: 0; } to { opacity: 1; } } #showButton.fadeOut { animation: fadeOut 0.5s forwards; } @keyframes fadeOut { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.5); } } `; const styleElement = document.createElement('style'); styleElement.innerHTML = buttonStyle; document.head.appendChild(styleElement); const wrapper = document.createElement('div'); wrapper.id = 'buttonWrapper'; const showButton = document.createElement('button'); showButton.id = 'showButton'; showButton.textContent = '+'; wrapper.appendChild(showButton); const hideButton = document.createElement('button'); hideButton.textContent = '‐'; hideButton.style.position = 'fixed'; hideButton.style.top = '5px'; hideButton.style.right = '5px'; hideButton.style.zIndex = '1001'; hideButton.style.transform = 'scale(-1)'; hideButton.style.padding = '0px 6px'; hideButton.style.fontSize = '12px'; hideButton.style.border = 'none'; hideButton.style.backgroundColor = '#FF6666'; hideButton.style.color = '#fff'; hideButton.style.borderRadius = '3px'; hideButton.style.cursor = 'pointer'; hideButton.style.display = memoVisible ? 'block' : 'none'; memoDiv.style.display = memoVisible ? 'flex' : 'none'; showButton.style.display = memoVisible ? 'none' : 'block'; hideButton.addEventListener('click', () => { memoVisible = false; memoDiv.style.display = 'none'; hideButton.style.display = 'none'; showButton.style.display = 'block'; localStorage.setItem('memoVisible', memoVisible); document.body.removeEventListener('click', handleClickOutside); }); showButton.addEventListener('click', () => { showButton.style.animation = 'buttonPop 0.5s'; setTimeout(() => { memoVisible = !memoVisible; setTimeout(() => { memoDiv.style.display = memoVisible ? 'flex' : 'none'; }, 70); hideButton.style.display = memoVisible ? 'block' : 'none'; if (memoVisible) { showButton.classList.add('fadeOut'); setTimeout(() => { showButton.style.display = 'none'; }, 70); document.body.addEventListener('click', handleClickOutside); } else { showButton.classList.remove('fadeOut'); showButton.style.display = 'block'; showButton.style.opacity = '1'; document.body.removeEventListener('click', handleClickOutside); } localStorage.setItem('memoVisible', memoVisible); }, 70); }); hideButton.addEventListener('click', () => { memoVisible = false; memoDiv.style.display = 'none'; hideButton.style.display = 'none'; showButton.style.display = 'block'; showButton.classList.remove('fadeOut'); showButton.style.opacity = '1'; localStorage.setItem('memoVisible', memoVisible); if (isStarlight) { if (memoVisible) { document.body.addEventListener('click', handleClickOutside); } else { document.body.removeEventListener('click', handleClickOutside); } } }); memoHeader.appendChild(splitButton); memoHeader.appendChild(hideButton); memoDiv.appendChild(memoHeader); memoDiv.appendChild(memoContainer); document.body.appendChild(memoDiv); document.body.appendChild(wrapper); updateMemoLayout(); window.addEventListener('resize', () => { if (memoVisible) { const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; const newWidth = Math.min(parseInt(memoDiv.style.width), windowWidth - 20) + 'px'; const newHeight = Math.min(parseInt(memoDiv.style.height), windowHeight - 50) + 'px'; memoDiv.style.width = newWidth; memoDiv.style.height = newHeight; } }); document.body.addEventListener('input', (event) => { if (event.target.closest('textarea')) { memoBoxChanged = true; } else { otherChanges = true; } }); const buttonIds = ['tempSaveButton', 'saveAndSkuStock', 'registeredSaveAndSkuStock', 'registeredSaveButton']; buttonIds.forEach(id => { const button = document.getElementById(id); if (button) { button.addEventListener('click', () => { }); } }); if (isStarlight) { let productId = new URLSearchParams(window.location.search).get('code'); const observer = new MutationObserver(() => { const params = new URLSearchParams(window.location.search); const newProductId = params.get('code'); if (newProductId !== productId) { productId = newProductId; updateMemoLayout(); } }); observer.observe(document.body, { childList: true, subtree: true }); } function handleClickOutside(event) { if (isStarlight && memoVisible && !memoDiv.contains(event.target) && !showButton.contains(event.target)) { memoVisible = false; memoDiv.style.display = 'none'; hideButton.style.display = 'none'; showButton.style.display = 'block'; showButton.classList.remove('fadeOut'); showButton.style.opacity = '1'; localStorage.setItem('memoVisible', memoVisible); document.removeEventListener('click', handleClickOutside); document.addEventListener('click', handleClickOutside); } } document.addEventListener('click', handleClickOutside); })();