Convert single column layout to multi-column layout only when printing. Double-press Ctrl key to open settings.
目前為
// ==UserScript==
// @name Multi-Column Layout for printing (Print Only)
// @namespace http://tampermonkey.net/
// @license MIT
// @version 2.1
// @description Convert single column layout to multi-column layout only when printing. Double-press Ctrl key to open settings.
// @author KQ yang
// @match *://*
// @match file:///*
// @match http://127.0.0.1:*/*
// @match http://localhost:*/*
// @grant GM_addStyle
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// Default configuration
const DEFAULT_CONFIG = {
columns: 2,
columnGap: '30px',
fontSize: '16px',
paragraphSpacing: '1em',
enablePageBreak: true,
lineHeight: '1.5',
};
// Load config from localStorage or use defaults
let CONFIG = loadConfig();
function loadConfig() {
const savedConfig = localStorage.getItem('printLayoutConfig');
return savedConfig ? {...DEFAULT_CONFIG, ...JSON.parse(savedConfig)} : DEFAULT_CONFIG;
}
function saveConfig(config) {
localStorage.setItem('printLayoutConfig', JSON.stringify(config));
CONFIG = config;
updateStyles();
}
// Create and inject the configuration UI
function createConfigUI() {
const modal = document.createElement('div');
modal.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
z-index: 9999;
display: none;
`;
modal.innerHTML = `
<h3 style="margin-top: 0;">Print Layout Settings</h3>
<div style="margin-bottom: 10px;">
<label>Columns (1-4): </label>
<input type="number" id="columns" min="1" max="4" value="${CONFIG.columns}">
</div>
<div style="margin-bottom: 10px;">
<label>Column Gap: </label>
<input type="text" id="columnGap" value="${CONFIG.columnGap}">
</div>
<div style="margin-bottom: 10px;">
<label>Font Size: </label>
<input type="text" id="fontSize" value="${CONFIG.fontSize}">
</div>
<div style="margin-bottom: 10px;">
<label>Paragraph Spacing: </label>
<input type="text" id="paragraphSpacing" value="${CONFIG.paragraphSpacing}">
</div>
<div style="margin-bottom: 10px;">
<label>Line Height: </label>
<input type="text" id="lineHeight" value="${CONFIG.lineHeight}">
</div>
<div style="margin-bottom: 10px;">
<label>Enable Page Break: </label>
<input type="checkbox" id="enablePageBreak" ${CONFIG.enablePageBreak ? 'checked' : ''}>
</div>
<div style="text-align: right; margin-top: 20px;">
<button id="saveConfig" style="padding: 5px 10px;">Save</button>
</div>
`;
document.body.appendChild(modal);
// Save button handler
document.getElementById('saveConfig').addEventListener('click', () => {
const newConfig = {
columns: parseInt(document.getElementById('columns').value, 10),
columnGap: document.getElementById('columnGap').value,
fontSize: document.getElementById('fontSize').value,
paragraphSpacing: document.getElementById('paragraphSpacing').value,
lineHeight: document.getElementById('lineHeight').value,
enablePageBreak: document.getElementById('enablePageBreak').checked
};
saveConfig(newConfig);
modal.style.display = 'none';
});
return modal;
}
// Create and update styles based on current config
function updateStyles() {
const styleSheet = `
/* 打印样式优化 */
@media print {
html, body {
margin: 0 !important;
padding: 0 !important;
min-height: 0 !important;
height: auto !important;
}
.print-column-container {
column-count: ${CONFIG.columns} !important;
column-gap: ${CONFIG.columnGap} !important;
column-rule: 1px solid #ddd !important;
width: 100% !important;
margin: 0 !important;
padding: 0 !important;
min-height: 0 !important;
height: auto !important;
overflow: visible !important;
box-sizing: border-box !important;
font-size: ${CONFIG.fontSize} !important;
line-height: ${CONFIG.lineHeight} !important;
${CONFIG.enablePageBreak ? '' : 'page-break-inside: avoid !important;'}
}
.print-column-container > * {
break-inside: avoid !important;
margin-bottom: ${CONFIG.paragraphSpacing} !important;
max-width: 100% !important;
box-sizing: border-box !important;
page-break-inside: avoid !important;
}
.print-column-container img {
max-width: 100% !important;
height: auto !important;
page-break-inside: avoid !important;
}
}
`;
// Remove existing style if any
const existingStyle = document.getElementById('print-layout-style');
if (existingStyle) {
existingStyle.remove();
}
// Add new style
const style = document.createElement('style');
style.id = 'print-layout-style';
style.textContent = styleSheet;
document.head.appendChild(style);
}
// Apply columns to main content
function applyPrintColumns() {
const mainContent = document.querySelector('.target-content') || document.body;
mainContent.classList.add('print-column-container');
const printStyle = document.createElement('style');
printStyle.media = 'print';
printStyle.textContent = `
@page {
margin: 1cm !important;
padding: 0 !important;
size: auto !important;
}
`;
document.head.appendChild(printStyle);
}
// Initialize
let lastCtrlPress = 0;
const configModal = createConfigUI();
// Handle double Ctrl press
document.addEventListener('keydown', (e) => {
if (e.key === 'Control') {
const now = Date.now();
if (now - lastCtrlPress < 300) { // 300ms threshold for double press
configModal.style.display = configModal.style.display === 'none' ? 'block' : 'none';
}
lastCtrlPress = now;
}
});
// Initial style application
updateStyles();
// Apply columns when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', applyPrintColumns);
} else {
applyPrintColumns();
}
// Log usage instructions to console
console.log(`
Multi-Column Layout Userscript Usage:
-----------------------------------
1. Double-press Ctrl key to open settings
2. Adjust your preferences:
- Columns: Number of columns (1-4)
- Column Gap: Space between columns
- Font Size: Text size in print
- Paragraph Spacing: Space between paragraphs
- Line Height: Text line height
- Enable Page Break: Allow/prevent content breaks across pages
3. Click Save to apply changes
4. Settings are automatically saved between sessions
5. Press Ctrl+P to see the print preview with your settings
Current configuration:`, CONFIG);
})();