Forum Moderators: open

Message Too Old, No Replies

eventListener to check when an element is hidden

         

csdude55

3:08 am on Apr 24, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What I have is an element that is display: none by default, then the user clicks a button to toggle it to display: block.. Or, more accurately, I'm using jQuery to toggle from hide() to show().

The same button clicks opens a script via Ajax, and I have a document.onclick function running so that if the user clicks anywhere on the page other than the opened Ajax script, the element toggles back to hide().

Like so:

// the JavaScript
document.onclick = function() {
if (toggle.el) $('#' + toggle.el).hide();
}

$.fn.toggleClick = function(e) {
toggle.el = this.attr('id');
this.toggle();
}

// the HTML to open the Ajax script
<div onClick="$('#bar').toggleClick(event);
$('#bar').ajax('foo.php');">
Blah
</div>

<div id="bar" style="display: none"></div>

// and inside of foo.php
<div id="someMenu"
onMouseOver="toggle.el= false;"
onMouseOut ="toggle.el= 'bar';">
Blah
</div>


Now I want to modify foo.php so that when it's toggled back to hide() then it will run a short script of its own. Or, I guess it could be in the original HTML page (with the onClick), but I definitely DON'T want it in the document.onclick or toggleClick functions because I use them in a hundred other scripts and don't want to modify all of them.

I know that I can put a second document.onclick function in the original HTML page, but that negates the original document.onclick so I have to end up duplicating the whole function.

I could also modify everything like this, and it works OK:

// the JavaScript
document.onclick = function() {
if (toggle.el) $('#' + toggle.el).hide();

if (otherVariables)
// do stuff
}

$.fn.toggleClick = function(e) {
toggle.el = this.attr('id');
this.toggle();
}

// the HTML to open the Ajax script
<script>
var otherVariables = 'stuff';
</script>

<div onClick="$('#bar').toggleClick(event);
$('#bar').ajax('foo.php');">
Blah
</div>

<div id="bar" style="display: none"></div>


But the problem with THAT is that I might have 2 or 3 scripts running on the same page, so I might catch some interference.

Is there not a way to do something like this?

// I tried 'hide' and 'blur' with no luck
$('#bar').on('hide', function () {
// do stuff
});

csdude55

7:28 pm on Apr 24, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I've been working on that second example, and here's where I've gotten:

// the main JavaScript
document.onclick = function() {
if (toggle.el) $('#' + toggle.el).hide();

if (typeof closeAjaxCallback == 'function')
closeAjaxCallback();
}

$.fn.toggleClick = function(e) {
toggle.el = this.attr('id');
this.toggle();
}

// the HTML page that opens the Ajax script
<script>
function closeAjaxCallback() {
alert(otherVariables);
}
</script>

<div onClick="$('#bar').toggleClick(event);
$('#bar').ajax('foo.php');">
Blah
</div>

<div id="bar" style="display: none"></div>

// and inside of foo.php
<script>
var otherVariables = 'stuff';
</script>


Using this, I can create a function on the HTML page called "closeAjaxCallback()", and the document.onclick will run it if it exists. This won't mess up my legacy projects, because if the function isn't on the page then it won't try to run it.

And creating otherVariables inside of the Ajax script (foo.php) eliminates the problem of the second instance overwriting the first.

This works so I'll stick with it, but it seems like a lot of code when I was just hoping for a listener for when bar is hidden. Hopefully this will help someone else out, but if someone has a better method then please post it! :-)

JAB Creations

9:24 am on May 31, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Offhand I do not think there is any "style-change" event. What you'll need to do is hook whatever function you're using to change the style of that element to call in the specific condition or a much better idea is to create your own "style-change" "event" function. However keep in mind that a lot of JavaScript is used to change the styles of elements and your goal should be to keep things dynamic.

In example my platform handles a lot of things with global events (which are generally discouraged). Some forms don't require excessive validation however some do. When the onsubmit event is triggered one of the things that happens is the name attribute/value pair is looked at:

<input name="blog_post_thread_comment" type="submit" />


Before I continue I would like to note that the name scheme is important here. There are various modules (blog, forums, email, search, etc). Then the HTTP method (get, post, put, delete, etc). Thirdly the major functionality (a blog thread or another example, a forum thread). If there is a minor distinction (e.g. in some modules such as Guest Book or Search there are little to no minor distinctions) a fourth word.

I will then look to see if a function with the name attribute's value exists (e.g. function blog_post_thread_comment() {/**/}). If it does exist the form handling is handed over to that function. You can call functions in the traditional manner (my_function(parameter1, parameter2)) and you can also call them from the window object to avoid having to use eval (window['my_function(parameter1, parameter2)]). If no function was found with the full exact name I then JavaScript to split the underscores and in such a case would effectively search for blog_post_thread. Sometimes functionality for two different forms may be very much alike (though they shouldn't also be forced if they're too different). If no matching named function exists the generic form handler eventually will submit the form itself.

The inexperienced will make highly proprietary functions and eventually realize they've got code bloat. You should concentrate on trying to orient your code around few (relatively speaking) though highly dynamic and refined custom functions which you will, if executed well enough, find will save you an amazing amount of time. As for your specifically the challenge you're dealing with there is no event directly relevant and you'll have to have your code handle it directly and hopefully dynamically. If your functions are too "global" in nature they won't be useful hence why you'll want a few dozen functions (once things have matured on a long term project) so you'll still have the flexibility to emulate "missing" events. In example HTML5 allows data-* attributes (e.g. data-style) so if an attribute exists (element.hasAttribute('data-style') and element.getAttribute('data-style')) you may find a generic-enough term that hints your code should run a function in certain scenarios though it will be up to you to determine not only if that is a valid approach for your code though also how to implement it. I hope this helps.

John