非IE MAC平台下window.print出现空白页的解决办法

本文探讨了在不同浏览器和操作系统下使用JavaScript实现网页打印时遇到的问题及解决方法,包括预览与实际打印效果差异、多页打印排版错位、连续打印出现空白页等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前在IE下用window.print实现打印由于有active等IE特性的强大功能,打印都比较简单。但是在FF,SAFARI,CHROME,以及MAC操作系统下用js实现打印会出现很多莫名其妙的问题。

1 预览和真实打印效果不同。

在不同操作系统不同浏览器及版本下,这是很正常的。以最终目标打印结果为标准。

 

2 多页打印的排版错位。

采用table动态生成tr td内容项拼凑出打印内容,但是这种效果即使预览OK了打印出来都可能是错位的。放弃这种做法。

 

3 连续打印会出现空白页。

连续打印即动态更新打印内容,(排版固定)将新的内容替换旧的内容再依次循环执行window.print。

出现空白页的原因是没有设置page-break-before和page-breake-after为avolid。

 

4 将web程序嵌入MAC XCOED程序的配置问题。

将MAC下的XCODE程序嵌入web应用,并配置打印设置的配置文件:

 

 

 

#import "mainView.h"

 

@implementation mainView

@synthesize cursorArea;

 

- (IBAction)reloadHome:(NSButton *)sender {

    [[mainWebView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://access.nmg.com.hk/"]]];

}

 

-(void)awakeFromNib{

[backGroundView setEnabled:TRUE];

//[mainWebView initWithFrame:[[NSScreen mainScreen]frame]];

[mainWebView autoresizesSubviews];

[mainWebView setFrameLoadDelegate:self];

[mainWebView setPolicyDelegate:self];

[mainWebView setUIDelegate:self];

[mainWebView setEditable:FALSE];

[[mainWebView preferences] setJavaEnabled:TRUE];

[[mainWebView preferences] setJavaScriptEnabled:TRUE];

[[mainWebView preferences] setPlugInsEnabled:TRUE];

[[mainWebView preferences] setUsesPageCache:TRUE];

[[mainWebView preferences] setJavaScriptCanOpenWindowsAutomatically:TRUE];

[[mainWebView preferences] setAllowsAnimatedImages:TRUE];

[[mainWebView preferences] setAllowsAnimatedImageLooping:TRUE];

[[mainWebView preferences] setLoadsImagesAutomatically:TRUE];

[[mainWebView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://access.nmg.com.hk/"]]];

//cursorArea = [[NSTrackingArea alloc] initWithRect:NSMakeRect(0, 0, [[NSScreen mainScreen] frame].size.width, 3) options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];

    //[self addTrackingArea:cursorArea];

}

 

-(void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message

{

NSAlert *alert = [NSAlert alertWithMessageText:nil

defaultButton:@"OK"

  alternateButton:nil

  otherButton:nil

informativeTextWithFormat:@"%@",message

 ];

 

[alert setAlertStyle:NSWarningAlertStyle];

[alert beginSheetModalForWindow:[sender window]

 modalDelegate:self

didEndSelector:@selector(endAlert)

contextInfo:nil];

}

 

-(void)endAlert

{

NSLog(@"end");

}

 

- (void)moveTrackingAreaup {

[super updateTrackingAreas];

[self removeTrackingArea:cursorArea];

cursorArea = [[NSTrackingArea alloc] initWithRect:NSMakeRect(0, 0, [[NSScreen mainScreen] frame].size.width, 60) options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];

[self addTrackingArea:cursorArea];

}

 

-(void)moveTrackingAreadown{

[super updateTrackingAreas];

[self removeTrackingArea:cursorArea];

cursorArea = [[NSTrackingArea alloc] initWithRect:NSMakeRect(0, 0, [[NSScreen mainScreen] frame].size.width, 3) options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];

[self addTrackingArea:cursorArea];

}

 

/*- (void)mouseEntered:(NSEvent *)event

{

[[mainWebView animator] setFrameOrigin:NSMakePoint([mainWebView frame].origin.x,60)];

[[buttonControlView animator] setAlphaValue:1];

//if ([backGroundView isEnabled] == FALSE) {

// [backGroundView setEnabled:TRUE];

// }

[self performSelector:@selector(moveTrackingAreaup)];

}*/

 

-(void)hideFunction{

if ([backGroundView isEnabled] == TRUE) {

[backGroundView setEnabled:FALSE];

}

}

 

/*- (void)mouseExited:(NSEvent *)event{

[self performSelector:@selector(moveTrackingAreadown)];

[[mainWebView animator] setFrameOrigin:NSMakePoint([[NSScreen mainScreen] frame].origin.x,[[NSScreen mainScreen] frame].origin.y)];

[[buttonControlView animator] setAlphaValue:0];

// [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(hideFunction) userInfo:nil repeats:NO];

}*/

 

//-(void)dealloc{

// [super dealloc];

//}

 

#pragma mark - WebUIDelegate

- (void)webView:(WebView *)sender printFrameView:(WebFrameView *)frameView

{

    if ([frameView documentViewShouldHandlePrint]) {

        [frameView printDocumentView];

    } else {

        NSPrintInfo *printInfo;

        NSPrintOperation *printOp; 

        NSMutableDictionary *printInfoDict;

 

        printInfoDict = [NSMutableDictionary dictionaryWithDictionary: 

                         [[NSPrintInfo sharedPrintInfo] dictionary]]; 

 

        [printInfoDict setObject:NSPrintSpoolJob forKey:NSPrintJobDisposition];

 

        printInfo = [[NSPrintInfo alloc] initWithDictionary: printInfoDict]; 

       // [printInfo setHorizontalPagination: NSFitPagination]; 

//        [printInfo setVerticalPagination: NSFitPagination]; 

[printInfo setHorizontalPagination: NSClipPagination];

[printInfo setVerticalPagination: NSClipPagination];

      //  [printInfo setVerticallyCentered:NO];

        [printInfo setOrientation:NSLandscapeOrientation];

        [printInfo setLeftMargin:-5];

        [printInfo setTopMargin:0];

[printInfo setRightMargin:0];

        [printInfo setBottomMargin:-30];

[printInfo setPaperSize:NSMakeSize(120, 240)];

[printInfo setScalingFactor:1];

 

        printOp = [NSPrintOperation printOperationWithView:[frameView documentView]  

                                                 printInfo:printInfo]; 

        [printOp setShowsPrintPanel:NO]; 

        [printOp runOperation];

    }

}

 

@end


配置项比较直观,能看得懂。

5 内容采用下拉框(动态显示)和直接显示(静态)的打印效果不同

采用下拉框动态显示会出现如果打多页第一页就是空白页。而静态不会。(后来证实,只有6页以上才不会,2-5页都会有空白页)。同样是page-breake的问题。

 

6 显示打印内容隐藏不打印内容

使用两个css文件。一个main.css一个print.css。
<link href="style/main.css" rel="stylesheet" type="text/css" media="screen"/>
<link href="style/print.css" rel="stylesheet" type="text/css" media="print"/>

打印时使用print.css。在print.css中将要隐藏的内容都隐藏了,要打印的显示出来。这时会显示打印的内容会使页面看起来比较乱。但是如果是直接打印不需要预览则不会看到(速度快)。预览的话还是建议新窗口显示预览结果。

### 关于 `window.print` 出现重复页面的问题 当使用 `window.print()` 方法打印网页时,可能会遇到页面内容被错误地重复打印的情况。这通常是因为 CSS 样式设置不当或是 HTML 结构中的某些元素未能正确处理分页。 为了防止这种情况发生,可以采取以下几种方法来优化打印效果: #### 使用 `@media print` 调整样式 通过定义专门用于打印的CSS规则,能够更好地控制哪些部分应该出现在最终输出中以及如何布局这些内容。特别是对于不需要打印的内容可以直接隐藏掉,从而减少不必要的重复项。 ```css @media print { .no-print { display: none !important; } } ``` 这样做的好处是可以精确指定那些仅限屏幕显示而不参与实际物理介质上的呈现的部分[^4]。 #### 设置合适的分页符 如果文档结构较为复杂,则可能需要显式指明各个逻辑单元之间的边界位置。利用 `page-break-before`, `page-break-after` 或者更现代的标准 `break-before`, `break-after` 属性可以帮助实现这一点。例如,在两个主要区块之间插入强制性的断开点以确保它们不会跨过单张纸上展示: ```html <div class="section"> <!-- 第一部分 --> </div> <div style="break-after: always;"></div> <!-- 强制换页 --> <div class="section"> <!-- 下一部分 --> </div> ``` 这种方法有助于保持每一页内的条理清晰并避免意外重叠或缺失。 #### 清除浮动与清除固定定位的影响 有时浮动静态元素或者绝对/相对定位于父容器之外的对象也可能引起渲染异常进而造成重复现象。因此建议在准备进入打印模式前先移除此类影响因素: ```javascript function prepareForPrint() { document.querySelectorAll('.floating-element').forEach(el => el.style.position = 'static'); } // 在调用 window.print 前执行此函数 prepareForPrint(); window.print(); ``` 以上措施综合运用可有效改善由 `window.print()` 导致的重复页面问题,并提高整体用户体验的质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值