javascript 移动 DOM 中的元素以实现响应式 Web 设计

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23238673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 00:36:17  来源:igfitidea点击:

Moving Elements in DOM for Responsive Web Design

javascriptjqueryhtmlcssresponsive-design

提问by Ben Carey

A Brief Explanation

简要说明

I have created a responsive website that effectively has three views (desktop,tablet,mobile). Most of the design is changed via CSS using media queries (as it should be for responsive websites). However, part of the design is too complex to simply be manipulated via CSS as the HTML actually needs to be moved around the DOM. I know this doesn't sound too great but I cannot see how else I am meant to replicate this design without moving certain elements within my HTML.

我创建了一个响应式网站,它有效地具有三个视图(桌面、平板电脑、移动设备)。大多数设计是通过 CSS 使用媒体查询进行更改的(对于响应式网站来说应该如此)。然而,部分设计过于复杂,不能简单地通过 CSS 进行操作,因为 HTML 实际上需要在 DOM 周围移动。我知道这听起来不太好,但我看不出我还打算如何在不移动 HTML 中的某些元素的情况下复制此设计。

So, with the above in mind, I now plan to write a function that creates custom events for each of the different ‘responsive views'. When each event is fired (in sync with the CSS media queries), it will execute some Javascript to move/animate any elements that cannot be manipulated enough using CSS.

因此,考虑到上述情况,我现在计划编写一个函数,为每个不同的“响应视图”创建自定义事件。当每个事件被触发时(与 CSS 媒体查询同步),它将执行一些 Javascript 来移动/动画任何不能使用 CSS 进行足够操作的元素。

My Question

我的问题

Is this the best method to go about doing this? If, not, what other options do I have? Are there any existing libraries that I could look at and learn from?

这是最好的方法吗?如果不是,我还有什么其他选择?是否有任何现有的库可供我查看和学习?

My actual question is; What is the best method of moving elements in the DOM for responsive web design?

我的实际问题是;在 DOM 中移动元素以进行响应式网页设计的最佳方法是什么?

Further Explanation

进一步说明

If the above wasn't clear, then read the following:

如果以上还不清楚,请阅读以下内容:

Consider these three different views:

考虑这三种不同的观点:

Responsive Views

响应式视图

Now consider the code for the first two views:

现在考虑前两个视图的代码:

Desktop

桌面

<div id="some_container">
    <nav>
        <ul>
        </ul>
    <nav>
    <p>Some Text</p>
    <!-- The rest of the content -->
</div>

Tablet

药片

<div id="some_container">
    <p>Some Text</p>
    <nav>
        <ul>
        </ul>
    <nav>
    <!-- The rest of the content -->
</div>

Notice the navtag has been moved below the ptag...

请注意nav标签已移至p标签下方...

采纳答案by Cerbrus

You can try this:

你可以试试这个:

Assuming this HTML:

假设这个 HTML:

<div id="some_container">
    <nav id="n1">
        <ul>
            <li>1</li>
            <li>2</li>
        </ul>
    </nav>
    <p>Some Text</p>
    <nav id="n2">
        <ul>
            <li>1</li>
            <li>2</li>
        </ul>
    </nav>
</div>

You will only need the following css:

您只需要以下 css:

#n1{
    display:none;
}

@media only screen 
and (min-width : 600px) {
    #n1{
        display:block;
    }
    #n2{
        display:none;
    }
}

Fiddle example

小提琴示例

This basically toggles which of the two navigation sections you see, depending on the screen size. It has the disadvantage of duplicated html in your source (the difference in the amount of data is really negligible), but you won't need JavaScript to get the effect, and JS disabled devices will only show one ul.

这基本上会根据屏幕大小切换您看到的两个导航部分中的哪一个。它的缺点是你的源中有重复的 html(数据量的差异真的可以忽略不计),但是你不需要 JavaScript 来获得效果,并且 JS 禁用的设备只会显示一个ul.

The great thing about this way is that it's very scale-able. Need this "effect" on a different page? You'll only have to edit [u]that[/u] page. No messing around with JavaScript, hard-coding new classes / cases.

这种方式的好处在于它非常具有可扩展性。在不同的页面上需要这种“效果”?你只需要编辑[u]那个[/u]页面。不要乱用 JavaScript,硬编码新的类/案例。

回答by David

I would suggest you use .insertAfter()and .resize()/.ready()to move the elements based on the page size:

我建议您使用.insertAfter().resize()/.ready()根据页面大小移动元素:

$(window).resize(){
    resize();
}

$(document).ready(){
    resize();
}

function resize(){
    if($(window).width() < 480)
    {
        //Mobile
        $("#some_container nav").insertAfter("#some_container p");
    }
    else if($(window).width() < 800)
    {
        //Tablet
        $("#some_container nav").insertAfter("#some_container p");
    }
    else
    {
        //Desktop
        //Leave original layout
    }
}

回答by jasperjohnny

The enquire.js library solves this problem by allowing you to fire JS functions in response to CSS media queries. So you could run your detach() and append() logic according to different screen sizes. It is lightweight to boot.

enquire.js 库通过允许您触发 JS 函数来响应 CSS 媒体查询来解决这个问题。所以你可以根据不同的屏幕尺寸运行你的 detach() 和 append() 逻辑。启动起来很轻巧。

See: http://wicky.nillia.ms/enquire.js/

见:http: //wicky.nillia.ms/enquire.js/

