我在this site(基于MediaWiki)上看到了此自定义过滤器,并想模仿其功能以实现自学目的。
我正在使用的表的代码太长,所以我只把它放在in here上。
[2019-05-15]
基于@KévinBibollet的示例修改代码后,遇到了一个新问题。
这是我的js代码,只需将新功能添加到一个按钮即可进行测试。
//different types of data from the table
const type = document.querySelectorAll("tr td:nth-last-child(1)");
const kiwameStats = document.querySelectorAll("tr td:nth-last-child(2)");
//buttons
const tantouFilter = document.querySelector("div#Tantou");
const wakiFilter = document.querySelector("div#Wakizashi");
const tokuFilter = document.querySelector("div#Toku");
const kiwameFilter = document.querySelector("div#Kiwame");
//path for buttons' image
const waki = "https://vignette.wikia.nocookie.net/a-normal-playground/images/b/b8/Wakizashi.png";
const wakiClicked = "https://vignette.wikia.nocookie.net/a-normal-playground/images/1/1f/Wakizashi-full.png";
//bind events to buttons
wakiFilter.addEventListener("click", () => (filter(waki, wakiClicked, type)));
//general filter method
function filter(unclickedImageSrc, clickedImageSrc, data){
//store button's img and img's src for future use
currentImg = this.querySelector("img");
currentImgSrc = currentImg.getAttribute("src");
//is the button being clicked
isFiltered = (currentImgSrc === clickedImageSrc);
if(isFiltered){ //button was clicked, undo the filtering
currentImg.setAttribute("src", unclickedImageSrc);
for(i = 0; i < data.length; i++){
if(!data[i].innerHTML.includes(this.id)){
data[i].parentElement.style.display = " ";
}
}
}else{ //button isn't clicked, start filtering
currentImg.setAttribute("src", clickedImageSrc);
for(i = 0; i < data.length; i++){
if(!data[i].innerHTML.includes(this.id)){
data[i].parentElement.style.display = "none";
}
}
}
}
当我将它们放入common.js并在test page上尝试时,控制台显示错误:JavaScript解析错误:解析错误:缺少),位于文件'User:somebody / common中.js'在第16行,该行将事件侦听器绑定到按钮 ( wakiFilter.addEventListener(“ click”,()=>(filter(waki,wakiClicked,type))); )
然后将代码放入控制台,然后单击按钮,我得到: TypeError:this.querySelector不是函数。
不确定是什么原因造成的。我是错误地编写了我的箭头函数还是...?
[2019-05-14]
我确实弄清楚了如何使用addEventListener()
一键过滤掉某些列。添加到两个按钮用于测试目的:
//type filter
var type = document.querySelectorAll("tr td:nth-last-child(1)");
//for tantou
const tantouFilter = document.getElementById("Tantou");
tantouFilter.addEventListener("click", function(e){
for(i = 0; i < type.length; i++){
if(!type[i].innerHTML.includes(tantouFilter.id)){
type[i].parentElement.style.display = "none";
}
}
});
//for wakizashi
const wakiFilter = document.getElementById("Wakizashi");
wakiFilter.addEventListener("click", function(e){
wakiFilter.innerHTML = "[[File:Wakizashi-full.png|30px|link=]]";
for(i = 0; i < type.length; i++){
if(!type[i].innerHTML.includes(wakiFilter.id)){
type[i].parentElement.style.display = "none";
}
}
});
在第二个功能中,我尝试同时更改该按钮的图像,但是得到的是:
现在我想知道的是:
-单击后如何更改按钮的图像?
-如何通过再次单击同一按钮来撤消此过滤?
是否可以重新格式化该过滤器功能,以便所有按钮都可以使用相同的功能?
顺便说一句,我使用my personal common.js进行测试,因为在Fandom Wiki上,整个wiki的common.js在发布前都需要时间对其进行检查。
如果您想使用该代码,只需将我的代码复制并粘贴到您的个人common.js中即可。
答案 0 :(得分:0)
您的图片未更新,因为您插入了“ Fandom ”标签来替换元素的HTML。
起初这是一个不错的主意,但是您需要知道,例如“ Fandom页面”,肯定在服务器端转换为HTML,并且您的浏览器仅接收HTML 。我不确定我刚才说的是什么,但是我想这就是过程。
简单地解释一下,在页面加载后添加“ Fandom ”标签时,由于未调用模板引擎,因此不会转换为HTML。
因此,为了更新您的图像,元素中可能有一个<img>
标签来获取事件侦听器。这是您需要更新的图像元素的[src]
属性。
查看页面DOM树后,我认为您必须自己找出正确的图像URL。
现在,回答您的问题:
HTMLElement#getAttribute
获取元素属性的值。HTMLElement#setAttribute
更新元素属性的值。使用if
语句,您可以检查当前显示的图片,然后选择要显示的图片。
为了对所有过滤器都具有独特的功能,只需对其进行设置并在事件监听器中使用它。
document.querySelector('#Tantou').addEventListener('click', function() {
filter(this, 'url/to/tantou.png', 'url/to/tantou-filtered.png');
});
document.querySelector('#Wakizashi').addEventListener('click', function() {
filter(this, 'url/to/wakizashi.png', 'url/to/wakizashi-filtered.png');
});
/**
* @param {HTMLElement} clickedElement - The element that triggered the event.
* @param {string} imageSrc - The URL of the picture when it is NOT active/clicked.
* @param {string} imageSrcFiltered - The URL of the picture when it is active/clicked.
*/
function filter(clickedElement, imageSrc, imageSrcFiltered) {
const types = document.querySelectorAll("tr td:nth-last-child(1)"),
// Gets the <img> tag.
imageElement = clickedElement.querySelector('img'),
// Gets the current [src] attribute's value of the <img>.
currentImageSrc = imageElement.getAttribute('src'),
// It is filtered if the current image URL is the same as the one when it is filtered.
isFiltered = (currentImageSrc === imageSrcFiltered);
// If filtered, displays the lines.
if (isFiltered) {
// Replaces the image URL.
imageElement.setAttribute('src', imageSrc);
// ---- Code snippet testing purpose here!
imageElement.setAttribute('alt', imageSrc.split('/').pop());
for(let i = 0; i < types.length; i++) {
if (!types[i].innerHTML.includes(clickedElement.id)) {
// Sets a CSS style to an empty string to reset its value.
types[i].parentElement.style.display = '';
}
}
} // If not, hides the lines.
else {
// Replaces the image URL.
imageElement.setAttribute('src', imageSrcFiltered);
// ---- Code snippet testing purpose here!
imageElement.setAttribute('alt', imageSrcFiltered.split('/').pop());
for(let i = 0; i < types.length; i++) {
if (!types[i].innerHTML.includes(clickedElement.id)) {
types[i].parentElement.style.display = 'none';
}
}
}
}
<div id="Tantou">
<img src="url/to/tantou.png" alt="tantou.png">
</div>
<div id="Wakizashi">
<img src="url/to/wakizashi.png" alt="wakizashi.png">
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>A column</th>
<th>Column checked by filters</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Cell</td>
<td>Tantou</td>
</tr>
<tr>
<td>2</td>
<td>Cell</td>
<td>OtherFilter</td>
</tr>
<tr>
<td>3</td>
<td>Cell</td>
<td>Wakizashi</td>
</tr>
</tbody>
</table>
最后,您可以进一步简化此功能,但我不想给您太多东西来一次吸收。