简体   繁体   English

在DOM中移动元素以进行响应式Web设计

[英]Moving Elements in DOM for Responsive Web Design

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). 大部分设计都是通过CSS使用媒体查询进行更改(因为它应该用于响应式网站)。 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. 但是,部分设计太复杂,不能简单地通过CSS操作,因为HTML实际上需要在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. 我知道这听起来不太好但是我无法看到我是如何在不移动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: 考虑以下三种不同的观点:

反响意见

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 nav tag has been moved below the p tag... 请注意, nav标签已移至p标签下方...

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
    }
}

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. 你只需要编辑[u]那个[/ u]页面。 No messing around with JavaScript, hard-coding new classes / cases. 不要乱用JavaScript,硬编码新的类/案例。

The enquire.js library solves this problem by allowing you to fire JS functions in response to CSS media queries. enquire.js库允许您触发JS函数以响应CSS媒体查询,从而解决了这个问题。 So you could run your detach() and append() logic according to different screen sizes. 因此,您可以根据不同的屏幕大小运行detach()和append()逻辑。 It is lightweight to boot. 它的重量很轻。

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

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');
}

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的辅助技术和其他Web代理将其视为重复内容。

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. 虽然JavaScript也不理想,但如果它被用作逐步增强的形式,我认为没有问题。 I recently found myself using it often enough that I created a jQuery plugin for it: https://github.com/thomashigginbotham/responsive-dom 我最近发现自己经常使用它,我为它创建了一个jQuery插件: https//github.com/thomashigginbotham/responsive-dom

Sample usage: 样品用法:

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

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

I've just written a jQuery plugin which does exactly this, have a look here . 我刚刚编写了一个jQuery插件,正是这样,看看这里 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 基本上它会根据行和列自动构建一系列布局,然后用于上面显示的不同视图

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. 我在调整大小的窗口上有一个事件监听器,它调用一个检查屏幕大小并将其传递给我的toggleNavigation函数的函数。 I have this separate because I have a few other functions aside from that that get called in the checkBreakPoint that are not listed. 我有这个单独的因为除了没有列出的checkBreakPoint调用之外我还有一些其他功能。 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. 然后为了确保它不是经常移动我的dom或重新附加它我首先检查它所在的父容器,如果它不在我期望的那个屏幕尺寸中,则仅移动它。 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. 我的项目要求它没有任何外部依赖项,所以这只是在普通的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);
        }
    }
}

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... 问候...

这可能会引入一组全新的问题,但你可以在要移动的元素上使用position:absolute,并根据屏幕的大小重新定位页面吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM