1

I want to add 'onclick' functionality to certain elements. These elements are perfectly targeted with this CSS, setting pointer-events to 'auto':

.custom-collections .o_slideshow .end-group {
    pointer-events: auto;
}

.custom-collections > .o_slideshow:first-child,
.custom-collections > .o_slideshow .o_slide[data-id="home_slide"],
.custom-collections > .o_slideshow:last-child {
    pointer-events: auto;
}

My javascript currently enables the elements to be dragged (on drag) and previewed (on long touch). Ultimately, I need it only to be previewed.

In the javascript, I include this, to disable drag functionality if 'defaultSlide' is one of the classes:

            if (event.target.classList.contains('defaultSlide')) {
                // If the slide contains 'defaultSlide', it shouldn't be draggable.
                return;
            }

How should I append the class defaultSlide to the elements? Alternatively, what else could I do, instead of an if class method, to have my drag-script return immediately?

Normally, I would add the class 'defaultSlide' to these elements in javascript when the elements are first created, but that requires a lot of code in my context of bad legacy code

  • Did you try hasClass method with jQuery? – Vecihi Baltacı Oct 18 '17 at 08:46
  • 3
    How do hasClass differ from event.target.classList.contains? – Karl Kristiansen Oct 18 '17 at 08:48
  • 6
    Keep in mind that import the whole library just to use a single function might not be a good aproach. – Hedegare Oct 18 '17 at 08:49
  • Is there any problem to run over all this elements and add the `defaultSlide` class? Alternatively, have you tried to add some class to their parent element? – Krusader Oct 18 '17 at 08:50
  • Short answer; yes, there's problems. In javascript, I cannot only target the ones I want to target. The CSS _does_ already target just the right ones, but those CSS selectors will only allow me to change properties, like I do with `pointer-events` - not append a class, that my javascript can point at in the `if` statement. – Karl Kristiansen Oct 18 '17 at 08:54

1 Answers1

3

If that CSS perfectly targets the elements, you have at least two options:

  1. Element#matches checks to see if the element you call it on matches the CSS selector you provide. So you could use Element#matches instead of your class check when you get the event, to see if the element matches those selectors:

    var selectors = '.custom-collections .o_slideshow .end-group, ' +
                    '.custom-collections > .o_slideshow:first-child, ' +
                    '.custom-collections > .o_slideshow .o_slide[data-id="home_slide"], ' +
                    '.custom-collections > .o_slideshow:last-child';
    if (event.target.matches(selectors)) {
        // return;
    }
    
  2. document.querySelectorAll returns a collection of elements that match the CSS selector you provide. So on page load, you could use querySelectorAll to get all elements matching those selectors and add the class to them:

    var selectors = '.custom-collections .o_slideshow .end-group, ' +
                    '.custom-collections > .o_slideshow:first-child, ' +
                    '.custom-collections > .o_slideshow .o_slide[data-id="home_slide"], ' +
                    '.custom-collections > .o_slideshow:last-child';
    document.querySelectorAll(selectors).forEach(function(e) {
        e.classList.add("defaultSlide");
    });
    

    ...and then use your existing code that checks for the class when you get the event.


Side note: The object returned by querySelectorAll only recently got the forEach method used above; see this answer for details and workaround for slightly out-of-date browsers.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • So close! The selector works for the last three bits, but not the `.custom-collections .o_slideshow .end-group` one. Maybe I need something else than `, +` on the first line of the selectors? – Karl Kristiansen Oct 18 '17 at 09:32
  • @KarlKristiansen: No, that code is correct. If there are elements that match `.custom-collections .o_slideshow .end-group`, they'll be matched. If you're not seeing that, it suggests that selector is incorrect. – T.J. Crowder Oct 18 '17 at 09:33