Переместить элемент обратно в исходное положение

Я использую плагин enquire.js для анализа медиазапросов, хранящихся как атрибуты данных, которые перемещают положение элементов в DOM на основе ширины браузера.

Таким образом, я написал следующее, что прекрасно работает, когда вы вручную указываете несоответствие, проблема с авто. Я хочу, чтобы это запомнило исходную позицию и автоматически переместило элемент назад, когда он выходит за пределы медиа-запроса.

Но у меня возникают проблемы, когда элемент prev/next, который изначально был ссылкой, также был перемещен. Есть ли другой способ, которым я могу переместить элемент обратно в исходное положение? Или мне лучше просто скрывать элемент, а не перемещать его?

/*
 * Organise elements using meta data
 * 
 * @example:
 * data-respond='{
 *      "query":"screen and (max-width:481px)", 
 *      "match": { 
 *          "target": "#page", 
 *          "method": "appendTo"
 *      }, 
 *      "unmatch":{
 *          "target": "#footer", 
 *          "method": "appendTo"
 *      }
 * }'
 */
var $this,
data,
options,
allowedMethods = ['appendTo', 'prependTo', 'insertAfter', 'insertBefore'];

$("[data-respond]").each(function () {
    $this = $(this),
    data = $this.data("respond");
    options = {};

    // check we have object
    /*if(typeof data !== 'object'){
        data = eval(data);
    }*/

    if (data.match) {
        if ($.inArray(data.match.method, allowedMethods) > -1) {
            options.match = function () {
                if (data.match.method == 'insertAfter') {
                    if ($this[0] == $(data.match.target).next()[0]) {
                        return;
                    }
                }
                if ($(data.match.target).length) {
                    $this[data.match.method](data.match.target);
                }
            }
        }
    } //match

    if (data.unmatch) {
        if (data.unmatch == 'auto') {
            data.unmatch = {};

            // a) insert after                      
            if ($this.prev().length) {
                data.unmatch.target = $this.prev();
                data.unmatch.method = 'insertAfter';
            } else if ($this.next().length) {
                // c) insert before 
                data.unmatch.target = $this.next();
                data.unmatch.method = 'insertBefore';
            } else {
                // d) append to parent
                data.unmatch.target = $this.parent();
                data.unmatch.method = 'appendTo';
            }

            if ($.inArray(data.unmatch.method, allowedMethods) > -1) {
                options.unmatch = function () {
                    $this[data.unmatch.method](data.unmatch.target);
                }
            }
        } else {
            // Manually set unmatch
            if ($.inArray(data.unmatch.method, allowedMethods) > -1) {
                options.unmatch = function () {
                    if ($(data.unmatch.target).length) {
                        $this[data.unmatch.method](data.unmatch.target);
                    }
                }
            }
        }

    } //unmatch

    enquire.register(data.query, options);
});

Jsbin - http://jsbin.com/akAV/1/edit

2 ответа

Решение

Я хочу, чтобы это запомнило исходную позицию и автоматически переместило элемент назад, когда он выходит за пределы медиа-запроса.

Но у меня возникают проблемы, когда элемент prev/next, который изначально был ссылкой, также был перемещен.

Общее замечание: вы должны четко определить, что такое "исходная позиция", когда "первоначального контекста" больше нет.


Я думаю, что одна из ваших проблем заключается в том, что вы используете движущиеся элементы в качестве ссылки.

Может быть, вы можете оставить пустой (фиксированный) тег HTML перед перемещением:

// create an empty tag, which will be left at the "original position"
var $beacon = $('<span class="beacon"></span>');
$(this).after($beacon);
// keep a reference to this node
$(this).data('unmatch-beacon', $beacon[0]);

// the unmatch function would be something like :
data.unmatch = function(){
    var beacon = $(this).data('unmatch-beacon');
    $(beacon).after(this);
    $(beacon).remove();
    $(this).data('unmatch-beacon', null);
};

Моя первая идея на самом деле довольно простая. Почему бы не обернуть их, где вы хотите их?

<div class="parentContainer">
    <div class="firstWrapper">
        <!-- Content that you want to move goes here -->
    </div>
    <div class="secondWrapper">
        <!-- Second content  that you want to move  goes here -->
    </div>
</div>

И ваш JS должен быть примерно таким:

// a) insert after                      
if($this.prev().length){
    data.unmatch.target = $('.firstWrapper');
    data.unmatch.method = 'appendTo';
} else if($this.next().length){
// c) insert before 
    data.unmatch.target = $('.secondWrapper');
    data.unmatch.method = 'appendTo';
} else {
// d) append to parent
    data.unmatch.target = $('.parentContainer');
    data.unmatch.method = 'appendTo';
}

Это позволит довольно легко найти, куда вы хотите что-то добавить. Будь проще!:)

/ J.

Другие вопросы по тегам