最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

What is the javascript equivalent to jquery closest()? - Stack Overflow

programmeradmin5浏览0评论

I have the following code, which is written in DOM API instead of jquery. I'm not sure why. It's inside the submit function for jquery form validation. I need to change the "parentNode" part so that instead of "parent" it is "closest." I'm no good with javascript. I tried my hand at converting this to jquery, but wasn't able to get that to work. Basically, if this were jquery, I'd need to change .parent() to .closest().

var summary = "";

$.each(element, function() { 
summary += "<li>" + this.element.parentNode.getElementsByTagName('label')[0].innerHTML.replace("\<span\>*\<\/span\>","") + "</li>"; 
});

summary = summary.replace(/\<li\>.+\<\/li\>\1/, "$1");

alert(summary);

Is this possible to do with javascript? Or, is there an easy way to convert this to jquery?

UPDATE: Here is a fiddle to help explain what I'm trying to accomplish. Basically, because I added a 'span' tag around one of the inputs, the 'p' tag is no longer the parent. As such, the parentNode is not finding the 'p' tag anymore.

/

UPDATE 2 -- THE previous fiddle link was incorrect. The link above is the right one.

How can I modify to find the <p> tag regardless of whether it is the direct parent, or a grandparent?

I have the following code, which is written in DOM API instead of jquery. I'm not sure why. It's inside the submit function for jquery form validation. I need to change the "parentNode" part so that instead of "parent" it is "closest." I'm no good with javascript. I tried my hand at converting this to jquery, but wasn't able to get that to work. Basically, if this were jquery, I'd need to change .parent() to .closest().

var summary = "";

$.each(element, function() { 
summary += "<li>" + this.element.parentNode.getElementsByTagName('label')[0].innerHTML.replace("\<span\>*\<\/span\>","") + "</li>"; 
});

summary = summary.replace(/\<li\>.+\<\/li\>\1/, "$1");

alert(summary);

Is this possible to do with javascript? Or, is there an easy way to convert this to jquery?

UPDATE: Here is a fiddle to help explain what I'm trying to accomplish. Basically, because I added a 'span' tag around one of the inputs, the 'p' tag is no longer the parent. As such, the parentNode is not finding the 'p' tag anymore.

http://jsfiddle.net/9um8xt79/1/

UPDATE 2 -- THE previous fiddle link was incorrect. The link above is the right one.

How can I modify to find the <p> tag regardless of whether it is the direct parent, or a grandparent?

Share Improve this question edited Sep 1, 2014 at 0:42 Fabrício Matté 70.1k27 gold badges133 silver badges167 bronze badges asked Aug 31, 2014 at 23:51 LindsayLindsay 1271 gold badge3 silver badges11 bronze badges 16
  • 6 "which is written in javascript instead of jquery" - this overdrove my oxymoron/contradiction detector. – The Paramagnetic Croissant Commented Aug 31, 2014 at 23:52
  • 1 Sorry, I'm using the wrong terminology. I realize jquery IS javascript. I'm not sure what you call the parentNode and getElementsByTagName parts.... XML? – Lindsay Commented Aug 31, 2014 at 23:54
  • 1 @Lindsay the term you're looking for is native DOM API. – Fabrício Matté Commented Aug 31, 2014 at 23:56
  • Thank you Fabricio. Is there any reason something like this would need to be written this way? – Lindsay Commented Aug 31, 2014 at 23:57
  • 1 @Lindsay well, I assume you know API is the term to reference a software component's public operations, methods, types, input and output. And you're talking about DOM methods. So yep, DOM API. – Fabrício Matté Commented Sep 1, 2014 at 0:11
 |  Show 11 more comments

4 Answers 4

Reset to default 19

Hello from the future (2019)! This is now directly possible with native DOM API in modern browsers (that is, not Internet Explorer): Element.closest

So you can replace jQuery(selector).closest with document.querySelector(selector).closest.

Similarly, you should be able to eliminate other jQuery functions in your code such as .children() by using native .children and .addClass() by using .classList.add().

See also

  • YouMightNotNeedJquery.com
  • "Native Equivalents of JQuery Methods - Part 1: Selecting DOM Elements" (links for other parts are at the bottom of this codepen)
  • "Native JavaScript Equivalents of jQuery Methods: the DOM and Forms"

Here's the javascript for the .closest property:

closest: function( selectors, context ) {
        var cur,
            i = 0,
            l = this.length,
            matched = [],
            pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
                jQuery( selectors, context || this.context ) :
                0;

        for ( ; i < l; i++ ) {
            for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
                // Always skip document fragments
                if ( cur.nodeType < 11 && (pos ?
                    pos.index(cur) > -1 :

                    // Don't pass non-elements to Sizzle
                    cur.nodeType === 1 &&
                        jQuery.find.matchesSelector(cur, selectors)) ) {

                    matched.push( cur );
                    break;
                }
            }
        }

Whenever you're trying to figure out something is done in jQuery, you can always just take a look at the jQuery source and reverse engineer it to your scenario. Although there will be times when this won't work, the way your question is phrased, this is where I'd start.

Source: http://code.jquery.com/jquery-2.1.1.js

Reading your question carefully, I think you want something like

var summary = "";
$(element).each(function (id, ele) {
    summary +=  "<li>" + $(ele).closest("label").html().replace("\<span\>*\<\/span\>","") + "</li>";
});

summary = summary.replace(/\<li\>.+\<\/li\>\1/, "$1");

But I'm not sure what you're doing with this last line. First you add all the label-Elements as li-Elements and then you remove all those li-s? But I'm not really a RegExp profi so I might miss something here.

Maybe I'm a bit late ;-) but here is a simple recursive function (calls it self with the parentNode to be analised) in plain old JS:

function closest( e, classname ) {
    if( hasClass( e, classname ) ) {
        //We found it!
        return e;
    }
    //console.error(e.parentNode.nodeName);
    if(e.parentNode.nodeName != 'BODY') //Last possibility! There's no parent behind!
        return e.parentNode && closest( e.parentNode, classname );

    //Didn't found it?
    return null;
}

hasClass() function (the equivalente to JQuery hasClass()) depends on the browser knowing classList - as in nowadays is almost the case.

But, anyway, here it goes for both older and (the so called) newer browsers:

var
    hasClass

;
if ( 'classList' in document.documentElement ) {
    hasClass = function( elem, c ) {
        return elem.classList.contains( c );
    };
}
else {
    hasClass = function( elem, c ) {
        return classReg( c ).test( elem.className );
    };
}

As notice, for older browsers, we use a RegExp to string comparision.
Here it is (and, promisse, final stuff :-) ):

function classReg( className ) {
    return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}

And that's it.
Now it's explained, if anyone uses the complete set of "tools", off course you have to code it down the inverse way (1st classReg(), then hasClass stuff and final our closest() queen).

Also, if you noticed, you gain here 2 equivalente JQuery tools (closest() and hasClass()) that you can use in multiple situations - as I use them for several years, now:
hasClass( elem, 'my-class-to-check' ) //<= returns true || false
closest( elem, 'my-class-to-look-up' ) //<= returns the look-up obj || null

发布评论

评论列表(0)

  1. 暂无评论