草庐IT

javascript - CSS 硬件加速宽度?

coder 2024-07-26 原文

我正在尝试构建一个 Phonegap 应用程序,它允许用户通过移动中间分隔线来更改两列布局的大小。

我能够让它工作,但存在一个巨大的用户体验问题:它很慢。这并不可怕,但在最新的 iPad 上它甚至很明显,这让我很担心。

这是我调整大小的 JS:

$("div").on("touchmove", "#columnResizeIcon", function(e) {
    e.preventDefault();
    var left = e.originalEvent.touches[0].pageX;
    var right = $("#columnContainer").width() - left;

    $("#leftColumn").css({
       "width":left - 1 + "px",
       "right":"auto",
    });
    $("#rightColumn").css({
       "width":right - 1 + "px",
       "left":"auto",
    });
    $("#columnResize").css({
       "-webkit-transform":"translate3d(" + left  + "px" + ", 0, 0)",
       "left":"auto",
    });
    $("#columnResizeIcon").css({
       "-webkit-transform":"translate3d(" + left  + "px" + ", 0, 0)",
       "left":"auto",
    });
}); 

您会注意到我利用 translate3d() 更改元素的“左”值,因为这是硬件加速的。我相信延迟是由改变左右列的宽度产生的,这是我需要硬件加速的。

我认为可行的解决方案是使用 -webkit-transform:translate3d(50%, 0, 0) 将右侧的列推到页面的一半以上,然后只需更改该值,希望它只会延伸到到达父级为止。但是,它会继续,并到达页面的 50%,而不是父页面的 50%。

我的 HTML 标记如下所示:

<div id="columnContainer">
    <div id="columnResize"></div>
    <div id="columnResizeIcon"></div>

    <div id="leftColumn">
        <div class="header">Left Header</div>
        <div class="content"></div>

    </div>
    <div id="rightColumn">
        <div class="header">Right Header</div>
        <div class="content"></div>
    </div>
</div>

还有我的 CSS:

body{
    background-color:#000;
}

#columnContainer{
    position: absolute;
    bottom:0;
    top:0;
    right:0;
    left:0;
    background-color:#000;
}

#leftColumn{
    position: absolute;
    top:0;
    left:0;
    right:50%;
    bottom:0;
    -webkit-overflow-scrolling: touch;
    z-index: 1;
    margin-right: 1px;
}

#rightColumn{
    position: absolute;
    top:0;
    left:50%;
    right:0;
    bottom:0;
    -webkit-overflow-scrolling: touch;
    z-index: 1;
    margin-left: 1px;
}

.header{
    position: absolute;
    left:0;
    right:0;
    height:33px;
    z-index: 5;
    background: -webkit-linear-gradient(top, #f4f5f7 0%,#a7abb7 100%);
    box-shadow:  inset 0 1px 0 #fff, inset 0 -1px 0 #7A8090, 3px 0 2px rgba(0,0,0,.3);
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    font-size: 17px;
    font-family: Helvetica;
    font-weight: bold;
    letter-spacing: .2px;
    text-align: center;
    padding-top:9px;
    color:#71787F;
    text-shadow: 0 1px 0 #E3E5E9;
}

.content{
    position: absolute;
    left:0;
    right: 0;
    top:42px;
    bottom: 0;
}

#leftColumn .content{
    background-color:#F5F5F5;
}

#rightColumn .content{
    background-color:#fff;
}

#columnResize{
    position: absolute;
    width:2px;
    top:0;
    bottom: 0;
    left:50%;
    margin-left:-1px;
    background-color:#000;
    z-index: 2;
}

#columnResizeIcon{
    position: absolute;
    z-index: 3;
    width:10px;
    height:30px;
    top:50%;
    bottom:50%;
    margin-top:-15px;
    left:50%;
    margin-left:-7px;
    border-left:2px solid #000;
    border-right:2px solid #000;
}

最佳答案

我终于想出了一个比我以前的解决方案效果更好的解决方案。基本上,我为容器设置动画,并在调整大小时隐藏内容。然后,调整大小完成后,我再次显示内容。我使用动画使其在隐藏/显示时看起来很漂亮。代码会比我更好地解释它:

万能的 fiddle

1 http://jsfiddle.net/charlescarver/hnQHH/134/

我的解释

