gpt4 book ai didi

javascript - 如何在带有文本的 Html 框中创建建议框(Javascript 中的提示框)

转载 作者:技术小花猫 更新时间:2023-10-29 12:31:17 24 4
gpt4 key购买 nike

enter image description here我正在尝试制作一个页面,允许用户在单击一个单词后获得一个小的建议框(如一个非常小的弹出窗口),他可以在其中单击并选择他想要的同义词。

我不确定这可以用什么语言完成,可能是 javascript,但我没有找到任何例子。

html代码如下:

Original:
I <b class="synonyms" style="color:black;"
title="love|really like|really love">like</b> apples.

The result should be(after a user chooses synonyms):
I <b>{like|love}</b> apples.


因此,例如,当他从句子“我喜欢苹果”中单击“喜欢”时,应该有一个小建议框,他可以在所有建议选项中进行选择(爱|真的喜欢|真的很喜欢)。

结果是原创加上他选择的。

这是我的 javascript 示例,但是我不确定是否有办法单击特定单词(一个句子中可能有多个单词),以及是否可以设置建议框样式并添加单词列表单击它们以从中进行选择。

<!DOCTYPE html>
<html>
<body>

<p>I <b id="demo">like</b> apples.</p>

<button onclick="choose()">Try it</button>


<script>
function choose() {
var synonym = prompt("Choose synonyms:", "like");

if (synonym != null) {
document.getElementById("demo").innerHTML =
"{" + "like" + "|" + synonym + "}";
}
}
</script>

</body>
</html>

最佳答案

...however I am not sure if there is a way to click on specific word (there could be more than one word in a sentence), and also is there way to style the suggestion box and add list of words to choose from by clicking on them.



把你的问题分解成几个步骤。这将使您更容易理解问题域并设计解决方案。根据我从您的问题中得出的结论,大致步骤及其实现可能类似于下面描述的步骤。

注释 1 :答案基于纯 JavaScript。请记住,所有框架(如 jQuery 等)都是仅在更高级别抽象的 JavaScript。首先学习基本的 JavaScript 对您来说很重要。

注释 2 :我在整个答案中以嵌入链接的形式提供了关键概念的引用(供您获取更多信息和学习)。

1) 文字的标记和 Javascript 设置:有些词有同义词。同义词在标题属性中的标记本身中可用。您到达的标记很好:

标记:
<p>
I <i class="synonyms" title="love|really like|really love">like</i> apples.
I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges.
</p>

我们需要能够识别所有带有同义词的单词,以便我们可以使用 Javascript 来操作它们。这些在标记中标识为 i具有名为 synonyms 的类的元素.

Javascript:
var words = [].slice.call(document.querySelectorAll('i.synonyms'));

querySelectorAll 返回一个节点列表,因此将其转换为数组的最简单方法是调用 slice on array prototype .我们需要一个数组,以便我们稍后对其进行迭代。

2) 菜单的标记和Javascript设置:需要弹出一个意见箱。因此,只需添加一个元素来保存您的同义词。您已经知道会有一个同义词列表,因此在语义上有一个列表元素是有意义的。并给它一个id。稍后我们将动态填充它。

标记:
<ul id="synonymMenu"></ul>

Javascript:
var menu = document.getElementById('synonymMenu');

3) 建议框菜单应该弹出 : 每当点击这样的词时。所以,我们需要在所有这些单词上添加一个事件监听器来监听点击事件。我们已经有了变量 words 中的单词在上面的第一步中。我们只是迭代和 add the event listener执行函数 manageMenu .稍后我们将定义该函数。在此期间,我们还使用 setAttribute 将现有单词缓存在数据属性中以便以后使用它。 .
words.forEach(function(wrd) {
wrd.setAttribute('data-word', wrd.textContent);
wrd.addEventListener('click', manageMenu);
});

4) 用选定的同义词替换单词 :每当在建议框菜单中单击同义词时。因此,我们还必须向同义词列表添加一个单击事件监听器。我们已经将菜单存储在变量 menu 中在上面的步骤 2 中。只需添加监听器即可执行函数 applySynonym .稍后我们将定义该函数。
menu.addEventListener('click', applySynonym);

5)我们也要关闭悬空的意见箱 :我们可以通过点击 body 的任何地方来做到这一点。只需在 body 上添加另一个 click 事件处理程序。执行函数 toggleMenuhide范围。稍后会定义这个函数。
document.body.addEventListener('click', function() {
toggleMenu('hide');
});

