Jquery:对某些元素运行方法,但不运行其他元素

时间:2022-04-03 21:26:24

I'm having a hard time figuring out how to run a method on certain elements/nodetypes but not others.

我很难弄清楚如何在某些元素/节点类型上运行方法而不是其他元素/节点类型。

For instance here's some HTML:

例如,这里有一些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>

My method is something like this:

我的方法是这样的:

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

Now I want to change the text of everything except what's in div.no-change. The end result should be something like this:

现在我想更改除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>

I don't know of any way to select a parent without also running the method on its child. Any help would be appreciated. Thanks!

我不知道如何选择父级而不在其子级上运行该方法。任何帮助,将不胜感激。谢谢!

Edit: Here is using Paulo's code and not working: http://jsbin.com/usaxa

编辑:这是使用Paulo的代码而不是工作:http://jsbin.com/usaxa

Edit@Jeff Meatball Yang: Hi, using your inplace replacement it outputs as text rather than html: http://jsbin.com/idina

编辑@ Jeff Meatball Yang:嗨,使用你的inplace替换它输出文本而不是html:http://jsbin.com/idina

I also wasn't able to get the other methods working: http://jsbin.com/aguca

我也无法使用其他方法:http://jsbin.com/aguca

Could you provide an example please?

你能提供一个例子吗?

Thanks!

2 个解决方案

#1


Try this:

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");

The end result is already HTML. So, you will be able to chain other jQuery functions after the plugin call. See my edit.

最终结果已经是HTML。因此,您可以在插件调用后链接其他jQuery函数。看我的编辑。


instead of setting the text node value (nodes[i].nodeValue), you can remove it and append a DIV after it. Instead of using a for loop and replacing the text, you can remove the for loop and use jQuery's built-in functions:

而不是设置文本节点值(nodes [i] .nodeValue),您可以删除它并在其后附加DIV。您可以删除for循环并使用jQuery的内置函数,而不是使用for循环并替换文本:

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

This is documented in the jQuery Docs (http://docs.jquery.com) on Manipulation and Traversing.

这在操作和遍历的jQuery Docs(http://docs.jquery.com)中有记录。

#2


I'm not really sure why you're writing a plugin to do this. This would find all the <div> elements inside #parent, filter out those that don't have the class of .no-change, and edit the text contents of them:

我不确定你为什么要编写插件来执行此操作。这将找到#parent中的所有

元素,过滤掉那些没有.no-change类的元素,并编辑它们的文本内容:

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

Which could also be written as:

这也可以写成:

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

jQuery is very good at working on set of elements, you don't have to loop through them and such.

jQuery非常擅长处理元素集,你不必循环遍历它们等等。

EDIT:

This should work to take account CMS's good observation:

这应该考虑到CMS的良好观察:

$('#parent').find('div').not('.no-change').each(function() {
    $(this).contents().not('*').eq(0).replaceWith('Whatever');    
});

#1


Try this:

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");

The end result is already HTML. So, you will be able to chain other jQuery functions after the plugin call. See my edit.

最终结果已经是HTML。因此,您可以在插件调用后链接其他jQuery函数。看我的编辑。


instead of setting the text node value (nodes[i].nodeValue), you can remove it and append a DIV after it. Instead of using a for loop and replacing the text, you can remove the for loop and use jQuery's built-in functions:

而不是设置文本节点值(nodes [i] .nodeValue),您可以删除它并在其后附加DIV。您可以删除for循环并使用jQuery的内置函数,而不是使用for循环并替换文本:

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

This is documented in the jQuery Docs (http://docs.jquery.com) on Manipulation and Traversing.

这在操作和遍历的jQuery Docs(http://docs.jquery.com)中有记录。

#2


I'm not really sure why you're writing a plugin to do this. This would find all the <div> elements inside #parent, filter out those that don't have the class of .no-change, and edit the text contents of them:

我不确定你为什么要编写插件来执行此操作。这将找到#parent中的所有

元素,过滤掉那些没有.no-change类的元素,并编辑它们的文本内容:

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

Which could also be written as:

这也可以写成:

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

jQuery is very good at working on set of elements, you don't have to loop through them and such.

jQuery非常擅长处理元素集,你不必循环遍历它们等等。

EDIT:

This should work to take account CMS's good observation:

这应该考虑到CMS的良好观察:

$('#parent').find('div').not('.no-change').each(function() {
    $(this).contents().not('*').eq(0).replaceWith('Whatever');    
});