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?
1 Answer 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:
- Wait for element to be present in DOM, and once it is available, add a listener function.
- Use
liveevents (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.
resizeVerticallyInitright 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.