6) 根据 title 属性创建同义词列表并显示 :它在建议框菜单中,当单击单词时。我们将在 manageMenu 中定义我们在第 3 步中声明的函数。解释在代码注释中。
function manageMenu(e) {
// define variables
var synonyms, optn, link, position;

// clear existing list and then show the menu
clearMenu(); toggleMenu('show');

// cache the click event target to a variable to be used later
currentWord = e.target;

// get the position of word relative to viewport
position = currentWord.getBoundingClientRect();

// use that position to shift the popup menu near to the word
menu.style.top = position.top + 24 + 'px';
menu.style.left = position.left + 2 + 'px';

// extract title attribute, split by | and store in array
synonyms = currentWord.getAttribute('title').split('|');

// iterate array creating an li and anchor for each synonym
// createElement creates a new element
// appendChild adds an element to another
synonyms.forEach(function(syn) {
optn = document.createElement('li');
link = document.createElement('a');
link.setAttribute('href', '#'); link.textContent = syn;
// add anchor to li, and the li to the menu
optn.appendChild(link); menu.appendChild(optn);
});
// stop propagation of click, so that it doesn't go to body
e.stopPropagation();
}

上面代码中给你的关键引用是关于 using the event object and its target , getting the position of word relative to viewport , createElement , appendChild , 和 stopPropagation

7) 原词后应加上同义词: 并在其位置显示,一旦单击同义词。这我们将在 applySynonym 中定义我们在步骤 4 中引用的函数。
function applySynonym(e) {
var txt = '';

// Because we added event listener to the parent ul element,
// we have to check if the clicked element is the anchor or not
if (e.target.tagName != 'A') { return false; }

// We retrieve the orginal text from the data attribute,
// which we cached in step 6 above. And append current anchor's text
txt += '{' + currentWord.getAttribute('data-word') + '|';
txt += e.target.textContent + '}';
// replace the text of the word
currentWord.textContent = txt;
toggleMenu('hide'); // hide the suggestion box menu
// stop propagation of click, so that it doesn't go to body
// prevent default so that clicking anchor doesn't jump to top
e.stopPropagation(); e.preventDefault();
}

上面代码中给你的关键引用是关于 preventDefault .

8) 我们定义了其余的辅助函数 :
function toggleMenu(mode) {
if (mode == 'show') { menu.style.display = 'block'; }
if (mode == 'hide') { menu.style.display = 'none'; }
}

function clearMenu() {
// we loop the child nodes of menu ul element,
// remove the last child (last li) of that ul element,
// until it does not has-child-nodes.
while (menu.hasChildNodes()) {
menu.removeChild(menu.lastChild);
}
}

上面代码中给你的关键引用是关于 hasChildNodes , removeChild , 和 lastChild .

9) 通过 CSS 定义演示文稿,特别是使菜单绝对定位,在第一次加载时隐藏它并美化演示:
ul#synonymMenu {
position: absolute; display: none;
...
border: 1px solid #bbb; background-color: #efefef;
}

10) 测试。

演示 fiddle :https://jsfiddle.net/abhitalks/zske2aoh/

演示片段:

(function() {
var menu = document.getElementById('synonymMenu'),
words = [].slice.call(document.querySelectorAll('i.synonyms')),
currentWord = null
;

words.forEach(function(wrd) {
wrd.setAttribute('data-word', wrd.textContent);
wrd.addEventListener('click', manageMenu);
});
menu.addEventListener('click', applySynonym);
document.body.addEventListener('click', function() {
toggleMenu('hide');
});

function manageMenu(e) {
var synonyms, optn, link, position;
clearMenu(); toggleMenu('show');
currentWord = e.target;
position = currentWord.getBoundingClientRect();
menu.style.top = position.top + 24 + 'px';
menu.style.left = position.left + 2 + 'px';
synonyms = currentWord.getAttribute('title').split('|');
synonyms.forEach(function(syn) {
optn = document.createElement('li');
link = document.createElement('a');
link.setAttribute('href', '#'); link.textContent = syn;
optn.appendChild(link); menu.appendChild(optn);
});
e.stopPropagation();
}

function applySynonym(e) {
var txt = '';
if (e.target.tagName != 'A') { return false; }
txt += '{' + currentWord.getAttribute('data-word') + '|';
txt += e.target.textContent + '}';
currentWord.textContent = txt;
toggleMenu('hide');
e.stopPropagation(); e.preventDefault();
}

function toggleMenu(mode) {
if (mode == 'show') { menu.style.display = 'block'; }
if (mode == 'hide') { menu.style.display = 'none'; }
}

function clearMenu() {
while (menu.hasChildNodes()) {
menu.removeChild(menu.lastChild);
}
}

})();
* { font-family: sans-serif; }
html, body { height: 100%; }
i.synonyms { cursor: pointer; color: #333; }
ul#synonymMenu {
position: absolute; display: none;
width: auto; max-height: 120px;
overflow: hidden; overflow-y: auto;
list-style: none; padding: 0; margin: 0;
border: 1px solid #bbb; background-color: #efefef;
box-shadow: 0px 0px 6px 1px rgba(128,128,128,0.3);
}
ul#synonymMenu > li { display: block; }
ul#synonymMenu a {
display: block; padding: 4px 20px 4px 6px;
color: #333; font-size: 0.9em; text-decoration: none;
}
ul#synonymMenu a:hover {
background-color: #99b;
}
<p>
I <i class="synonyms" title="love|really like|really love">like</i> apples.
I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges.
</p>
<ul id="synonymMenu"></ul>