回答by Bhojendra Rauniyar

There are many methods like appendTo

方法很多,比如appendTo

//check for the window width
if($(window).width() < 700){
  //append to the p  
  $('#some_container nav').appendTo('#some_container p');
}

回答by Thomas Higginbotham

Creating duplicate content to solve responsive design challenges is not a best practice. It makes the markup harder to maintain (especially when another developer takes over the project and doesn't realize it has to be updated in more than one location), it increases file size (if file size wasn't important, we wouldn't minify our CSS/JS or GZIP our HTML), and assistive technologies and other web agents that don't take CSS into account see it as repeated content.

创建重复的内容来解决响应式设计挑战并不是最佳实践。它使标记更难维护(特别是当另一位开发人员接管项目并且没有意识到它必须在多个位置更新时),它增加了文件大小(如果文件大小不重要,我们不会缩小我们的 CSS/JS 或 GZIP 我们的 HTML),并且不考虑 CSS 的辅助技术和其他网络代理将其视为重复内容。

It's just messy, and I don't see how anyone would consider it a best practice.

这只是一团糟,我看不出有人会认为这是最佳实践。

While JavaScript isn't ideal either, I see no issue if it is used as a form of progressive enhancement. I recently found myself using it often enough that I created a jQuery plugin for it: https://github.com/thomashigginbotham/responsive-dom

虽然 JavaScript 也不是理想的,但我认为如果将其用作渐进式增强形式没有问题。我最近发现自己经常使用它,因此我为它创建了一个 jQuery 插件:https: //github.com/thomashigginbotham/responsive-dom

Sample usage:

示例用法:

var $mainNav = $('.main-nav');

$mainNav.responsiveDom({
    appendTo: '.sidebar',
    mediaQuery: '(min-width: 600px)'
});

回答by crumdev

I am doing this exact thing right now with navigation that I need to move into the header for desktop and just below the header for a hamburger menu on mobile. I have an event listener on the window being resized that calls a function that checks screen size and passes it to my toggleNavigation function. I have this separate because I have a few other functions aside from that that get called in the checkBreakPoint that are not listed. Then to make sure that it is not constantly moving my dom or re-appending it I first check what parent container it is in and only move it if it is not in the one I expect for that screensize. My project requires that it not have any external dependencies so this is just done in plain Javascript and then I use media queries to style the elements based on screen size.

我现在正在用导航做这件事,我需要移动到桌面的标题和移动设备上汉堡菜单标题的正下方。我在调整大小的窗口上有一个事件侦听器,它调用一个函数来检查屏幕大小并将其传递给我的 toggleNavigation 函数。我有这个单独的,因为除了在 checkBreakPoint 中没有列出的那些被调用的函数之外,我还有一些其他的函数。然后为了确保它不会不断移动我的 dom 或重新附加它,我首先检查它所在的父容器,只有在它不是我期望的屏幕尺寸时才移动它。我的项目要求它没有任何外部依赖项,所以这只是在纯 Javascript 中完成,然后我使用媒体查询根据屏幕大小设置元素的样式。

var mainNav = document.getElementById('rww_main_nav'); //element I want to move
var tieredHeader = document.getElementById('rww_tiered_header'); //where it should be on mobile
var branding = document.getElementById('rww_branding'); //where it should be on desktop

window.addEventListener("resize", checkBreakPoint);

function checkBreakPoint() {
        //width of viewport
        var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
        toggleNavLocation(w);
}

function toggleNavLocation(screensize) {
    if (screensize > 999) {
        if (mainNav.parentElement.id === 'rww_tiered_header') {
            branding.appendChild(mainNav);
        }
    } else {
        if (mainNav.parentElement.id === 'rww_branding') {
            tieredHeader.appendChild(mainNav);
        }
    }
}

回答by Johnattan Tibocha

If you don't want to make javascript, use grid technique.

如果您不想制作 javascript,请使用网格技术。

<div class="main_container">
    <nav class="grid_nav">
        <ul>
        </ul>
    <nav>
    <div class="grid_text">
        <p>Some Text</p>
    </div>
    <!-- The rest of the content -->
</div>

.main_container{
  display: grid;
  @media screen and (max-width: 500px) { //mobile
    grid-template-rows:    1fr 1fr;
    grid-template-areas: "gridnav"
                         "gridtext";
  }
  @media screen and (min-width: 500px) {//web
    grid-template-rows:    1fr 1fr;
    grid-template-areas: "gridtext"
                         "gridnav";
  }
}

.grid_nav{
  grid-area: gridnav;
}
.grid_text{
  grid-area: gridtext;
}

But is only when the movements are inside of the "main_container"

但仅当运动在“main_container”内时

regards...

问候...

回答by James Ellis-Jones

I've just written a jQuery plugin which does exactly this, have a look here. Basically it automatically builds a series of layouts in terms of rows and columns, which are then used for the different views as you show above

我刚刚编写了一个 jQuery 插件,它完全可以做到这一点,请看这里。基本上它会根据行和列自动构建一系列布局,然后用于不同的视图,如上所示

回答by Patrick Mattei

This may introduce a whole new set of problems, but could you use position: absolute on the elements set to move, and have them reposition around the page based on the size of the screen?

这可能会带来一系列全新的问题,但是您能否在设置要移动的元素上使用 position: absolute 并让它们根据屏幕大小在页面周围重新定位?