2

What I'm looking to do COULD be accomplished easily if CSS4 standards were in-place. But, I am looking to do something similar with Greasemonkey in the meantime and learn more about parent selectors.

My early attempt looks a little like this:

$(document).find("minds-remind").parentElement.style.display = 'none';

The element I'm looking to access is:

minds-activity < div < div < minds-remind

So if it contains minds-remind, then hide parent minds-activity only in that instance. There are hundreds of minds-activity elements, I only want those containing div div minds-remind to become hidden.

Any help would be much appreciated and I am anxious to better understand how to go about pursuing this in the future. :)

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
govspiders
  • 23
  • 2
  • Possible duplicate of [Is there a CSS parent selector?](http://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector) – roberrrt-s Nov 23 '16 at 11:13
  • I'm not looking for CSS, I'm looking to do this in javascript in greasemonkey as previously stated, CSS4 standards are not yet available, so this cannot be accomplished through those methods and I have read that thread in the past. – govspiders Nov 23 '16 at 22:32

1 Answers1

1

You seem to be trying to use jQuery, so you can use the jQuery :has selector. Like so:

$(".minds-activity:has('.minds-remind')").hide ();


Or more precise (but also more brittle):

$(".minds-activity > div > div > .minds-remind").parents (".minds-activity").hide ();


The plain javascript equivalent:

document.querySelectorAll (".minds-activity > div > div > .minds-remind").forEach ( function (node) {
    node.parentNode.parentNode.parentNode.style.display = "none";
} );

For AJAX driven pages, use waitForKeyElements(), like so:

// ==UserScript==
// @name     _Hiding ancestors of select content
// @match    http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
//- The @grant directive is needed to restore the proper sandbox.

waitForKeyElements (
    ".minds-activity > div > div > .minds-remind", hideAncestor
);

function hideAncestor (jNode) {
    jNode.parents (".minds-activity").hide ();
}


Comparing the "¿good enough?" selector to the more precise/brittle one (Run the code snippet button, below):

$("button").click ( function (zEvent) {
    $("body > div").removeAttr ("style");
    switch (zEvent.target.id) {
        case "okay":
            $(".minds-activity:has('.minds-remind')").css ("background", "pink");
            break;
        case "precise":
            $(".minds-activity > div > div > .minds-remind").parents (".minds-activity").css ("background", "pink");
            break;
        default:
            console.error ("Missing case in button click handler: ", zEvent.target.id);
            break;
    }
} );
body > div {
    margin: 1ex;
    border: 1px solid gray;
    border-radius: 1ex;
    display: inline-block;
}
body > div > div {
    display: table;
    height: 3em;
}
body > div > div > div {
    display: table-cell;
    vertical-align: middle;
    min-width: 20vw;
    text-align: center;
}
button { margin: 1ex; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="minds-activity">
    <div><div><div class="">Good</div></div></div>
</div>
<div class="minds-activity">
    <div><div><div class="minds-remind">Bad</div></div></div>
</div>
<div class="minds-activity">
    <div><div><div><div class="minds-remind">Ugly</div></div></div></div>
</div>
<div class="hive-minds">
    <div><div><div class="minds-remind">Martian</div></div></div>
</div>
<button id="okay">Test good enough jQuery</button>
<button id="precise">Test precise jQuery</button>
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • Thank you! This is exactly what I was looking for and I've learned a ton, I wasn't aware I could use has to select the parent. Great response, very informative! It seems to work perfectly in that snippet and I can understand it alot better now, but sadly does not seem to work in the website I was hoping it would. I can 'display:none' for minds-remind in css, but it seems I won't be able to modify its parent with javascript. – govspiders Nov 24 '16 at 01:17
  • (1) That site uses AJAX, so you must use the `waitForKeyElements` code, above. ... (2) I used CSS classes above, but the site uses custom HTML elements, so the selector must change a bit. ... (3) The site's structure is different than what's in the question. ... So, putting it all together, this waitForKeyElements selector worked for me: `"minds-activity > div > minds-remind"`. – Brock Adams Nov 24 '16 at 04:43
  • `code` waitForKeyElements ( "minds-activity > div > minds-remind", hideAncestor ); function hideAncestor (jNode) { jNode.parents ("minds-activity").hide (); } `code` would be correct? – govspiders Nov 24 '16 at 04:48
  • Yes, but you also need the metadata block listed above. Those `@require`s and `@grant`s are important. – Brock Adams Nov 24 '16 at 04:50