Jquery: запустить метод для определенных элементов, но не для других - PullRequest
1 голос
/ 23 июня 2009

Мне трудно понять, как запустить метод для определенных элементов / типов узлов, но не для других.

Например, вот какой-то HTML:

<div id="parent">
    <div class="subparent">Changing Text
        <div class="no-change">Changing Text</div>
    </div>
    <div class="subparent">Changing Text</div>
        <div class="child">Changing Text
            <div class="no-change">Changing Text</div>
        </div>
    <div class="subparent">Changing Text</div>
</div>

Мой метод примерно такой:

jQuery.fn.changingtext = function(expr) {
    return this.each(function() {
        this.innerHTML = this.innerHTML
        .replace(/Changing Text/ig, "Edited!")
    });
};

Теперь я хочу изменить текст всего, кроме того, что в div.no-change. Конечный результат должен выглядеть примерно так:

<div id="parent">
    <div class="subparent">Edited!
        <div class="no-change">Changing Text</div>
    </div>
    <div class="subparent">Edited!</div>
        <div class="child">Edited!
            <div class="no-change">Changing Text</div>
        </div>
    <div class="subparent">Edited!</div>
</div>

Я не знаю ни одного способа выбора родителя, не запустив метод для его потомка. Любая помощь будет оценена. Спасибо!

Редактировать: Здесь используется код Пауло, а не работает: http://jsbin.com/usaxa

Редактировать @ Джефф Фрикадельки Ян: Привет, используя замену на месте, он выводит текст, а не HTML: http://jsbin.com/idina

Я также не смог заставить работать другие методы: http://jsbin.com/aguca

Не могли бы вы привести пример?

Спасибо!

Ответы [ 2 ]

7 голосов
/ 23 июня 2009

Я не совсем уверен, почему вы пишете плагин для этого. Это позволит найти все элементы <div> внутри #parent, отфильтровать элементы, которые не имеют класса .no-change, и отредактировать их текстовое содержимое:

$('#parent').find('div').not('.no-change').text('Edited!');

Что также может быть записано как:

$('#parent div:not(.no-change)').text('Edited!');

jQuery очень хорошо работает с множеством элементов, вам не нужно их циклически проходить и все такое.

EDIT

Это должно работать, чтобы учесть хорошие наблюдения CMS:

$('#parent').find('div').not('.no-change').each(function() {
    $(this).contents().not('*').eq(0).replaceWith('Whatever');    
});
0 голосов
/ 23 июня 2009

Попробуйте это:

jQuery.fn.changingtext = function(expr) {
    return this.each(function() {
      // filter for text node
      var nodes = $(this).contents().filter(function() { return this.nodeType == 3); });

      // or do in-place editing
      for(var i = 0, len = nodes.length; i < len; i++) {
        nodes[i].nodeValue = nodes[i].nodeValue.replace(/Changing Text/ig, "Edited!");
      }
    });
};

// prove that no change is still white
$("#parent div.no-change").css("color", "white");

// change text, then make it red using jQuery
$("#parent div:not(.no-change)").changingtext().css("color", "red");

Конечный результат уже HTML. Таким образом, вы сможете связывать другие функции jQuery после вызова плагина. Смотрите мои правки.


вместо установки значения текстового узла (node ​​[i] .nodeValue), вы можете удалить его и добавить DIV после него. Вместо использования цикла for и замены текста вы можете удалить цикл for и использовать встроенные функции jQuery:

jQuery.fn.changingtext = function(expr) {
    return this.each(function() {
      // filter for text node
      var nodes = $(this).contents().filter(function() { return this.nodeType == 3); });

      // you can replace the text nodes:
      // insert a DIV after each one, 
      // then remove it from the DOM
      nodes.after("<div>Edited!</div>").remove();
    });
};

Это описано в Документах jQuery (http://docs.jquery.com) по Манипулированию и Обходу.

...