精华内容
下载资源
问答
  • 解决360浏览器兼容模式不兼容,极速模式兼容问题

    解决360浏览器兼容模式不兼容,极速模式兼容问题

    参考文章:

    (1)解决360浏览器兼容模式不兼容,极速模式兼容问题

    (2)https://www.cnblogs.com/longronglang/p/6877593.html


    备忘一下。


    展开全文
  • 文章目录I、问题分析II、使用方法交换,全局修改see also 今天升级最新IDE Xcode,准备适配iOS14 API,结果发现app首页的cell中按钮也无法点击了。 I、问题分析 iOS14 UITableViewCell的子试图不能点击或者滑动等...

    前言

    今天升级最新IDE Xcode,准备适配iOS14 API,结果发现app首页的cell中按钮也无法点击了。

    I、问题分析

    iOS14 UITableViewCell的子试图不能点击或者滑动等手势响应问题,发现有问题的cell基本都是直接

    cell.addSubView(tempView1)
    
    

    这种方式添加的,通过Xcode自带的DebugViewHierarchy视图分析发现问题的原因是:被系统自带的UITableViewCellContentView遮挡在底部了

    在这里插入图片描述

    在这里插入图片描述

    所以需要改规范的做法

    cell.contentView.addSubView(tempView1)
    
    

    温馨提示:如果你用旧版的Xcode打包,而非使用Xcode12以上版本编译打包的话,是不会有问题。一旦你使用了Xcode12打包,就会出现此问题。(但是苹果迟早会限制高于Xcode12才可以上传appstore,所以一旦使用了不规范的代码,早晚都要面临这个问题

    1.0 其他分析视图层级的方法:私有API _printHierarchy 和recursiveDescription

    关于视图层级分析你也可以使用私有API _printHierarchyrecursiveDescription 在lldb 窗口进行分析:

    例如先打印VC层级(lldb) po [[[UIWindow keyWindow] rootViewController] _printHierarchy]

    再使用目标View的地址进行recursiveDescription打印子视图的层级。

    • po [0x10ff5e5e0 recursiveDescription]
    (lldb) po [0x10ff5e5e0 recursiveDescription]
    <UITableViewCell: 0x10ff5e5e0; frame = (0 767.5; 375 120); hidden = YES; autoresize = W; layer = <CAGradientLayer: 0x280b80860>>
       | <_UISystemBackgroundView: 0x10fe2d170; frame = (0 0; 375 120); layer = <CAGradientLayer: 0x280c58500>; configuration = <UIBackgroundConfiguration: 0x283aa54a0; Base Style = List Grouped Cell; backgroundColor = <UIDynamicSystemColor: 0x2818d3140; name = tableCellGroupedBackgroundColor>>>
       |    | <UIView: 0x10fe2d310; frame = (0 0; 375 120); clipsToBounds = YES; layer = <CAGradientLayer: 0x280c58640>>
       | <UIView: 0x10ff9a820; frame = (0 0; 375 120); layer = <CAGradientLayer: 0x280b9db60>>
       |    | <UIButton: 0x10ff9ab10; frame = (17 0; 170.5 60); opaque = NO; layer = <CAGradientLayer: 0x280b9dc40>>
       |    |    | <UIImageView: 0x10fe70710; frame = (0 16; 28 28); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280be9520>>
       |    |    | <UIButtonLabel: 0x10ff9af70; frame = (38 21.5; 86 17); text = '商户交易汇总'; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b9dc80>>
       |    | <UIButton: 0x10ff9bd40; frame = (187.5 0; 170.5 60); opaque = NO; tag = 1; layer = <CAGradientLayer: 0x280b9e1c0>>
       |    |    | <UIImageView: 0x10ffacfd0; frame = (0 16; 28 28); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b93220>>
       |    |    | <UIButtonLabel: 0x10ff9c1a0; frame = (38 21.5; 100 17); text = '代理商交易汇总'; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b9e340>>
       |    | <UIButton: 0x10ff9cda0; frame = (17 60; 170.5 60); opaque = NO; tag = 2; layer = <CAGradientLayer: 0x280b9e540>>
       |    |    | <UIImageView: 0x10ffab1f0; frame = (0 16; 28 28); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b92f40>>
       |    |    | <UIButtonLabel: 0x10ff9d200; frame = (38 21.5; 86 17); text = '终端激活汇总'; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b9e680>>
       |    | <UIButton: 0x10ff9db20; frame = (187.5 60; 170.5 60); opaque = NO; tag = 3; layer = <CAGradientLayer: 0x280b9ea20>>
       |    |    | <UIImageView: 0x10ffa95d0; frame = (0 16; 28 28); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b92ce0>>
       |    |    | <UIButtonLabel: 0x10ff9df80; frame = (38 21.5; 86 17); text = '商户终端汇总'; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b9eb80>>
       |    | <UIView: 0x10ff9e8a0; frame = (15 60; 345 0.5); layer = <CAGradientLayer: 0x280b9ef00>>
       |    | <UIView: 0x10ff9ea10; frame = (15 120; 345 0.5); layer = <CAGradientLayer: 0x280b9f0c0>>
       | <UITableViewCellContentView: 0x10ffaafa0; frame = (0 0; 375 120); gestureRecognizers = <NSArray: 0x281fc73c0>; layer = <CAGradientLayer: 0x280b808e0>>
       |    | <UIImageView: 0x110f07d00; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b7e220>>
    
    
    
    

    1.1 注意事项

    因为此问题涉及的是添加子视图cell.addSubView,因此与之对应的方法(UITableViewCell *)[SubView superview]cell.subviews 都要注意谨慎使用和处理

    II、使用方法交换,全局修改

    如果错误代码比较多,可以采用hook,进行便捷的方法进行修改。

    例如125个文件的1452个地方使用错误的方法,这个如果不使用hook高质工作量有点大在这里插入图片描述
    所以通过Runtime hook cell的addSubView 方法强制修改为正确的添加cell 子视图的方式

    2.1 全局修改

    • 只允许添加 UITableViewCellContentView,其余都直接添加到self.contentView
    //
    //  UITableViewCell+CRMaddSubView.m
    //  Housekeeper
    //
    //  Created by mac on 2020/9/18.
    //  Copyright © 2020 QCT. All rights reserved.
    //
    
    #import "UITableViewCell+CRMaddSubView.h"
    
    @implementation UITableViewCell (CRMaddSubView)
    + (void)load {
        // Swizzle addSubView
        [UITableViewCell sensorsdata_swizzleMethod:@selector(addSubview:) withMethod:@selector(kunnan_addSubview:)];
        
    }
    
    - (void)kunnan_addSubview:(UIView *)view {
    
        
        
        if  ([view isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {//允许 addSubView UITableViewCellContentView 
            
            [self kunnan_addSubview:view];//实现方法,因为已经进行了 swizzle,相当于调用原来的方法
            
    
            
        } else {
            
            [self.contentView addSubview:view];
            
        }
    
    
    
    }
    
    
    
    @end
    
    

    2.2 注意事项

    因为此问题涉及的是添加子视图cell.addSubView,因此与之对应的方法(UITableViewCell *)[SubView superview] 和cell.subviews 都要注意谨慎使用和处理

    具体例子如下2.2.1 和2.2.2

    2.2.1 cell.subviews

    因为这是针对全局的,所以测试的覆盖面也要广。 比如获取子视图采用cell.subviews 也要记得修改为 cell.contentView.subviews.

        UIButton * btn = cell.contentView.subviews[2-1];
    
    

    2.2.2 通过superview 获取cell的也需做相关修改

    • 经过全局hook之后,以下的代码就是错误的
      (UITableViewCell *)[textField superview]

    • 全局搜索进行修改
      在这里插入图片描述

            UITableViewCell * myCell = (UITableViewCell *)[textField superview].superview;
    
    

    所以使用class的时候,最好写得健壮性强点,进行类型判断,避免一旦类型错误,就会找不到对应的方法,发送闪退

        UIView * textFieldsuperview = [textField superview];
        UITableViewCell * myCell = nil;
        
        if([textFieldsuperview isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]){
            
            
            
             myCell= (UITableViewCell *)[textFieldsuperview superview];
    
        }else{
            
            return;
            
            
        }
        
    
    

    能遇见这样的奇葩代码,只能说之前的同事很”牛逼啊。。。。“

    2.3 使用到的工具类

    • h
    //
    //  NSObject+CRMSwizzling.h
    //  Housekeeper
    //
    //  Created by mac on 2020/9/18.
    //  Copyright © 2020 QCT. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    typedef IMP *IMPPointer;
    /**
     让所有继承自NSObject的子类,都具有Method Swizzling的能力。
     */
    
    @interface NSObject (CRMSwizzling)
    
    
    /**
    交换方法名为 originalSEL 和方法名为 alternateSEL 两个方法的实现
    @param originalSEL 原始方法名
    @param alternateSEL 要交换的方法名称
    */
    + (BOOL)sensorsdata_swizzleMethod:(SEL)originalSEL withMethod:(SEL)alternateSEL;
    
    
    
    
    /**
     方式二
     */
    + (BOOL)swizzle:(SEL)original with:(IMP)replacement store:(out IMPPointer)store;
    
    
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    • m
    //
    //  NSObject+CRMSwizzling.m
    //  Housekeeper
    //
    //  Created by mac on 2020/9/18.
    //  Copyright © 2020 QCT. All rights reserved.
    //
    
    #import <objc/runtime.h>
    #import <objc/message.h>
    
    
    #import "NSObject+CRMSwizzling.h"
    
    BOOL class_swizzleMethodAndStore(Class class, SEL original, IMP replacement, IMPPointer store);
    
    BOOL class_swizzleMethodAndStore(Class class, SEL original, IMP replacement, IMPPointer store) {
        
        IMP imp = NULL;
        Method method = class_getInstanceMethod(class, original);
        
        if (method) {
            
            const char *type = method_getTypeEncoding(method);
            imp = class_replaceMethod(class, original, replacement, type);
            
            
            if (!imp) {
                
                imp = method_getImplementation(method);
                
            }
        }
        if (imp && store) {
            *store = imp;
        }
        return (imp != NULL);
    }
    
    
    
        
    @implementation NSObject (CRMSwizzling)
    
    + (BOOL)sensorsdata_swizzleMethod:(SEL)originalSEL withMethod:(SEL)alternateSEL {
        // 获取原始方法
        Method originalMethod = class_getInstanceMethod(self, originalSEL);
        // 当原始方法不存在时,返回 NO,表示 Swizzling 失败
        if (!originalMethod) {
            return NO;
        }
    
        // 获取要交换的方法
        Method alternateMethod = class_getInstanceMethod(self, alternateSEL);
        // 当要交换的方法不存在时,返回 NO,表示 Swizzling 失败
        if (!alternateMethod) {
            return NO;
        }
    
        // 获取 originalSEL 方法的实现
        IMP originalIMP = method_getImplementation(originalMethod);
        // 获取 originalSEL 方法的类型
        const char * originalMethodType = method_getTypeEncoding(originalMethod);
        // 往类中添加 originalSEL 方法,如果已经存在会添加失败,并返回 NO
        if (class_addMethod(self, originalSEL, originalIMP, originalMethodType)) {
            // 如果添加成功了,重新获取 originalSEL 实例方法
            originalMethod = class_getInstanceMethod(self, originalSEL);
        }
    
        // 获取 alternateIMP 方法的实现
        IMP alternateIMP = method_getImplementation(alternateMethod);
        // 获取 alternateIMP 方法的类型
        const char * alternateMethodType = method_getTypeEncoding(alternateMethod);
        // 往类中添加 alternateIMP 方法,如果已经存在会添加失败,并返回 NO
        if (class_addMethod(self, alternateSEL, alternateIMP, alternateMethodType)) {
            // 如果添加成功了,重新获取 alternateIMP 实例方法
            alternateMethod = class_getInstanceMethod(self, alternateSEL);
        }
    
        // 交换两个方法的实现
        method_exchangeImplementations(originalMethod, alternateMethod);
    
        // 返回 YES,表示 Swizzling 成功
        return YES;
    }
    
    
    
    + (BOOL)swizzle:(SEL)original with:(IMP)replacement store:(out IMPPointer)store {
        return class_swizzleMethodAndStore(self, original, replacement, store);
    }
    
    
    
    @end
    
    

    III、逆向相关

    3.1 iOS 恢复调用栈(适配iOS14)

    原理:objective-c 函数信息除了保存在符号表中,还保存在其他段中

    https://github.com/zhangkn/restore-symbol4iOS14
    __TEXT.__objc_methname - Method names for locally implemented methods
    __TEXT.__objc_classname - Names for locally implemented classes
    __TEXT.__objc_methtype - Types for locally implemented method types
    __DATA.__objc_classlist - An array of pointers to ObjC classes
    __DATA.__objc_nlclslist - An array of pointers to classes who implement +load
    __DATA.__objc_catlist - List of ObjC categories
    __DATA.__objc_protolist - List of ObjC protocols
    __DATA.__objc_imageinfo - Version info, not really useful
    __DATA.__objc_const - Constant data, i.e. class_ro_t data
    __DATA.__objc_selrefs - External references to selectors
    __DATA.__objc_protorefs - External references to protocols
    __DATA.__objc_classrefs - External references to other classes
    __DATA.__objc_superrefs - External references to super classes
    __DATA.__objc_ivar - Offsets to ObjC properties
    __DATA.__objc_data - Misc ObjC storage, notably ObjC classes

    see also

    extension UITableViewCell {
        
        class func ios14Bug() {
            
            let sel1 = #selector(UITableViewCell.runtime_addSubview(_:))
            let sel2 = #selector(UITableViewCell.addSubview(_:))
            
            let method1 = class_getInstanceMethod(UITableViewCell.self, sel1)!
            let method2 = class_getInstanceMethod(UITableViewCell.self, sel2)!
            
            let isDid: Bool = class_addMethod(self, sel2, method_getImplementation(method1), method_getTypeEncoding(method1))
            if isDid {
                class_replaceMethod(self, sel1, method_getImplementation(method2), method_getTypeEncoding(method2))
            } else {
                method_exchangeImplementations(method2, method1)
            }
        }
        
        @objc func runtime_addSubview(_ view: UIView) {
            // 判断不让 UITableViewCellContentView addSubView自己
            if view.isKind(of: NSClassFromString("UITableViewCellContentView")!) {
                runtime_addSubview(view)
            } else {
                self.contentView.addSubview(view)
            }
        }
    }
    
    
    
    

    还发现他的另一个不规范使用cell API导致的问题,具体请看这里

    展开全文
  • 为什么会有兼容问题?由于市场上浏览器种类众多,而不同浏览器其内核亦不尽相同,所以各个浏览器对网页的解析就有一定出入,这也是导致浏览器兼容问题出现的主要原因,我们的网页需要在主流浏览器上正常运行,就需要...

    为什么会有兼容问题?

    由于浏览器种类众多,不同的浏览器其内核亦不尽相同,故各个浏览器对网页的解析有一定出入,这也是导致浏览器兼容问题出现的主要原因,我们的网页需要在主流浏览器上正常运行,就需要做好浏览器兼容。

    • 使用Trident内核的浏览器:IE、Maxthon、TT
    • 使用Gecko内核的浏览器:Netcape6及以上版本、FireFox
    • 使用Presto内核的浏览器:Opera7及以上版本;
    • 使用Webkit内核的浏览器:Safari、Chrome

    现在说的兼容性问题,主要是说IE与几个主流浏览器如firefox,google等。而对IE浏览器来说,IE7又是个跨度,因为之前的版本更新甚慢,bug甚多。从IE8开始,IE浏览器渐渐遵循标准,到IE9后由于大家都一致认为标准很重要,可以说在兼容性上比较好,但在中国来说,由于xp的占有率问题,使用IE7以下的用户仍然很多,所以不得不考虑低版本浏览器的兼容。

    对浏览器兼容问题,一般分,HTML,Javascript兼容,CSS兼容。 其中html相关问题较容易处理,无非是高版本浏览器用了低版本浏览器无法识别的元素,致其不能解析,所以平时注意一点。特别是HTML5增加了许多新标签,低版本浏览器有点影响时代进步啊

    问题一:不同浏览器的标签默认的外补丁和内补丁不同

    • 问题症状:随便写几个标签,不加样式控制的情况下,各自的marginpadding差异较大。
    • 碰到频率: 100%
    • 解决方案:css*{margin:0;padding:0;}
    • 备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的css文件开头都会用通配符*来设置各个标签的内外补丁是0

    问题二:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大

    • 问题症状:常见症状是ie6中后面的一块被顶到下一行
    • 碰到频率:90%(稍微复杂点的页面都会碰到,float布局最常见的浏览器兼容问题)
    • 解决方案:在float的标签样式控制中加入 display:inline;将其转化为行内属性
    • 备注:我们最常用的就是div+css布局了,而div就是个典型的块属性标签,横向布局的时候我们通常都是用div float实现的,横向的间距设置如果用margin实现,这是个必然会碰到的兼容性问题。

    问题三:设置较小高度标签(一般小于10px),在ie6,ie7,遨游中高度超出自己设置高度

    • 问题症状:ie6、7和遨游里这个标签的高度不受控制,超出自己设置的高度
    • 碰到频率:60%
    • 解决方案:给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度。
    • 备注:这一般出现在我们设置小圆角背景的标签里。出现这个问题的原因是ie8之前的浏览器都会给标签一个最小默认的行高的高度。即使你的标签是空的,这个标签的高度还是会达到默认的行高。

    问题四:行内属性标签,设置display:block后采用float布局,又有横行的margin的情况,ie6间距bug(类似第二种)

    • 问题症状:ie6里的间距比超过设置的间距
    • 碰到几率:20%
    • 解决方案:在display:block;后面加入display:inline;display:table;
    • 备注:行内属性标签,为设置宽高,我们需要设置display:block;(除input标签比较特殊)。在用float布局并有横向的margin后,在ie6下,他就具有了块属性float后的横向marginbug。不过因它本身就是行内属性标签,所以我们再加上display:inline的话,它的高宽就不可设了。这时候我们还需要在display:inline后面加入display:talbe

    问题五:图片默认有间距

    • 问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,加上问题一中提到的通配符也不起作用。
    • 碰到几率:20%
    • 解决方案:使用float属性为img布局
    • 备注:因img标签是行内属性标签,所以只要不超出容器宽度,img标签都会排在一行里,但是部分浏览器的img标签之间会有个间距。去掉这个间距使用float是王道

    问题六:标签最低高度设置min-height不兼容

    • 问题症状:因为min-height本身就是一个不兼容的css属性,所以设置min-height时不能很好的被各个浏览器兼容
    • 碰到几率:5%
    • 解决方案:如果我们要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !important; height:200px; overflow:visible;}
    • 备注:在B/S系统前端开时,有很多情况下我们有这种需求。当内容小于一个值(如300px)时。容器高度为300px;当内容高度大于这个值时,容器高度被撑高,而不是出现滚动条。这时候我们就会面临这个兼容性问题。

    问题七:透明度的兼容css设置

    方法是:每写一小段代码(布局中的一行或者一块)我们都要在不同的浏览器中看是否兼容,当然熟练到一定的程度就没这么麻烦了。建议经常
    会碰到兼容性问题的新手使用。很多兼容性问题都是因为浏览器对标签的默认属性解析不同造成的,只要我们稍加设置都能轻松地解决这些兼容
    问题。如果我们熟悉标签的默认属性的话,就能很好的理解为什么会出现兼容问题以及怎么去解决这些兼容问题。
    


    技巧一:css hack

    使用hack 我可以把浏览器分为3类:ie6 ;ie7和遨游;其他(ie8 chrome ff safari opera等)

    • ie6认识的hack 是下划线_ 和星号 *
    • ie7 遨游认识的hack是星号 * (包括上面问题6中的 !important也算是hack的一种。不过实用性较小。)
    比如这样一个css设置 height:300px;*height:200px;_height:100px;
    ie6浏览器在读到 height:300px的时候会认为高时300px;继续往下读,他也认识*heihgt, 所以当ie6读到*height:200px的时候会覆盖掉
    前一条的相冲突设置,认为高度是200px。继续往下读,ie6还认识_height,所以他又会覆盖掉200px高的设置,把高度设置为100px;
    ie7和遨游也是一样的从高度300px的设置往下读。当它们读到*height200px的时候就停下了,因为它们不认识_height。所以它们会把高度
    解析为200px;剩下的浏览器只认识第一个height:300px;所以他们会把高度解析为300px。
    

    因为优先级相同且相冲突的属性设置后一个会覆盖掉前一个,所以书写的次序是很重要的。

    /* CSS属性级Hack */ 
    color:red; /* 所有浏览器可识别*/
    
    _color:red; /* 仅IE6 识别 */
    
    *color:red; /* IE6、IE7 识别 */
    
    +color:red; /* IE6、IE7 识别 */
    
    *+color:red; /* IE6、IE7 识别 */
    
    [color:red; /* IE6、IE7 识别 */ 
    
    color:red\9; /* IE6、IE7、IE8、IE9 识别 */
    
    color:red\0; /* IE8、IE9 识别*/
    
    color:red\9\0; /* 仅IE9识别 */
    
    color:red \0; /* 仅IE9识别 */
    
    color:red!important; /* IE6 不识别!important 有危险*/
    
    /* CSS选择符级Hack */ 
    *html #demo { color:red;} /* 仅IE6 识别 */
    
    *+html #demo { color:red;} /* 仅IE7 识别 */
    
    body:nth-of-type(1) #demo { color:red;} /* IE9+、FF3.5+、Chrome、Safari、Opera 可以识别 
    */ 
    head:first-child+body #demo { color:red; } /* IE7+、FF、Chrome、Safari、Opera 可以识别 */
    
    :root #demo { color:red\9; } : /* 仅IE9识别 */
    

    越少的浮动,就会越少的代码,会有更灵活的页面,会有扩展性更强的页面。这不多说,归结为到一定水平了,浮动会用的较少。另外,您也会避免使用浮动+margin的用法。所以,越后来越不易遇到这种bug

    技巧二:padding,marign,height,width

    注意是技巧,不是方法: 写好标准头 http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> http://www.w3.org/1999/xhtml”> 尽量用padding,慎用marginheight尽量补上100%,父级height有定值子级height不用100%,子级全为浮动时底部补个空clear:bothdiv宽尽量用margin,慎用paddingwidth算准实际要的减去padding

    技巧三:显示类(display:block,inline)

    display:block,inline两个元素
    
    display:block; //可以为内嵌元素模拟为块元素
    
    display:inline; //实现同一行排列的的效果
    
    display:table; //for FF,模拟table的效果
    

    display:block块元素,元素的特点是: 总是在新行上开始;高度,行高以及顶和底边距都可控制;宽度缺省是它的容器的100%,除非设定一个宽度

    display:inline就是将元素显示为行内元素,元素的特点是:和其他元素都在一行上;高,行高及顶和底边距不可改变;宽度就是它的文字或图片的宽度,不可改变。span,a,label,input,img,strongeminline 元素的例子

    技巧四:怎样使一个div层居中于浏览器中?

    1)

    <style type="text/css">
    
    <!-- div {
    
    position:absolute;
    
    top:50%;
    
    left:50%;
    
    margin:-100px 0 0 -100px;
    
    width:200px;
    
    height:200px;
    
    border:1px solid red; } -->
    
    </style>
    

    2)div里的内容,IE默认为居中,而FF默认为左对齐,可以尝试增加代码margin: 0 auto;

    技巧五:float的div闭合;清除浮动;自适应高度

    ① 例如:<div id="floatA"><div id="floatB"><div id="NOTfloatC">

    • 这里的NOTfloatC并不希望继续平移,而是希望往下排。(其中floatA、floatB的属性已经设置为float:left;)
    • 这段代码在IE中毫无问题,问题出在FF。原因是NOTfloatC并非float标签,必须将float标签闭合。在<divclass="floatB"><div class="NOTfloatC">之间加上<div class="clear">这个div一定要注意位置,而且必须与两个具有float属性的div同级,之间不能存在嵌套关系,否则会产生异常。并且将clear这种样式定义为为如下即可:.clear{clear:both;}

    ②作为外部 wrapperdiv 不要定死高度,为了让高度能自适应,要在wrapper里面加上overflow:hidden; 当包含floatbox的时候,高度自适应在IE下无效,这时候应该触发IElayout私有属性用zoom:1;可以做到,这样就达到了兼容。
    例如某一个wrapper如下定义:

    .colwrapper{overflow:hidden; zoom:1; margin:5px auto;}
    

    ③对于排版,我们用得最多的css描述可能就是float:left.有的时候我们需要在n栏的float div后面做一个统一的背景,譬如:

    <div id=”page”>
    
    <div id=”left”></div>
    <div id=”center”></div>
    <div id=”right”></div>
    
    </div>
    

    比如我们要将page的背景设置成蓝色,以达到所有三栏的背景颜色是蓝色的目的,但是我们会发现随着left centerright的向下拉长,而page居然保存高度不变,问题来了,原因在于page不是float属性,而我们的page由于要居中,不能设置成float,所以我们应该这样解决:

    <div id=”page”>
    
    <div id=”bg” style=”float:left;width:100%”>
    
    <div id=”left”></div>
    <div id=”center”></div>
    <div id=”right”></div>
    
    </div>
    
    </div>
    

    再嵌入一个float left而宽度是100%的DIV解决之。

    ④万能float 闭合(非常重要!)

    将以下代码加入Global CSS 中,给需要闭合的div加上class="clearfix"即可,屡试不爽。

    /* Clear Fix */ 
    .clearfix:after { content:"."; display:block; height:0; clear:both;visibility:hidden; } 
    .clearfix { display:inline-block; } 
    /* Hide from IE Mac */ 
    .clearfix {display:block;} 
    /* End hide from IE Mac */ 
    /* end of clearfix */
    

    或者这样设置:.hackbox{display:table; //将对象作为块元素级的表格显示}

    技巧六:div嵌套时 y轴上 padding和 marign的问题

    • FFy 轴上 子div 到 父div 的距离为 父padding + 子marign
    • IEy 轴上 子div 到 父div 的距离为 父padding和 子marign里大的一个
    • FFy 轴上 父padding=0border=0 时,子div 到 父div 的距离为0,子marign 作用到 父div 外面

    **技巧七:父级盒子的BFC **

    marign 重合问题: 当两个垂直边界相遇时,它们将形成一个边界。这个边界的高度等于两个发生叠加的边界的高度中的较大者。总的有以下解决方式:

    • 外层 padding
    • 透明边框 border:1px solid transparent;
    • .绝对定位 postion:absolute:
    • 外层DIV overflow:hidden;
    • 内层DIV 加 float:left;display:inline;
    • 外层DIV 有时会用到zoom:1;
    展开全文
  • HTML5 video 标签浏览器兼容问题

    万次阅读 2017-07-21 17:53:21
    HTML5 video 标签浏览器兼容问题 小示例代码地址:https://github.com/danhuan/video-demo IE8、火狐、谷歌测试通过。使用需要注意的问题:1.多种格式视频不可以只有MP4格式,一定要引入Ogg格式视频,否则在火狐上...

    image.png

    小示例代码地址:https://github.com/danhuan/video-demo
    IE8、火狐、谷歌测试通过。

    使用需要注意的问题:

    1.多种格式视频

    不可以只有MP4格式,一定要引入Ogg格式视频,否则在火狐上会不兼容报错。
    推荐个不错的视频格式转换器,下载地址 :http://download.csdn.net/detail/danhuan/9905942

    2.引入html5media.js

    引入html5media.js,可以使兼容IE

    3.如果想要设置视频宽度为百分比%自适应占满容器,注意 video的属性width不可以为百分比%

    注意 不可以 直接在<video> 标签里面加width = “100%”,因为的属性width只支持像素值,不支持百分比。虽然<video width = "100%"> 在谷歌火狐浏览器中可以正确显示,但是在IE中会不兼容,导致无法播放视频。
    如果想要设置视频宽度为百分比%自适应占满容器,可以 通过内部样式<style>...</style>或外部样式<link rel="stylesheet" href="CSS文件路径" />设置,但 不可以 通过内联样式style="width:100%" 设置样式,否则不兼容IE。

    4.如果视频是固定宽高,则可以直接在属性中设置,千万注意不要加单位px,否则IE不兼容。

    正确示例如下:

    <video width="1000" height="500" controls autoplay="true" loop="true" preload="auto">
    

    错误示例如下:

    <video width="1000px" height="500px" controls autoplay="true" loop="true" preload="auto">
    

    image.png

    展开全文
  • 文章目录一、描述二、兼容问题1、高低版本.NET兼容问题2、windows自带的.NET版本2、如何查案已安装的.NET版本2.1、方法一:官方办法2.2、方法二:通过javascript查看.NET版本2.3、方法三:通过注册表查看.NET版本三...
  • 关于Spring 版本和Jackson版本兼容问题

    万次阅读 2019-01-20 20:40:15
    关于Spring 版本和Jackson版本兼容问题 官方下载 版本大概说明 在Spring 4.2和之后版本与jackson 2.2和之前不兼容,在运行时会报错,报错信息复制到百度就有说明, 如果是版本问题 高版本spring下载对应高版本...
  • Axios 兼容问题 NetWork Error

    千次阅读 2020-10-30 14:56:50
    Axios 移动端真机低版本 请求 NetWork Error 如果默认配置了Headers application/json get请求是可以的 post请求需要使用 application/x-...Axios兼容问题 低版本不支持promise 安装es6-promise兼容低版本
  • ant-design-vue的兼容问题

    万次阅读 热门讨论 2019-05-07 00:44:59
    ant-design-vue的兼容问题 问题:ant-design-vue不兼容ie浏览器 要求:ie兼容 >= 9 环境:vue cli3搭建项目,ant-design-vue@1.3.8 babel.config.js文件 module.exports = { presets: [ '@vue/app', // 兼容...
  • ie8video 兼容问题

    千次阅读 2017-10-12 11:09:17
    ie8video 兼容问题
  • 解决swiper在ie9以下不兼容问题

    千次阅读 2020-04-09 09:39:25
    解决swiper在ie9以下不兼容问题
  • ios9 以下 flex 兼容问题

    千次阅读 2018-02-06 08:29:56
    ios9 以下 flex 兼容问题 详情描述 ios9 以下,display:flex 元素的第一级子元素必须是block,否则 flex 布局是不会生效的
  • 前端面试——浏览器兼容问题

    万次阅读 2019-03-26 23:23:28
    前端面试——浏览器兼容问题一、css样式兼容性问题 一、css样式兼容性问题 ie8浏览器不支持css3,像: ie8对选择器支持情况 ie8支持:first-child,但不支持:last-child、:last-of-type、:first-of-type、:...
  • gulp与node版本兼容问题

    千次阅读 2020-04-18 13:20:16
    gulp与node版本兼容问题 win10系统下使用django时,用到了node,gulp等插件,但是在执行gulp命令时一直报错,网上找了n种方法,靠自己一步步填坑,终于解决了这个bug。记录一下完整的过程。 一、node与gulp版本兼容...
  • 一行代码解决各种IE兼容问题

    万次阅读 2017-07-06 09:37:52
    一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 前端面试秘籍,欢迎star! 在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案 百度也应用了这种方案去解决IE的...
  • 浅谈前端兼容问题

    千次阅读 2018-04-14 01:18:12
    1、为什么会出现兼容问题 在各大浏览器厂商的发展过程中,他们其实对web的标准都有不同的实现,因为实现的标准的不同,所以会有兼容性的产生。通俗的说,就是对于web标准,有些浏览器支持,有些浏览器不支持。 2...
  • Tensorflow2.0和keras版本兼容问题

    千次阅读 2020-10-22 13:22:34
    Tensorflow2.0和keras版本兼容问题 本文主要是记录一些自己在win10系统下使用TensorFlow2.0版本是遇到的问题和最后解决的方案,会一直进行更新,以下文章中用tf代替TensorFlow2.0。。。。。。 TensorFlow和Keras的...
  • Pytorch版本兼容问题

    千次阅读 2019-06-10 10:03:13
    报错信息: Implicit dimension choice for soft max has been deprecated. Change the call to include ...版本兼容问题。pytorch较高版本会出现此错误,在高版本中,softmax的隐式维度选择已弃用 。需要调用包含d...
  • ios中的一些兼容问题

    千次阅读 2018-01-30 21:25:34
    ios中的一些兼容问题 详情描述 ios8.4.1版本中对jQuery中closeset()、find()、存在兼容性,只能直接使用jQuery对象去使用这些方法。通过赋值的方法去调用不起作用; ios上微信端a标签href必须填写...
  • 请问布署azure的时候存在硬件兼容问题吗?如果有可不可以列举不兼容的硬件信息!
  • SpringBoot 版本 与 jdk 版本兼容问题

    万次阅读 2018-03-14 16:52:57
    SpringBoot 版本 与 jdk 版本兼容问题 环境: jdk 1.7 springboot 1.4.0 jdk1.7 不支持 springboot 最新版本2.0.0 配置好 springboot 项目之后启动程序,出现上述错误,是 jdk 版本与 springboot 版本不...
  • idea2019本地导入lombok不兼容问题

    千次阅读 2019-10-09 10:03:01
    idea2019最新版本和lombok0.25及以下版本不兼容问题 因为公司内网,不能直接plugins里面搜索安装lombok。所以推荐本地安装方式如下: idea版本:2019.2 ;lombok版本:0.25-2018(0.25版本对应idea2018及以下应该没...
  • JS事件中的兼容问题

    千次阅读 2018-03-10 12:31:21
    1. 事件对象event的兼容问题 IE9+ : event IE9- : window.evente = e || window.event; 可简写为: e = e || event;2. 获取鼠标位置 pageX, pageY 的兼容问题 e.clientX / e.clientY 无兼容问题 (获取到页面可视...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 950,532
精华内容 380,212
关键字:

兼容问题