1

I've made a small trick in a div where I put my own "data" precising what to do if the user clicks on it.

My JavaScript code looks like (lot of code omitted for sake of clarity):

$('[data-hqf-switch]').click(function() {
    var t = $(this).attr('data-hqf-switch').split('/'),
        i = 0;
    if (t % 2) {
        alert('Burn the dev. Its the dev. himself who wrote that.');
        return;
    }
    while (i < t.length) {
        var ev = sw(t[i++], '$')+'.'+sw(t[i++], 'd')+';';
        eval(ev);
    }
});

Now in my HTML I have something like that:

<div class="col-lg-12" data-hqf-switch="$.pt().pv()/Xd/$.pt()/Xu">
    <h4>25 mars 2016 22:07 - You wrote...</h4>
    <p>J'ai refusé votre invitation</p>
    <button type="button" class="btn btn-default" 
            data-toggle="modal" 
            data-target="#modal-msg-7-24" title="Répondre">
        <i class="fa fa-envelope-o"></i>&nbsp;Répondre
    </button>
    <div class="modal fade" id="modal-msg-7-24" tabindex="-1" 
         role="dialog" 
         aria-labelledby="Envoyer un message" aria-hidden="true" 
         style="display: none;">
        <div class="modal-dialog">
            <div class="modal-content">
            </div>
        </div>
    </div>
    <button class="btn btn-warning" 
            data-hqf-switch="$.pt().pt().pv()/Xd/$.pt().pt()/Xu">
        Fermer
    </button>
</div>                

The most important is the first button: when clicked it shows the modal dialog box which is declared just after the button.

Everything should work fine except that when you click on the button it's like you click on the button and on the "surrounding" div because the event of the div is launched too.

What am I missing?

Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
  • Your string in the `alert()` has mis-matching quotes which will be resulting in a syntax error. I would suggest you look at using an editor with syntax highlighting as it makes errors like that almost impossible to miss. As for stopping propagation, get the event from the handler and call `stopPropagation()` on it. Finally note that the use of `eval()` is extremely bad practice and should be avoided at all costs. What exactly are you trying to achieve? I'm sure there's a less needlessly convoluted way of achieving it. – Rory McCrossan Apr 11 '16 at 12:34
  • I know what eval() is all about... but here's what I wanted to do: a generic method where you just precise on an element, when we click on it what to do. It's only about showing or hiding (with various effects) elements relative to this element: (ie prev, next, parent, and so on). And I wanted to remove all unnecessary stuff like locating elements with their ids or things like that because my HTML template got too messy with that. Until now I'm more than happy with my solution because it cover all my needs, and more than I could imagine. And I've put my own solution which is ok and generic! – Olivier Pons Apr 11 '16 at 13:01

2 Answers2

1

Event propagation means the event is handled for the clicked element and all ancestors.

You may want to look into event.stopPropagation().


I believe your small trick will eventually make you regret the day you invented it if you're doing anything moderately complicated.

alex
  • 479,566
  • 201
  • 878
  • 984
  • Just to expand it would look like `$('[data-hqf-switch]').click(function(event) { event.stopPropagation(); // then carry on with your code` – Djave Apr 11 '16 at 12:39
  • Ok but it's not me who wrote the `data-toggle` and `data-modal` stuff, it's part of the bootstrap stuff... so how would you do? – Olivier Pons Apr 11 '16 at 12:39
  • I just regret the day I've said "I give up on Delphi I'll make a living thanks to developping Websites". Because it should not be called WWW but WWM (World Wide Mess) (almost all the time WWFM) – Olivier Pons Apr 11 '16 at 12:40
  • @OlivierPons Yeah front-end development is a bit of a kludgy hack but it's better than it's been in the past. – alex Apr 11 '16 at 12:42
  • I've tried to add "event.stopPropagation();" in my code, and the `data-toggle` is ignored. It does exactly the opposite of what I want to do (= "normal behavior" with the button, and dont call the "click" of its parent) – Olivier Pons Apr 11 '16 at 12:42
0

The solution is here. And it's not a duplicate, even though it's close to.

I just test if the element the user "has pushed" has actually the "switch data". If not, I return instantaneously because I suppose (and I dont imagine a case where it's not) that it's one of the children of this element, not the element itself.

$('[data-hqf-switch]').click(function(e) {
    if ($(e.target).filter(':not([data-hqf-switch])').length) {
        return;
    }
    /* ok the target contains a 'data-hqf-switch' attribute */
    /* ... blabla ...*/
}
Community
  • 1
  • 1
Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
  • There's an easier way to pinpoint the element clicked among multiple siblings and not trigger events on ancestors (parent, grandparent, etc.) It's 5+ lines of JS (not counting the event handler), not jQuery. – zer00ne Apr 11 '16 at 14:43
  • If you just say "there's an easier way" without giving the solution it wont be of any help.... – Olivier Pons Apr 11 '16 at 14:47
  • Seeing that you have already found a solution, I don't want to waste my time if you're not interested. – zer00ne Apr 11 '16 at 15:49