Как обновить позицию х / у элемента popper.js? - PullRequest
0 голосов
/ 06 мая 2018

Как мне переместить элемент popper.js, чтобы следовать определенным координатам?

Мне удалось получить (я думаю) позицию каретки в текстовой области, но теперь мне нужно заставить Popper.js следовать ей.

Пробовал, обновляюсь и обновляюсь на руте и в модификаторах. Я вообще не разбираюсь в документации.

Я создал кодовую ручку, чтобы показать, чего я смог достичь:

https://codepen.io/anon/pen/gzGvvG

const refEl = document.getElementById('ref');
const popEl = document.getElementById('pop');

new Popper(refEl, popEl, {
  placement: 'auto',

            modifiers: {
                offset: {
                    enabled: true,
                    offset: '0,10'
                },
                flip: {
                    behavior: ['left', 'bottom', 'top']
                },
                preventOverflow: {
                    enabled: true,
                    padding: 10,
                    escapeWithReference: false,
                }
            },
});

document.getElementById("ref").onkeyup = function() {
  var xy = getCursorXY(refEl, refEl.selectionEnd)

  document.getElementById("log").innerText = `X: ${xy.x}, Y: ${xy.y}`;
}

Функция getcursorXY, которую я получил от Medium: https://medium.com/@jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a

1 Ответ

0 голосов
/ 09 марта 2019

Это не полный ответ на ваш вопрос ... так как нужно несколько настроек, чтобы заставить его работать так, как я думаю, вы пытаетесь заставить его работать. Но вот javascript, который я изменил из вашего CodePen, который, как полагают, является шагом в правильном направлении для того, чего вы хотите достичь.

    const refEl = document.getElementById('ref');
    const popEl = document.getElementById('pop');

    function update_popper(x, y) {
        new Popper(refEl, popEl, {
            placement: 'auto',

            modifiers: {
                offset: {
                    enabled: true,
                    offset: (x - 150) + ',' + (-1 * (y - 140))
                },
                flip: {
                    behavior: ['left', 'bottom', 'top']
                },
                preventOverflow: {
                    enabled: true,
                    padding: 10,
                    escapeWithReference: false,
                }
            },
        });
    }

    document.getElementById("ref").onkeyup = function () {
        var xy = getCursorXY(refEl, refEl.selectionEnd)

        document.getElementById("log").innerText = `X: ${xy.x}, Y: ${xy.y}`;
        update_popper(xy.x, xy.y);
    }

    const getCursorXY = (input, selectionPoint) => {
        const {
            offsetLeft: inputX,
            offsetTop: inputY,
        } = input
        // create a dummy element that will be a clone of our input
        const div = document.createElement('div')
        // get the computed style of the input and clone it onto the dummy element
        const copyStyle = getComputedStyle(input)
        for (const prop of copyStyle) {
            div.style[prop] = copyStyle[prop]
        }
        // we need a character that will replace whitespace when filling our dummy element if it's a single line <input/>
        const swap = '.'
        const inputValue = input.tagName === 'INPUT' ? input.value.replace(/ /g, swap) : input.value
        // set the div content to that of the textarea up until selection
        const textContent = inputValue.substr(0, selectionPoint)
        // set the text content of the dummy element div
        div.textContent = textContent
        if (input.tagName === 'TEXTAREA') div.style.height = 'auto'
        // if a single line input then the div needs to be single line and not break out like a text area
        if (input.tagName === 'INPUT') div.style.width = 'auto'
        // create a marker element to obtain caret position
        const span = document.createElement('span')
        // give the span the textContent of remaining content so that the recreated dummy element is as close as possible
        span.textContent = inputValue.substr(selectionPoint) || '.'
        // append the span marker to the div
        div.appendChild(span)
        // append the dummy element to the body
        document.body.appendChild(div)
        // get the marker position, this is the caret position top and left relative to the input
        const { offsetLeft: spanX, offsetTop: spanY } = span
        // lastly, remove that dummy element
        // NOTE:: can comment this out for debugging purposes if you want to see where that span is rendered
        document.body.removeChild(div)
        // return an object with the x and y of the caret. account for input positioning so that you don't need to wrap the input
        return {
            x: inputX + spanX,
            y: inputY + spanY,
        }
    }        

что я сделал здесь, это переместил ваш Popper () в функцию, называемую update popper, которая будет каждый раз перестраивать popper с новым с новым смещением x, y. Вам не нужно беспокоиться о создании нового Popper () снова и снова, так как в основном это всего лишь математика, с очень небольшим весом.

В любом случае, я думаю, это должно помочь вам приблизиться к вашей цели ... удачи!

...