编辑:

根据 Op 的评论,代码已更新,以通过复选框容纳多个同义词选择。增加的复杂性是添加复选框而不是简单的 anchor ,更改相同的更新样式的事件监听器,以及在重复单击时保留预先存在的选择的逻辑。

更新 fiddle :https://jsfiddle.net/abhitalks/ffpL4f7k/

更新片段:

(function() {
var menu = document.getElementById('synonymMenu'),
menuWrap = document.getElementById('menuWrapper'),
okButton = document.getElementById('synOk'),
words = [].slice.call(document.querySelectorAll('i.synonyms')),
currentWord = null
;

words.forEach(function(wrd) {
wrd.setAttribute('data-word', wrd.textContent);
wrd.addEventListener('click', manageMenu);
});
okButton.addEventListener('click', applySynonym);
document.body.addEventListener('click', function(e) {
if (isDescendant(menuWrapper, e.target)) {
return;
}
toggleMenu('hide');
});

function manageMenu(e) {
var synonyms, opt, lbl, chk, txt, position, existing;
clearMenu(); toggleMenu('show');
currentWord = e.target;
position = currentWord.getBoundingClientRect();
menuWrap.style.top = position.top + 20 + 'px';
menuWrap.style.left = position.left + 2 + 'px';
existing = currentWord.textContent;
synonyms = currentWord.getAttribute('title').split('|');
synonyms.forEach(function(syn) {
opt = document.createElement('li');
lbl = document.createElement('label');
chk = document.createElement('input');
chk.setAttribute('type', 'checkbox');
txt = document.createTextNode(syn);
lbl.appendChild(chk);
lbl.appendChild(txt);
opt.appendChild(lbl);
menu.appendChild(opt);
});
preSelect(existing);
e.stopPropagation();
}

function preSelect(existing) {
var labels = [].slice.call(menu.querySelectorAll('label'));
labels.forEach(function(lbl) {
if (existing.indexOf(lbl.textContent) > -1) {
lbl.firstChild.checked = true;
}
});
}

function applySynonym(e) {
var txt = '', labels, checked, selected;
labels = [].slice.call(menu.querySelectorAll('label'));
checked = labels.filter(function(lbl){
return lbl.firstChild.checked;
});
selected = checked.map(function(lbl){
return lbl.textContent;
}).join('|');

txt += '{' + currentWord.getAttribute('data-word') + '|';
txt += selected + '}';
currentWord.textContent = txt;
toggleMenu('hide');
e.stopPropagation();
}

function toggleMenu(mode) {
if (mode == 'show') { menuWrap.style.display = 'block'; }
if (mode == 'hide') { menuWrap.style.display = 'none'; }
}

function clearMenu() {
while (menu.hasChildNodes()) {
menu.removeChild(menu.lastChild);
}
}

function isDescendant(parent, child) {
var node = child.parentNode;
while (node != null) {
if (node == parent) {
return true;
}
node = node.parentNode;
}
return false;
}

})();
* { font-family: sans-serif; box-sizing: border-box; }
html, body { height: 100%; }
div.wrap {
border: 1px solid #ddd; max-height: 480px;
padding: 4px 22px 4px 4px; font-size: 0.9em;
overflow: hidden; overflow-y: auto;
}
i.synonyms { cursor: pointer; color: #333; }
div#menuWrapper {
position: absolute; display: none; width: 128px;
padding: 4px; margin: 0;
border: 1px solid #bbb; background-color: #efefef;
box-shadow: 0px 0px 6px 1px rgba(128,128,128,0.3);
}
ul#synonymMenu {
max-height: 120px;
overflow: hidden; overflow-y: auto;
list-style: none; padding: 0; margin: 0;
}
ul#synonymMenu > li { display: block; }
ul#synonymMenu label {
display: block; color: #333; font-size: 0.9em;
padding: 2px 18px 2px 4px;
}
ul#synonymMenu label:hover { background-color: #99b; }
button#synOk { padding: 2px; width: 100%; }
<div class="wrap">
<p>
I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges.
</p>
<p>
I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges.
</p>
<p>
I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges. I <i class="synonyms" title="love|relish|savor">like</i> apples. I <i class="synonyms" title="love|relish|savor|enjoy|patronize|adore">like</i> oranges.
</p>
</div>
<div id="menuWrapper">
<ul id="synonymMenu"></ul>
<hr/>
<button id="synOk">Ok</button>
</div>

关于javascript - 如何在带有文本的 Html 框中创建建议框(Javascript 中的提示框),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36049942/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com