#javascript
#javascript
Вопрос:
Я пытаюсь вернуть выбранное значение в выпадающем списке и приписать его atom.name для того, чтобы изменить имя атома. По умолчанию присутствует молекула ch2, а при нажатии на Na. Ch2 следует заменить на Na, но проблема заключается в области прослушивателя событий и возможности управлять этими двумя eventlistener. Тот, кто управляет выпадающим результатом
var a = document.getElementById('atomDropdown');
a.addEventListener('change', function() {
console.log(this.value);
}, false);
консоль.журнал выдает здесь правильный результат и
eventlistener, который управляет положением выпадающего меню с
document.body.addEventListener('mouseup', e => {
let atom = atoms.find(a => distance(a.position, { x: e.pageX, y: e.pageY}) <= a.r)
atomDropdown.classList.remove('hidden')
if(atom){
atomDropdown.style.left = atom.position.x 'px'
atomDropdown.style.top = (atom.position.y atom.r) 'px'
}
console.log(atom.name);
})
Что я безуспешно пытаюсь сделать, так это приписать atom.name до этого значения.
const canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
atoms = [],
bonds = [],
atomDropdown = document.getElementById('atomDropdown')
document.body.appendChild(canvas)
class Atom {
constructor({ x, y, name }){
this.position = {}
this.position.x = x
this.position.y = y
this.name = name
this.r = name.length * 10
atoms.push(this)
}
draw(){
let { position, name, r } = this,
{ x, y } = position
context.fillStyle = '#EEEEEE'
context.beginPath()
context.arc(x, y, r, 0, 2 * Math.PI)
context.fill()
context.fillStyle = '#000000'
context.font = '20px sans-serif'
context.textAlign = 'center'
context.fillText(name, x, y 5)
}
}
class Bond {
constructor({ atom1, atom2, type }){
this.atom1 = atom1
this.atom2 = atom2
bonds.push(this)
}
draw(){
let { atom1, atom2 } = this
context.beginPath()
context.strokeStyle = '#000000'
context.moveTo(atom1.position.x, atom1.position.y)
context.lineTo(atom2.position.x, atom2.position.y)
context.stroke()
}
}
let hexagon = {
size: 100,
x: width/2,
y: height/2
}
let lastAtom
for (var side = 0; side < 7; side ) {
let newAtom = new Atom({
x: hexagon.x hexagon.size * Math.cos(side * 2 * Math.PI / 6),
y: hexagon.y hexagon.size * Math.sin(side * 2 * Math.PI / 6),
name: 'CH2'
})
if(lastAtom) new Bond({ atom1: lastAtom, atom2: newAtom })
if(side == 6) new Bond({ atom1: newAtom, atom2: atoms[0] })
lastAtom = newAtom
}
function render(){
context.fillStyle = '#FFFFFF'
context.fillRect(0,0,width,height)
bonds.map(b => b.draw())
atoms.map(a => a.draw())
}
render()
function distance(p1, p2){
return Math.sqrt(Math.pow(p1.x - p2.x, 2) Math.pow(p1.y - p2.y, 2))
}
var a = document.getElementById('atomDropdown');
a.addEventListener('change', function() {
console.log(this.value);
}, false);
document.body.addEventListener('mouseup', e => {
let atom = atoms.find(a => distance(a.position, { x: e.pageX, y: e.pageY}) <= a.r)
atomDropdown.classList.remove('hidden')
if(atom){
atomDropdown.style.left = atom.position.x 'px'
atomDropdown.style.top = (atom.position.y atom.r) 'px'
}
console.log(atom.name);
})
#atomDropdown {
position: absolute;
amp;.hidden {
display: none;
}
}
<select id="atomDropdown" class="hidden">
<option>Test1</option>
<option>Test2</option>
<option>Test3</option>
</select>
Ответ №1:
Похоже, желаемое поведение заключается в изменении значения atom.name для атома, на который был сделан щелчок, замените его именем из выпадающего меню.
Например, щелкните по атому CH2 -> выберите «Test1» из выпадающего меню -> значение this.name для атома, который вы нажимаете, изменяется с «CH2» на «Test1».
Если это так, проблема заключается в том, как настроить таргетинг на тот же атом из вашего последнего события «наведения курсора мыши» в обработчике «изменить» для atomDropdown. В этом случае вы можете добавить новую переменную в свои определения:
const canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
atoms = [],
bonds = [],
atomDropdown = document.getElementById('atomDropdown')
var selectedAtom = null
установите selectedAtom в экземпляр atom в обработчике «mouseup»:
document.body.addEventListener('mouseup', e => {
let atom = atoms.find(a => distance(a.position, { x: e.pageX, y: e.pageY}) <= a.r)
atomDropdown.classList.remove('hidden')
if(atom){
selectedAtom = atom
atomDropdown.style.left = atom.position.x 'px'
atomDropdown.style.top = (atom.position.y atom.r) 'px'
}
console.log(atom.name);
})
и обновление selectedAtom.name в «событии изменения»:
var a = document.getElementById('atomDropdown');
a.addEventListener('change', function() {
if (selectedAtom) {
selectedAtom.name = this.value;
render(); //added so that the GUI updates when the name value changes
}
console.log(this.value);
}, false);
РЕДАКТИРОВАТЬ: чтобы немедленно обновить имя atom в том виде, в каком оно отображается в графическом интерфейсе / на дисплее, вам также необходимо вызвать render() после selectedAtom.name изменяется в событии «изменить» atomDropDown.
Комментарии:
1. Привет, esopp, это странно, потому что я могу изменить каждый атом, кроме правильного: codepen.io/anon/pen/WmdWbW
2. Похоже, что справа есть два перекрывающихся атома (т. Е. дополнительный, 7-й атом, нарисованный поверх первого в той же позиции). Если вы измените условие «сторона < 7» на «сторона < 6» в
for (var side = 0; side < 7; side )
и «если (сторона == 6)» на «если (сторона ==5)» вif(side == 6) new Bond({ atom1: newAtom, atom2: atoms[0] })
, это устранит проблему.3. Это случай, когда find() возвращает только первый совпадающий элемент в массиве, когда есть два совпадающих элемента. Это происходит в событии «наведение курсора мыши», где atoms[0] становится выбранным атомом. Поскольку атомы[0] будут отрисованы первыми в функции render(), при отрисовке атомов[6] атомы[0] закрываются.
Ответ №2:
Если я правильно понимаю этот вопрос, вы хотите установить значение выпадающего меню равным atom.name ?
Если это так, вам нужно добавить атрибут «value» к параметрам, тогда вы можете сказать что-то вроде:
document.getElementById("atomDropdown").value = atom.name
HTML-код будет выглядеть примерно так:
<select id="atomDropdown" class="hidden">
<option value="Na">Test1</option>
<option value="Ch2">Test2</option>
<option value="O2">Test3</option>
</select>