点击 slider 时,它会使用 translate3d() 转换将所有文本元素推出页面,然后隐藏 div。这是因为如果我在显示元素时尝试更新宽度,则会返回滞后。因此,一旦 div 被隐藏,我就再次使用 translate3d() 转换向左或向右移动列。我可以在不让每个元素的宽度停止变短的情况下执行此操作,因为我将 leftright 值设置为永远无法达到的值,因此它扩展得足够远超出页。这样,我就可以简单地移动它,而不必担心它会过早切断。

怪异

其中有些部分可能是多余的,但我会尽快清理它们。您可能还会注意到一些奇怪的事情,例如 (1) cornerLeft, (2) dummy, (3) shadow,在 JS 中,(4) 最小值:

  1. 当我调整页面大小时,dummy 导航栏扩展了左右两列的整个宽度,这意味着它达到了宽度的 1000%。这意味着我无法在每列左侧和右侧的导航栏上设置 border-radius,因为它离屏幕太远以至于不可见。所以,我做了一个简单的 Angular 来遮盖 window 的每一侧,让它看起来很漂亮。

  2. 我在调整大小时隐藏了 .contentLeft.contentRight,因为它在显示时会导致延迟。不过,我不想去掉导航栏,所以我制作了一个 dummy 导航栏,它始终出现在页面上,并且在即将调整大小时简单地显示出来。我认为这减少了延迟,因为我不必添加元素,因为它一直存在。

  3. 然而,其中一个问题是,当普通导航覆盖虚拟导航时,box-shadow 重叠,导致它变暗 200 毫秒。我不喜欢这个。因此,无论导航显示什么,我都会在导航上方放置一个阴影。

  4. 我现在可以轻松设置可拖动列在停止前可以达到的界限。方便吧?

代码

HTML:

<div id="container">
    <div class="cornerLeft"></div>
    <div class="cornerRight"></div>
    <div class="shadow"></div>
    <div class="left">
        <div class="contentLeft">
            <div class="header"></div>
            <div class="headerbehind"></div>
            <div class="text textLeft">Praesent id metus massa, ut blandit odio. Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus.</div>
        </div>
        <div class="dummy"></div>
        <div class="dummybg"></div>
    </div>
    <div class="divider"></div>
    <div class="right">
        <div class="contentRight">
            <div class="header"></div>
            <div class="headerbehind"></div>
            <div class="text textRight">Praesent id metus massa, ut blandit odio. Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus.</div>
        </div>
        <div class="dummy"></div>
        <div class="dummybg"></div>
    </div>
</div>

CSS:

