0

jQuery:

var isResizing = false,
    lastDownX = 0;

$(function () {
    var container = $('#container'),
        top = $('#top-panel'),
        handle = $('#drag');

    handle.on('mousedown', function (e) {
        isResizing = true;
        lastDownX = e.clientY;
    });

    $(document).on('mousemove', function (e) {
        // we don't want to do anything if we aren't resizing.
        if (!isResizing) 
            return;
        var offsetRight = top.height() + (e.clientY - container.offset().top);

        top.css('top', offsetRight);
    }).on('mouseup', function (e) {
        // stop resizing
        isResizing = false;
    });
});

JavaScript:

var isResizing = false
// eslint-disable-next-line no-unused-vars
var lastDownX = 0

function resizeVerticallyInit () {
  var top = document.querySelector('#topology-container')
  var handle = document.querySelector('#drag')

  handle.addEventListener('mousedown', function (e) {
    isResizing = true
    lastDownX = e.clientY
  })

  document.addEventListener('mousemove', function (e) {
    // we don't want to do anything if we aren't resizing.
    if (!isResizing) {
      return
    }
    var offsetRight = top.height() + 20

    document.querySelector('#topology-container').style.top = offsetRight
  })

  document.addEventListener('mouseup', function (e) {
    // stop resizing
    isResizing = false
  })
}

mounted () {
  ...
  resizeVerticallyInit()
}

As you can see I use JavaScript function in Vue.js component in mounted() life-cycle method.

I've tried to convert it, but it doesn't work.

First of all I needed to put:

// eslint-disable-next-line no-unused-vars
var lastDownX = 0

I don't know why it's complaining that lastDownX is unused.

The second one is error:

"[Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'addEventListener' of null"

It's complaining about:

  handle.addEventListener('mousedown', function (e) {
    isResizing = true
    lastDownX = e.clientY
  })

Could someone help to convert it?

5
  • 1
    Could you at least post your code properly to begin with? Commented Aug 5, 2020 at 11:59
  • I've done all as usual, but it displays like that. Commented Aug 5, 2020 at 12:01
  • (Using 1), 2) creates numbered lists, inside those the normal four-space-indent for code does not appear to fully work. Fixed, by removing the numbers.) Commented Aug 5, 2020 at 12:04
  • I don’t see where you would even be calling resizeVerticallyInit right now. But that is probably part of the problem - $(function () {}) is jQuery syntax for firing this at document.ready - if you did nothing in your implementation, to make sure the function is called after that, then it probably doesn’t find the element, because it simply does not exist yet. Commented Aug 5, 2020 at 12:05
  • I use JavaScript function in Vue.js component in mounted(). Commented Aug 5, 2020 at 12:10

1 Answer 1

1

First of document.querySelector method will return null if the element is not present in DOM. You cannot call addEventListener on null. In jQuery it worked because jquery constructs a separate object (called jQuery object). A jQuery object looks somewhat like this:

{
  0: {...} // HTMLElement reference
  length: 1
} // jQuery object

This object exposes a jQuery API which has on method for event handling (available regardless of presence of actual DOM element). This is a beauty of jQuery (and a drawback).

Query selector method on the other hand returns the HTMLElement. If the element is not present in DOM then null is returned.

Now assuming that the element will appear in DOM after certain amount of time, there are two things you can do:

  1. Wait for element to be present in DOM, and once it is available, add a listener function.
  2. Use live events (event delegation) in JavaScript.

I will show you the second approach:

setTimeout(() => {
  document.querySelector('#container').innerHTML = `<button id="btn">Click</button>`;
}, 3000);

document.addEventListener('click', (e) => {
  if (e.target.id === 'btn') {
    alert('Click works!');
  }
});
<div id="container">
  A button will appear after 3 seconds. However, click event would still work.
</div>

As you can see I am using e.target to detect which element I clicked inside document (where I have attached the listener). Once the condition matches, it triggers the alert. This allows us to bind events for elements that are not initially present in DOM.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.