style.left,offsetLeft相对于容器的位置控制

本文详细解释了当父元素设置为position: relative,子元素设置为position: absolute时,子元素的定位方式。重点对比了style.left属性与offsetLeft属性的区别,并讨论了它们的应用场景。
如果父div的position定义为relative,子div的position定义为absolute,那么子div的style.left的值是相对于父div的值,
这同offsetLeft是相同的,区别在于:
1. style.left 返回的是字符串,如28px,offsetLeft返回的是数值28,如果需要对取得的值进行计算,
还用offsetLeft比较方便。
2. style.left是读写的,offsetLeft是只读的,所以要改变div的位置,只能修改style.left。
3. style.left的值需要事先定义,否则取到的值为空。而且必须要定义在html里,我做过试验,如果定义在
css里,style.left的值仍然 为空,这就是我刚开始碰到的问题,总是取不到style.left的值。

offsetLeft则仍然能够取到,无需事先定义div的位置。
// 监听拖拽元素结束 handledrag(event) { if(!this.componentsList.imageUrl){ this.$message.error('请先上传管网图片!') return; } event.preventDefault(); const value = event.dataTransfer.getData("dragData"); // 获取绑定到拖拽元素身上的 dragData属性 if (value) { let dragData = JSON.parse(value); // 获取编号 getNum(this.precipitatorId,dragData.type).then(res=>{ let uuid = res.data[0] dragData.precipitatorId = this.precipitatorId if (dragData.type == 5 || dragData.type == 6) { dragData.valveProp = dragData.valveProp || {}; dragData.valveProp.uuid = uuid; dragData.valveProp.precipitatorId = this.precipitatorId dragData.valveProp.name = '未命名' } else if (dragData.type == 9) { dragData.presetDustProperty = dragData. presetDustProperty || {}; dragData.presetDustProperty.uuid = uuid; dragData.presetDustProperty.precipitatorId = this.precipitatorId dragData.presetDustProperty.name = '未命名' } // 获取拖拽容器的位置 const container = this.$refs.dragContainer; const containerRect = container.getBoundingClientRect(); // 计算鼠标相对于容器的位置 const mouseX = event.clientX - containerRect.left; const mouseY = event.clientY - containerRect.top; const correctX = mouseX - (dragData.xpos || 0); const correctY = mouseY - (dragData.ypos || 0); const newComponent = { ...dragData, xpos: (correctX < 0 ? 0 : correctX), ypos: (correctY < 0 ? 0 : correctY), temp: { xpos: (correctX < 0 ? 0 : correctX), ypos: (correctY < 0 ? 0 : correctY), }, precipitatorId: this.precipitatorId, }; this.$emit('add-component', newComponent); }) } }, 以上方法还是不行
09-11
index.aspx代码(<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="Report_index" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" /> <link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" /> <title>运营报告</title> <script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.worker.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"/> <style> * { margin: 0; padding: 0; } body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; line-height: 1.6; } .container { width: 100%; max-width: 1200px; margin: 0 auto; } .page-header { padding-bottom: 0.5rem; margin: 1.5rem 0 1rem; border-bottom: 1px solid #eee; color: #333; } h2, h3 { margin-top: 1rem; margin-bottom: 0.75rem; font-weight: 500; line-height: 1.1; } h2 { font-size: clamp(1.5rem, 3vw, 2rem); } h3 { font-size: clamp(1.2rem, 2.5vw, 1.6rem); } .pdf-list-container { margin-top: 1.5rem; } .pdf-list-item { cursor: pointer; padding: 1rem; margin-bottom: 0.5rem; border: 1px solid #eee; border-radius: 4px; transition: all 0.2s ease; background-color: #fff; font-size: clamp(1rem, 2vw, 1.2rem); display: flex; align-items: center; justify-content: space-between; } .pdf-list-item:hover:not(.text-muted) { background-color: #f5f5f5; border-color: #ccc; transform: translateY(-1px); } .pdf-list-item.active { background-color: #e3f2fd; border-color: #2196f3; font-weight: 500; } .pdf-list-item.text-muted { color: #777; cursor: not-allowed; background-color: #f9f9f9; } #loadingTip { min-height: calc(100vh - 200px); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; color: #666; } .spinner { margin-right: 10px; width: 30px; height: 30px; border: 3px solid rgba(0,0,0,.1); border-radius: 50%; border-top-color: #337ab7; animation: spin 1s ease-in-out infinite; } @keyframes spin { to { transform: rotate(360deg); } } .error-message { color: #d9534f; text-align: center; padding: 20px; line-height: 1.8; } #timeoutTip { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.85); align-items: center; justify-content: center; z-index: 10; flex-direction: column; } .timeout-retry-btn { margin-top: 10px; padding: 8px 16px; border: 1px solid #2196f3; border-radius: 4px; background: #fff; color: #2196f3; cursor: pointer; transition: all 0.2s; font-size: 1rem; } .timeout-retry-btn:hover { background: #e3f2fd; } .label { display: inline-block; padding: .2em .6em .3em; font-size: 75%; font-weight: 700; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25em; margin-left: 10px; } .label-danger { background-color: #d9534f; } .file-icon { margin-right: 8px; } .progress-container { width: 100%; height: 4px; background-color: #f1f1f1; position: absolute; top: 0; left: 0; z-index: 15; display: none; } .progress-bar { height: 100%; background-color: #2196f3; width: 0%; transition: width 0.3s ease; } @media (max-width: 768px) { .pdf-list-item { padding: 0.75rem; flex-direction: column; align-items: flex-start; } .label { margin-left: 0; margin-top: 0.5rem; align-self: flex-start; } } /* 双击放大相关样式 */ .zoom-target-highlight { position: absolute; border: 2px solid #2196f3; border-radius: 4px; pointer-events: none; z-index: 10; animation: pulse 0.5s ease-in-out; } @keyframes pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.1); opacity: 0.8; } 100% { transform: scale(1); opacity: 0; } } /* 占位容器:固定原列表容器的空间 */ .pdf-list-placeholder { height: 200px; visibility: hidden; } /* 原列表容器 */ .pdf-list-container { position: absolute; left: 0; top: -9999px; opacity: 0; pointer-events: none; } </style> </head> <body> <form id="form1" runat="server"> <div class="container"> <div id="loadingTip"> <div class="spinner"></div> <span>正在加载,请稍候...</span> </div> <div id="pdfPreviewContainer"> <div class="progress-container"> <div class="progress-bar" id="progressBar"></div> </div> <div id="pdfContainer"></div> <div id="timeoutTip" class="error-message"> <span>❌</span> <br/>加载超时,请检查网络或尝试重新点击 </div> </div> <div class="pdf-list-placeholder"></div> <div class="pdf-list-container" style="padding:10px;display: none;"> <h3 >历史维护报告</h3> <div id="pdfList" style="width: 100%; max-width: 700px; padding-bottom: 20px" > <asp:Repeater ID="rptPdfList" runat="server"> <ItemTemplate> <div class="pdf-list-item " data-pdf-url="<%# GetProxyUrl((Eval("PdfUrl").ToString()),Convert.ToInt32(Eval("pid"))) %>" data-pdf-name="<%# Eval("PdfName") %>" data-name="<%# Eval("Name") %>" data-is-valid="True" > <span><i class="fa fa-file-pdf-o file-icon"></i><%# Eval("PdfName") %></span> </div> </ItemTemplate> </asp:Repeater> </div> </div> </div> </form> <script> let pdfDoc = null; let zoom = 1.0; let isRendering = false; let loadTimer = null; let baseScale = 1.0; let renderedPages = 0; let totalPages = 0; let currentPdfUrl = null; let lastClickTime = 0; let clickTimeout = null; let isZoomed = false; let originalZoom = 1.0; let lastDoubleClickData = null; let pdfContainer, loadingTip, pdfPreviewContainer; let timeoutTip, progressBar, progressContainer; document.addEventListener('DOMContentLoaded', function () { pdfContainer = document.getElementById('pdfContainer'); loadingTip = document.getElementById('loadingTip'); pdfPreviewContainer = document.getElementById('pdfPreviewContainer'); timeoutTip = document.getElementById('timeoutTip'); progressBar = document.getElementById('progressBar'); progressContainer = document.querySelector('.progress-container'); pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.worker.min.js'; initDefaultPdf(); setupPdfListClickHandlers(); setupDoubleClickZoom(); document.addEventListener('keydown', function (e) { if ((e.ctrlKey && (e.key === 's' || e.key === 'p')) || e.key === 'F12') { e.preventDefault(); return false; } }); // 窗口大小变化时重新渲染 let resizeTimeout; window.addEventListener('resize', function () { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { if (pdfDoc && pdfContainer) { calculateBaseScale(); renderAllPages().then(() => { if (lastDoubleClickData) { centerClickPoint(lastDoubleClickData); } }); } }, 200); }); // 显示PDF列表容器 const pdfListContainer = document.querySelector('.pdf-list-container'); if (pdfListContainer) { pdfListContainer.style.display = 'block'; } }); // 设置双击缩放功能 function setupDoubleClickZoom() { if (!pdfContainer) return; pdfContainer.addEventListener('click', function (e) { const now = Date.now(); const DOUBLE_CLICK_THRESHOLD = 300; if (clickTimeout) { clearTimeout(clickTimeout); } if (now - lastClickTime < DOUBLE_CLICK_THRESHOLD) { handleDoubleClickZoom(e); lastClickTime = 0; } else { lastClickTime = now; clickTimeout = setTimeout(() => { lastClickTime = 0; }, DOUBLE_CLICK_THRESHOLD); } }); } // 处理双击放大/还原 function handleDoubleClickZoom(event) { if (!pdfDoc || !pdfContainer) return; event.preventDefault(); const containerRect = pdfContainer.getBoundingClientRect(); const scrollLeft = pdfContainer.scrollLeft; const scrollTop = pdfContainer.scrollTop; // 计算点击位置(考虑滚动偏移) const clientX = event.clientX; const clientY = event.clientY; const clickX = clientX - containerRect.left + scrollLeft; const clickY = clientY - containerRect.top + scrollTop; // 创建视觉反馈 const highlight = document.createElement('div'); highlight.className = 'zoom-target-highlight'; highlight.style.width = '80px'; highlight.style.height = '80px'; highlight.style.left = `${clientX - containerRect.left - 40}px`; highlight.style.top = `${clientY - containerRect.top - 40}px`; pdfContainer.appendChild(highlight); setTimeout(() => { if (pdfContainer.contains(highlight)) { pdfContainer.removeChild(highlight); } }, 500); // 确定点击的页码和相对位置 const pageData = getClickedPageAndPosition(clickX, clickY); if (!pageData) return; // 保存双击数据 lastDoubleClickData = { targetPageNum: pageData.pageNum, ratioX: pageData.ratioX, ratioY: pageData.ratioY }; // 切换缩放状态 if (!isZoomed) { // 放大操作 originalZoom = zoom; zoom *= 1.5; isZoomed = true; } else { // 还原操作 zoom = originalZoom; isZoomed = false; } renderAllPages(); } // 获取点击的页码和相对位置 - 完全重写版本 function getClickedPageAndPosition(clickX, clickY) { if (!pdfContainer) return null; const pageContainers = pdfContainer.querySelectorAll('.pdf-page-container'); for (let i = 0; i < pageContainers.length; i++) { const page = pageContainers[i]; const pageRect = page.getBoundingClientRect(); const containerRect = pdfContainer.getBoundingClientRect(); // 计算页面在容器内的绝对位置(考虑滚动) const pageAbsoluteTop = page.offsetTop; const pageAbsoluteBottom = pageAbsoluteTop + page.offsetHeight; const pageAbsoluteLeft = page.offsetLeft; const pageAbsoluteRight = pageAbsoluteLeft + page.offsetWidth; // 检查点击是否在当前页面范围内 if (clickY >= pageAbsoluteTop && clickY <= pageAbsoluteBottom && clickX >= pageAbsoluteLeft && clickX <= pageAbsoluteRight) { // 计算在页面内的相对位置 const relativeX = clickX - pageAbsoluteLeft; const relativeY = clickY - pageAbsoluteTop; return { pageNum: i + 1, ratioX: Math.max(0, Math.min(1, relativeX / page.offsetWidth)), ratioY: Math.max(0, Math.min(1, relativeY / page.offsetHeight)) }; } } // 如果没有找到精确匹配的页面,返回第一个页面中心 if (pageContainers.length > 0) { return { pageNum: 1, ratioX: 0.5, ratioY: 0.5 }; } return null; } // 将点击点居中显示 - 完全重写版本 function centerClickPoint(doubleClickData) { if (!pdfContainer || !doubleClickData) return; const { targetPageNum, ratioX, ratioY } = doubleClickData; // 获取所有页面容器 const pageContainers = pdfContainer.querySelectorAll('.pdf-page-container'); if (pageContainers.length === 0) return; // 找到目标页面 const targetPage = pageContainers[targetPageNum - 1]; if (!targetPage) return; // 计算目标页面的绝对位置 const pageTop = targetPage.offsetTop; const pageLeft = targetPage.offsetLeft; const pageWidth = targetPage.offsetWidth; const pageHeight = targetPage.offsetHeight; // 根据比例计算点击点在页面内的位置 const pointInPageX = pageWidth * ratioX; const pointInPageY = pageHeight * ratioY; // 计算点击点在容器内的绝对位置 const absoluteX = pageLeft + pointInPageX; const absoluteY = pageTop + pointInPageY; // 计算需要滚动到的位置,使点击点居中 const containerWidth = pdfContainer.clientWidth; const containerHeight = pdfContainer.clientHeight; const scrollToX = Math.max(0, Math.min(absoluteX - containerWidth / 2, pdfContainer.scrollWidth - containerWidth)); const scrollToY = Math.max(0, Math.min(absoluteY - containerHeight / 2, pdfContainer.scrollHeight - containerHeight)); // 使用requestAnimationFrame确保在渲染完成后执行滚动 requestAnimationFrame(() => { pdfContainer.scrollTo({ left: scrollToX, top: scrollToY, behavior: 'smooth' }); }); } // 设置PDF列表项的点击事件处理 function setupPdfListClickHandlers() { const pdfList = document.getElementById('pdfList'); if (!pdfList) return; pdfList.addEventListener('click', function (e) { const listItem = e.target.closest('.pdf-list-item'); if (!listItem) return; e.preventDefault(); e.stopPropagation(); const isValid = listItem.getAttribute('data-is-valid') === 'True'; if (!isValid) { alert('当前文件链接无效,无法预览'); return; } const pdfUrl = listItem.getAttribute('data-pdf-url'); if (listItem.classList.contains('active') && pdfDoc && pdfUrl === currentPdfUrl) { return; } document.querySelectorAll('.pdf-list-item').forEach(li => li.classList.remove('active')); listItem.classList.add('active'); // 重置缩放状态 zoom = 1.0; isZoomed = false; originalZoom = 1.0; lastDoubleClickData = null; const pdfName = listItem.getAttribute('data-pdf-name'); const name = listItem.getAttribute('data-name'); loadPdf(pdfUrl, pdfName, name); }); } // 初始化默认加载第一个有效PDF function initDefaultPdf() { let defaultItem = document.querySelector('.pdf-list-item[data-is-valid="True"]'); if (!defaultItem) { defaultItem = document.querySelector('.pdf-list-item'); } if (defaultItem) { const pdfUrl = defaultItem.getAttribute('data-pdf-url'); const pdfName = defaultItem.getAttribute('data-pdf-name'); const name = defaultItem.getAttribute('data-name'); defaultItem.classList.add('active'); loadPdf(pdfUrl, pdfName, name); } else if (loadingTip) { loadingTip.innerHTML = '<div class="error-message">没有找到可预览的PDF文件</div>'; } } // 重新加载当前PDF function reloadCurrentPdf() { if (currentPdfUrl) { const activeItem = document.querySelector('.pdf-list-item.active'); if (activeItem) { const pdfName = activeItem.getAttribute('data-pdf-name'); const name = activeItem.getAttribute('data-name'); loadPdf(currentPdfUrl, pdfName, name); } } } // 加载PDF文件 function loadPdf(pdfUrl, pdfName, name) { if (!pdfPreviewContainer || !loadingTip || !timeoutTip || !progressContainer || !progressBar) { console.error('DOM元素未准备好'); return; } currentPdfUrl = pdfUrl; // 重置状态 pdfDoc = null; baseScale = 1.0; renderedPages = 0; totalPages = 0; isZoomed = false; originalZoom = 1.0; lastDoubleClickData = null; // 更新UI loadingTip.style.display = 'flex'; pdfPreviewContainer.style.display = 'block'; timeoutTip.style.display = 'none'; progressContainer.style.display = 'none'; progressBar.style.width = '0%'; document.title = pdfName || '运营报告'; clearTimeout(loadTimer); // 微信环境防缓存 let urlToLoad = pdfUrl; const isWeChat = /MicroMessenger/i.test(navigator.userAgent); if (isWeChat) { urlToLoad += (urlToLoad.includes('?') ? '&' : '?') + 't=' + new Date().getTime(); } // 加载PDF const loadingTask = pdfjsLib.getDocument({ url: urlToLoad, cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/cmaps/', cMapPacked: true, withCredentials: false, timeout: 20000 }); loadingTask.promise.then(function (pdfDoc_) { pdfDoc = pdfDoc_; totalPages = pdfDoc.numPages; calculateBaseScale().then(() => { if (loadingTip) loadingTip.style.display = 'none'; if (progressContainer) progressContainer.style.display = 'block'; renderAllPages(); clearTimeout(loadTimer); }); }).catch(function (error) { console.error('Error loading PDF:', error); if (loadingTip) { loadingTip.innerHTML = ` <div class="error-message"> <span>❌</span> <br>加载失败,请检查文件链接或网络 <br><button class="timeout-retry-btn" onclick="reloadCurrentPdf()">点击重试</button> </div> `; } if (pdfPreviewContainer) pdfPreviewContainer.style.display = 'none'; clearTimeout(loadTimer); }); // 加载超时处理 loadTimer = setTimeout(() => { if (!pdfDoc) { if (loadingTip) loadingTip.style.display = 'none'; if (timeoutTip) { timeoutTip.style.display = 'flex'; timeoutTip.innerHTML = ` <span>❌</span> <br/>PDF加载超时,请检查网络或尝试重新点击 <br><button class="timeout-retry-btn" onclick="reloadCurrentPdf()">点击重试</button> `; } } }, 15000); } function calculateBaseScale() { return new Promise((resolve) => { if (!pdfDoc || !pdfContainer) { baseScale = 1.0; resolve(); return; } const containerWidth = pdfContainer.clientWidth; if (containerWidth <= 0) { baseScale = 1.0; resolve(); return; } pdfDoc.getPage(1).then(function (page) { const viewport = page.getViewport({ scale: 1 }); baseScale = containerWidth / viewport.width; resolve(); }).catch(() => { baseScale = 1.0; resolve(); }); }); } // 渲染所有页面 function renderAllPages() { return new Promise((resolve) => { if (!pdfDoc || isRendering || !pdfContainer) { resolve(); return; } isRendering = true; renderedPages = 0; pdfContainer.innerHTML = ''; const renderPage = (pageNum) => { if (pageNum > pdfDoc.numPages) { isRendering = false; // 所有页面渲染完成后,执行双击定位 setTimeout(() => { if (lastDoubleClickData) { centerClickPoint(lastDoubleClickData); } resolve(); }, 100); return; } pdfDoc.getPage(pageNum).then(function (page) { const finalScale = baseScale * zoom; const viewport = page.getViewport({ scale: finalScale }); // 适配设备像素比 const dpr = window.devicePixelRatio || 1; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); canvas.width = Math.floor(viewport.width * dpr); canvas.height = Math.floor(viewport.height * dpr); canvas.style.width = `${viewport.width}px`; canvas.style.height = `${viewport.height}px`; context.setTransform(dpr, 0, 0, dpr, 0, 0); const pageContainer = document.createElement('div'); pageContainer.className = 'pdf-page-container'; pageContainer.setAttribute('data-page-number', pageNum); pageContainer.style.marginBottom = '10px'; pageContainer.appendChild(canvas); if (pdfContainer.isConnected) { pdfContainer.appendChild(pageContainer); } else { console.error('pdfContainer不在DOM中'); isRendering = false; resolve(); return; } // 渲染页面 const renderContext = { canvasContext: context, viewport: viewport }; const renderTask = page.render(renderContext); renderTask.promise.then(function () { renderedPages++; if (progressBar) { const progress = (renderedPages / totalPages) * 100; progressBar.style.width = `${progress}%`; } if (renderedPages === totalPages && progressContainer) { setTimeout(() => { progressContainer.style.display = 'none'; }, 500); } // 渲染下一页 renderPage(pageNum + 1); }).catch(function (error) { console.error(`渲染第${pageNum}页失败:`, error); renderedPages++; renderPage(pageNum + 1); }); }).catch(function (error) { console.error(`获取第${pageNum}页失败:`, error); renderPage(pageNum + 1); }); }; renderPage(1); }); } </script> </body> </html>),index.aspx.cs代码(using LiangCeLib.DAL; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text.RegularExpressions; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using Utils; public partial class Report_index : System.Web.UI.Page { ProjectDocumentsDal dalproject = new ProjectDocumentsDal(); CustomerAccountsDal dalAccount = new CustomerAccountsDal(); public class PdfFileModel { public int pid { get; set; } public string PdfName { get; set; } public string PdfUrl { get; set; } public string Name { get; set; } public bool IsValid { get; set; } // 标记PDF是否有效 } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { var id = SL.GetQueryIntValue("id"); if (id == 0) { id = 1; } BindPdfList(id); } if (!string.IsNullOrEmpty(Request.QueryString["pdfUrl"])) { ProxyPdfFile(); Response.End(); } } private void BindPdfList(int id) { var model = dalproject.GetPDF(id); // 确保列表按创建时间倒序排列(最新的在前面) List<PdfFileModel> pdfList = model .OrderByDescending(item => item.CREATETIME) .Select(item => new PdfFileModel { pid = item.pid, PdfName = FormatReportTitle(item.projectName, item.CREATETIME, item.PDFILEURL), PdfUrl = "http://www.black-jet.cn" + item.PDFILEURL, Name = item.projectName, IsValid = IsValidPdfUrl("http://www.black-jet.cn" + item.PDFILEURL) }).ToList(); rptPdfList.DataSource = pdfList; rptPdfList.DataBind(); } protected string GetProxyUrl(string originalUrl, int pid) { string encodedUrl = HttpUtility.UrlEncode(originalUrl); string currentPagePath = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath + "?id=" + pid; string absolutePagePath = VirtualPathUtility.ToAbsolute(currentPagePath); return absolutePagePath + "&pdfUrl=" + encodedUrl; } private void ProxyPdfFile() { try { string encodedPdfUrl = Request.QueryString["pdfUrl"]; string pdfUrl = HttpUtility.UrlDecode(encodedPdfUrl); if (string.IsNullOrEmpty(pdfUrl)) { Response.StatusCode = 400; Response.Write("无效的PDF链接,请检查链接格式"); return; } HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pdfUrl); request.Method = "GET"; request.Timeout = 20000; request.UserAgent = "Mozilla/5.0 (Linux; Android 10; MI 9 SE Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/86.0.4240.99 XWEB/3263 MMWEBSDK/20220401 Mobile Safari/537.36 MMWEBID/6505 MicroMessenger/8.0.24.2120(0x28001857) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64"; request.Accept = "application/pdf,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; request.AllowAutoRedirect = true; using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { if (!response.ContentType.Contains("application/pdf") && !response.ContentType.Contains("application/octet-stream")) { Response.StatusCode = 415; Response.Write("文件不是有效的PDF格式,当前类型:" + response.ContentType); return; } Response.ContentType = "application/pdf"; string fileName = System.IO.Path.GetFileName(pdfUrl); Response.AddHeader("Content-Disposition", "inline; filename=\"" + fileName + "\""); Response.AddHeader("Content-Length", response.ContentLength.ToString()); Response.AddHeader("Cache-Control", "public, must-revalidate, max-age=0"); Response.AddHeader("Pragma", "public"); Response.AddHeader("X-Content-Type-Options", "nosniff"); Response.AddHeader("Accept-Ranges", "bytes"); Response.AddHeader("X-Download-Options", "noopen"); using (var stream = response.GetResponseStream()) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { Response.OutputStream.Write(buffer, 0, bytesRead); } } Response.Flush(); } } catch (WebException ex) { Response.StatusCode = 500; Response.Write("PDF加载失败:" + ex.Message); if (ex.Response != null) { Response.Write("(HTTP状态码:" + ((HttpWebResponse)ex.Response).StatusCode + ")"); } } catch (Exception ex) { Response.StatusCode = 500; Response.Write("服务器处理错误:" + ex.Message); } } protected bool IsValidPdfUrl(string pdfUrl) { try { if (!Uri.IsWellFormedUriString(pdfUrl, UriKind.Absolute)) return false; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pdfUrl); try { request.Method = "HEAD"; request.Timeout = 5000; request.UserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"; using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { return response.StatusCode == HttpStatusCode.OK && (response.ContentType.Contains("application/pdf") || response.ContentType.Contains("application/octet-stream")); } } catch { request.Method = "GET"; request.Timeout = 5000; request.AddRange(0, 99); using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { return response.StatusCode == HttpStatusCode.PartialContent || response.StatusCode == HttpStatusCode.OK; } } } catch { return false; } } private string FormatReportTitle(string companyName, DateTime dateString, string PDFILEURL) { try { DateTime reportDate = dateString; int year = reportDate.Year; return companyName + "技术运营报告(" + (ExtractMonthFromFilePath(PDFILEURL)) + ")- " + year; } catch (Exception ex) { Console.WriteLine("日期格式错误: " + ex.Message); return companyName + "技术运营报告"; } } private string ExtractMonthFromFilePath(string filePath) { if (string.IsNullOrEmpty(filePath)) return null; Match match = Regex.Match(filePath, @"\d+月"); if (match.Success) { return match.Value; } Match dateMatch = Regex.Match(filePath, @"\d{8}"); if (dateMatch.Success && dateMatch.Value.Length == 8) { string monthPart = dateMatch.Value.Substring(4, 2); return int.Parse(monthPart) + "月"; } return null; } }),双击放大,双击点显示在页面中间,没有问题。但双击还原缩小后没有显示将双击点显示在页面中间。修改以上代码,实现双击还原后,双击点保持在页面中心。生成完整代码
最新发布
10-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值