* {
    -webkit-text-size-adjust:none;
}
#container {
    position:fixed;
    left:0;
    right:0;
    bottom:0;
    top:0;
    background-color:#000;
    -webkit-transform: translateZ(0);
    -webkit-perspective: 1000;
}
.left {
    -webkit-transform:translate3d(0, 0, 0);
    position:absolute;
    left:-3000px;
    right:50%;
    top:0;
    bottom:0;
    border-right:1px solid #000;
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.right {
    -webkit-transform:translate3d(0, 0, 0);
    position:absolute;
    left:50%;
    right:-3000px;
    top:0;
    bottom:0;
    border-left:1px solid #000;
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.divider {
    width:24px;
    height:40px;
    border-left:2px solid #000;
    border-right:2px solid #000;
    position:absolute;
    left:50%;
    z-index:3;
    margin-left:-14px;
    margin-top:-20px;
    top:50%;
    -webkit-transform:translate3d(0, 0, 0);
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
}
.contentLeft {
    position:absolute;
    right:0;
    bottom:0;
    top:0;
    -webkit-transform: translateZ(0);
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.contentRight {
    position:absolute;
    left:0;
    bottom:0;
    top:0;
    -webkit-transform: translateZ(0);
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.cornerLeft:after {
    content:"";
    height:5px;
    position:absolute;
    left:0;
    width:5px;
    background: -webkit-linear-gradient(top, #F0F2F4 0%, #EAEBEE 100%);
    z-index:700;
    border-top-left-radius:5px;
    box-shadow:inset 0 1px 0 #fff;
}
.cornerLeft {
    position:absolute;
    z-index:700;
    left:0;
    width:5px;
    height:5px;
    background-color:#000;
}
.cornerRight:after {
    content:"";
    height:5px;
    position:absolute;
    right:0;
    width:5px;
    background: -webkit-linear-gradient(top, #F0F2F4 0%, #EAEBEE 100%);
    z-index:700;
    border-top-right-radius:5px;
    box-shadow:inset 0 1px 0 #fff;
}
.cornerRight {
    position:absolute;
    z-index:700;
    right:0;
    width:5px;
    height:5px;
    background-color:#000;
}
.header, .dummy {
    position: absolute;
    left:0;
    right:0;
    height:35px;
    background: -webkit-linear-gradient(top, #f4f5f7 0%, #a7abb7 100%);
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    font-size: 17px;
    font-family: Helvetica;
    font-weight: bold;
    letter-spacing: .2px;
    text-align: center;
    padding-top:9px;
    color:#71787F;
    text-shadow: 0 1px 0 #E3E5E9;
    word-break: break-all;
    box-shadow:inset 0 1px 0 #fff, inset 0 -1px 0 #7A8090;
}
.shadow {
    height:44px;
    position:absolute;
    left:0;
    right:0;
    box-shadow:0 1px 2px rgba(0, 0, 0, .2);
    z-index:600;
}
.header {
    z-index:500;
}
.dummy {
    z-index:100;
}
.headerbehind {
    position:absolute;
    background-color:#000;
    left:0;
    right:0;
    height:44px;
    z-index:499;
}
.text, .dummybg {
    margin-top:44px;
    background-color:#fff;
    position:absolute;
    top:0;
    right:0;
    left:0;
    bottom:0;
}
.text {
    z-index:2;
    padding:20px 40px;
    -webkit-animation-duration:200ms;
    -webkit-animation-timing-function:ease;
}
.contentLeft, .contentRight {
    z-index:300;
}
.leftOut {
    -webkit-transform:translate3d(-100%, 0, 0);
    -webkit-animation-name:leftOut;
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
.leftIn {
    -webkit-transform:translate3d(0, 0, 0);
    -webkit-animation-name:leftIn;
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}
@-webkit-keyframes leftOut {
    0% {
        -webkit-transform:translate3d(0, 0, 0);
    }
    100% {
        -webkit-transform:translate3d(-100%, 0, 0);
    }
}
@-webkit-keyframes leftIn {
    0% {
        -webkit-transform:translate3d(-100%, 0, 0);
    }
    100% {
        -webkit-transform:translate3d(0, 0, 0);
    }
}
.rightOut {
    -webkit-transform:translate3d(100%, 0, 0);
    -webkit-animation-name:rightOut;
}
.rightIn {
    -webkit-transform:translate3d(0, 0, 0);
    -webkit-animation-name:rightIn;
}
@-webkit-keyframes rightOut {
    0% {
        -webkit-transform:translate3d(0, 0, 0);
    }
    100% {
        -webkit-transform:translate3d(100%, 0, 0);
    }
}
@-webkit-keyframes rightIn {
    0% {
        -webkit-transform:translate3d(100%, 0, 0);
    }
    100% {
        -webkit-transform:translate3d(0, 0, 0);
    }
}

JS:

minimum = 100;
$(".contentLeft").css("width", ($("#container").width() / 2) - 1);
$(".contentRight").css("width", ($("#container").width() / 2) - 1);

$("div").on("touchstart", ".divider", function (e) {
    $(".textLeft").removeClass("leftIn");
    $(".textLeft").addClass("leftOut");
    $(".textRight").removeClass("rightIn");
    $(".textRight").addClass("rightOut");
    setTimeout(function () {
        $(".contentLeft, .contentRight").hide();
    }, 200);
});

$("div").on("touchmove", ".divider", function (e) {
    e.preventDefault();
    if ($(".contentLeft").css("display", "none")) {
        var page = $("#container").width();
        var left = e.originalEvent.touches[0].pageX;
        var right = page - left;
        updateWidth(page, left, right);
    }
});

//$(".contentLeft, .contentRight").hide();

$("div").on("touchend", ".divider", function (e) {
    setTimeout(function () {
        $(".textLeft").removeClass("leftOut");
        $(".textLeft").addClass("leftIn");
        $(".textRight").removeClass("rightOut");
        $(".textRight").addClass("rightIn");
        $(".contentLeft, .contentRight").show();
    }, 200);
});

$(window).on('orientationchange', function (e) {
    var page = $("#container").width();
    var leftWidth = $(".contentLeft").width();
    var rightWidth = $(".contentRight").width();
    var previousWidth = (leftWidth + rightWidth);
    if (leftWidth + rightWidth + 2 < page) {
        var left = (page / 2) - (previousWidth / 2) + leftWidth;
    } else if (leftWidth + rightWidth + 2 > page) {
        var left = leftWidth - ((previousWidth / 2) - (page / 2));
    }
    var right = page - left;
    updateWidth(page, left, right);
});

function updateWidth(page, left, right) {
    if (left < minimum) {
        var finalLeft = minimum;
        var finalRight = (-1 * (page - minimum));
        var finalRightWidth = (page - minimum);
    } else if (right < minimum) {
        var finalLeft = (page - minimum);
        var finalRight = (-1 * minimum);
        var finalRightWidth = minimum;
    } else {
        var finalLeft = (left);
        var finalRight = (0 - right);
        var finalRightWidth = (right);
    }
    $(".divider").css({
        "-webkit-transform": "translate3d(" + finalLeft + "px, 0, 0)",
            "left": "auto",
    });
    $(".left").css({
        "-webkit-transform": "translate3d(" + finalLeft + "px, 0, 0)",
            "right": "100%",
    });
    $(".right").css({
        "-webkit-transform": "translate3d(" + finalRight + "px, 0, 0)",
            "left": "100%",
    });
    $(".contentLeft").css("width", finalLeft);
    $(".contentRight").css("width", finalRightWidth);
}

1 是的,我尝试了 134 次。

关于javascript - CSS 硬件加速宽度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15670303/

有关javascript - CSS 硬件加速宽度?的更多相关文章

  1. ruby - capybara field.has_css?匹配器 - 2

    我在MiniTest::Spec和Capybara中使用以下规范:find_field('Email').must_have_css('[autofocus]')检查名为“电子邮件”的字段是否具有autofocus属性。doc说如下:has_css?(path,options={})ChecksifagivenCSSselectorisonthepageorcurrentnode.据我了解,字段“Email”是一个节点,因此调用must_have_css绝对有效!我做错了什么? 最佳答案 通过JonasNicklas得到了答案:No

  2. css - 用 watir 检查标签类? - 2

    我有一个div,它根据表单是否正确提交而改变。我想知道是否可以检查类的特定元素?开始元素看起来像这样。如果输入不正确,添加错误类。 最佳答案 试试这个:browser.div(:id=>"myerrortest").class_name更多信息:http://watir.github.com/watir-webdriver/doc/Watir/HTMLElement.html#class_name-instance_method另一种选择是只查看具有您期望的类的div是否存在browser.div((:id=>"myerrortes

  3. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  4. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  5. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  6. css - Rails 4.1 和 Bootstrap 3 字形图标不工作 - 2

    我正在尝试消除使用Bootstrap3的Rails4元素中的glyphicon错误。我没有使用任何Bootstrapgem将其添加到Assets管道中。我手动将bootstrap.css和bootstrap.js添加到各自的app/assets目录下,分别添加到application.css和application.js什么的我现在在网络浏览器的控制台中看到以下内容:GEThttp://localhost:3000/fonts/glyphicons-halflings-regular.woff404(NotFound)localhost/:1GEThttp://localhost:30

  7. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  8. css - rails 萨斯 : variables are not passed with @import - 2

    我有一个使用twitterbootstrap和sass的Rails元素。scss文件结构化到文件夹中,所以我有更好的概述。现在我想为包含我的颜色等的全局变量定义一个文件,并将这些值传递给其他文件,这样我就有更少的冗余代码。虽然所有代码都已正确导入和应用,变量不起作用。这是当前的设置:样式表/application.css.scss/**=require_self*=require_tree*//*stylesheets/||–base/||–_reset.scss#Reset/normalize||–_typography.scss#Typographyrules||–componen

  9. css - Jekyll 和自定义 CSS - 2

    有没有一种方法可以在jekyll站点中包含自定义css标签,同时将markdown用于入口文件?例如,当我想突出显示某个段落时? 最佳答案 Markdown和YAMLFrontMatter都内置了这个。但你可以自己制作。比如说,您有foo.css想要包含在某些帖子中。在_posts/2013-02-03-higligting-foo.markdown中:---css:footitle:"DrupalImagecachesecurityvulnarabilitywithDDOSattackexplained"tags:[drupal,

  10. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

随机推荐